Logo Search packages:      
Sourcecode: fex version File versions  Download package

Sender.java

package fix;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.regex.Pattern;

import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.RepaintManager;

/**
 * This class sends the HTTP-MIME-messages necessary for the F*EX upload.
 * 
 * $Date: 2010-02-04 12:01:01 +0100 (Thu, 04 Feb 2010) $
 * $Revision: 30 $
 * $Author: roth $
 * 
 * @author Dominik
 * 
 * Copyright (C) 2008 Dominik Greibl
 * Copyright (C) 2009 Sebastian Roth
 * 
 * All Rights Reserved
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

00048 public class Sender {

      private String rec = "";
      private String file = "";
      private String comm = "";
      private String host = "";
      private String user = "";
      private String id = "";
      private String akey = "";
      private String skey = "";
      public String boundary = "";
      private String url = "";
      private int port = 0;
      public HttpClient hc = null;
      private FileInputStream is = null;
      private boolean debug = false;
      private long seek = 0;
      private String sid = null;
      private ErrorWindow er = null;
      private boolean mime = false;
      private String lastReply = "";
      private boolean isCanceled = false;

      /**
       * The default constructor
       * 
       * @param reci
       *            The recipient of the file.
       * @param file
       *            The file to be sent.
       * @param comment
       *            The optional comment (may be null or empty String).
       * @param m
       *            Flag to set MIME-Type to application/x-mime.
       * @param server
       *            The URL of the F*EX Server
       * @param user
       *            The user that sends the file.
       * @param id
       *            The auth-id of this user.
       * @param err
       *            The ErrorWindow used to display errors.
       */
00091       public Sender(String reci, String file, String comment, boolean m,
                  String server, String user, String id, String akey, String skey, ErrorWindow err, boolean d) {
            try {
                  rec = reci;
                  this.file = file;
                  comm = comment;
                  host = new URL(server).getHost();
                  this.user = user;
                  this.id = id;
                  this.akey = akey;
                  this.skey = skey;
                  url = server;
            } catch (MalformedURLException e) {
                  err.setMess("The host URL is malformed.", e);
            }
            er = err;
            mime = m;
            debug = d;
            isCanceled = false;
      }

      /**
       * Sends the MIME-Messages used to prepare the upload and starts the upload.
       */
00115       public boolean send(JProgressBar progressBar, JLabel statusLabel) {
            progressBar.setVisible(true);
            RepaintManager.currentManager(progressBar).paintDirtyRegions();
            /** Creates a new Instance of HttpClient and connects to the given url* */
            hc = new HttpClient(er, debug);
            hc.connect(url);
            /** Parses the protocol and the port from the given url* */
            String protocol = hc.parseURL(url)[0];
            port = hc.getPort(protocol);

            /** Gets the fileName of the given file * */
            File f = new File(file);
            String fileName = f.getName();
            String URLEncodedFileName = fileName;
            try {
                  URLEncodedFileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException uee) {
                  uee.printStackTrace();
                  return false;
            }

            /** Sends the first header * */
            hc.send("GET SID HTTP/1.1");
            hc.nl();
            hc.send("Host: " + host + ":" + port);
            hc.nl();
            hc.send("User-Agent: F*IX");
            hc.nl();
            hc.nl();

            /** Creates the BufferedReader for reading the server's response * */
            BufferedReader br = null;
            try {
                  br = new BufferedReader(new InputStreamReader(hc.getSocket()
                              .getInputStream()));
            } catch (IOException e2) {
                  er.setMess("Verbindung kann nicht hergestellt werden", e2);
                  return false;
            }
            /** Receives the first response from the server and parses the sessionID * */
            String s = receive(br);
            if (Pattern.compile("HTTP\\/[0-9]\\.[0-9]\\s*201\\s*.*").matcher(s).find())
                  sid = s.split("\\r\\n")[0].split(" 201 ")[1];

            /** Creates the encoded authentification id * */
            try {
                  id = ("MD5H:" + AeSimpleMD5.MD5(id + sid));
            } catch (NoSuchAlgorithmException e1) {
                  er.setMess("MD5 Algorithm cannot be calculated.", e1);
                  return false;
            } catch (UnsupportedEncodingException e1) {
                  er.setMess("MD5 Algorithm cannot be calculated.", e1);
                  return false;
            }

            /** Creates the boundary * */
            int arraySize = 40;
            byte[] bytes = new byte[arraySize];
            for (int i = 0; i < arraySize; i++) {
                  bytes[i] += (byte) (int) (Math.random() * 256);
            }
            boundary = String.valueOf(Base64Coder.encode(bytes));
            String NEWLINE = "\r\n";

            /** Sets the MIME-Type depending on the view option (mime) * */
            String mimetype = "application/octet-stream";
            if (mime) {
                  mimetype = "application/x-mime";
            }
            /** Variables often used * */
            String formbody = "Content-Disposition: form-data; name=\"";
            String end = "\"\r\n";

            /** Gets the SEEK value by requesting a header * */
            hc.send("HEAD /fop/" + rec + "/" + user + "/" + URLEncodedFileName + "??&ID="
                        + id + (!skey.equals("") ? "&SKEY=" + skey : "") + " HTTP/1.1\r\n");
            hc.nl();
            String reply = receive(br);

            /** Checks if the server replys an OK * */
            if (reply.matches("^HTTP\\/[0-9]\\.[0-9]\\s*200\\s*OK\\r\\nContent-Length: *[0-9]+$")) {
                  if (debug)
                        System.out.println(reply);

                  try {
                        seek = 0;
                        seek = Long.parseLong(reply.split("Content-Length: ")[1]);
                  } catch (NumberFormatException nfe) {
                        er.setMess("Could not parse HTTP header 'Content-Length' value. Must be a number.", nfe);
                        return false;
                  } catch (ArrayIndexOutOfBoundsException aioobe) {
                        er.setMess("No HTTP header 'Content-Length' in reply found.", aioobe);
                        return false;
                  }

                  /**
                   * Creates the message body for sending and calculating the
                   * Content-Length *
                   */
                  ArrayList<String> data = new ArrayList<String>();
                  data.add("--" + boundary + NEWLINE);
                  data.add(formbody + "FROM" + end);
                  data.add(NEWLINE);
                  data.add(user + NEWLINE);
                  data.add(data.get(0));
                  data.add(formbody + "TO" + end);
                  data.add(data.get(2));
                  data.add(rec + NEWLINE);
                  data.add(data.get(0));
                  data.add(formbody + "ID" + end);
                  data.add(data.get(2));
                  data.add(id + NEWLINE);
                  if (akey != null && !akey.equals("")) {
                        data.add("--" + boundary + NEWLINE);
                        data.add(formbody + "AKEY" + end);
                        data.add(data.get(2));
                        data.add(akey + NEWLINE);
                  }
                  if (skey != null && !skey.equals("")) {
                        data.add("--" + boundary + NEWLINE);
                        data.add(formbody + "SKEY" + end);
                        data.add(data.get(2));
                        data.add(skey + NEWLINE);
                  }
                  if (comm != null && !comm.equals("")) {
                        data.add("--" + boundary + NEWLINE);
                        data.add(formbody + "COMMENT" + end);
                        data.add(data.get(2));
                        data.add(comm + NEWLINE);
                  }
                  if (seek > 0) {
                        data.add("--" + boundary + NEWLINE);
                        data.add(formbody + "SEEK" + end);
                        data.add(NEWLINE);
                        data.add(seek + NEWLINE);
                  }
                  data.add("--" + boundary + NEWLINE);
                  data.add("Content-Disposition: form-data; name=\"FILE\"; filename=\"" + fileName + end);
                  data.add("Content-Type: " + mimetype + NEWLINE);
                  data.add("Content-Length: " + (f.length() - seek) + NEWLINE);
                  data.add(NEWLINE);
                  /** Calculates the Content-Length * */
                  long length = f.length();
                  for (String d : data) {
                        length += d.getBytes().length;
                  }
                  length += boundary.getBytes().length + 6;
                  length -= seek;

                  /** Sends the Header for the actual upload * */
                  hc.send("POST /fup HTTP/1.1");
                  hc.nl();
                  hc.send("Host: " + host + ":" + port);
                  hc.nl();
                  hc.send("Content-Length: " + length);
                  hc.nl();
                  hc.send("User-Agent: F*IX");
                  hc.nl();
                  hc.send("Content-Type: multipart/form-data; boundary=" + boundary);
                  hc.nl();
                  hc.nl();

                  /** Sends the message body * */
                  for (String d : data) {
                        try {
                              hc.send(d.getBytes("UTF-8"));
                        } catch (UnsupportedEncodingException e) {
                              er.setMess(d + " could not be converted to UTF-8.", e);
                        }
                  }
                        try {
                              long max = f.length();
                              System.out.println(max);
                              long reached = 0;
                              int r = 0;
                              byte[] data2 = new byte[16384];
                              is = new FileInputStream(file);
                              is.skip(seek);
                              reached = seek;
                              while ((r = is.read(data2, 0, data2.length)) != -1) {
                                    if (isCanceled == true) {
                                          br.close();
                                          is.close();
                                          hc.out.flush();
                                          hc.out.close();
                                          isCanceled = false;
                                          return false;
                                    }
                                    hc.out.write(data2, 0, r);
                                    reached += r;
                                    progressBar.setValue((int) (reached * 100. / max) * 2);
                                    RepaintManager.currentManager(progressBar).paintDirtyRegions();
                              }
                        } catch (IOException e1) {
                              er.setMess("File could not be sent: " + e1.getMessage(), e1);
                              return false;
                        }
                        hc.nl();
                        hc.nl();
                        hc.send("--" + boundary + "--" + "\r\n");

                        statusLabel.setText("waiting for server confirmation");
                        RepaintManager.currentManager(statusLabel).paintDirtyRegions();
                        String sss = null;
                        String result = "";
                        sss = receive(br);
                        if (sss.startsWith("HTTP")) {
                                    result = sss.split("\\r\\n")[0].split(" ")[2];
                        } else if (s == null) {
                                    result = "no response";
                        }
                        er.setMess("File uploaded successful! Server answered: " + result, "Done",  null);
                        System.out.println("result: " + result);


                        
                        try {
                              br.close();
                              is.close();
                              hc.out.flush();
                              hc.out.close();
                        } catch (IOException e) {
                              er.setMess("Streams could not be closed, please restart Client.", e);
                              return false;
                        }
                  
            }
            else {
                  er.setMess(reply.split("\r\n")[0], null);
                  return false;
            }
            return true;
      }

      /**
       * Receives the response from the server and writes it to an OutputStream
       * 
       * @return response from server
       */
00354       public String receive(BufferedReader from_server) {
            String s = "";
            String result = "";
            try {
                  while (((s = from_server.readLine()) != null) && s.length() > 0) {
                        result = result + s + "\r\n";
                        if (debug) {
                              System.err.println("\t" + s);
                        }
                  }
            } catch (IOException e) {
                  if (e.getMessage().equals("Connection reset")) { // &&
//                      e.getClass().equals(new java.net.SocketException())) {
                              System.out.println("Communication terminated. Server has reset the connection.");
                  }
                  lastReply = result.split("\r\n")[0];
                  er.setMess("Can not read from Server: " + lastReply, e);
            }
            lastReply = result.replaceAll("\r\n$", "");
            return lastReply;
      }

      public String getLastReply() {
            return lastReply;
      }
      
      public void cancelSend() {
            isCanceled = true;
      }
      
}

Generated by  Doxygen 1.6.0   Back to index