[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/imagex/postlet/rev165/ -> UploadThread.java (source)

   1  /*    Copyright (C) 2005 Simon David Rycroft
   2  
   3      This program is free software; you can redistribute it and/or
   4      modify it under the terms of the GNU General Public License
   5      as published by the Free Software Foundation; either version 2
   6      of the License, or (at your option) any later version.
   7  
   8      This program is distributed in the hope that it will be useful,
   9      but WITHOUT ANY WARRANTY; without even the implied warranty of
  10      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11      GNU General Public License for more details.
  12  
  13      You should have received a copy of the GNU General Public License
  14      along with this program; if not, write to the Free Software
  15      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  16  
  17  import com.sun.java.browser.net.ProxyInfo;
  18  import com.sun.java.browser.net.ProxyService;
  19  import java.io.File;
  20  import java.io.FileInputStream;
  21  import java.io.BufferedOutputStream;
  22  import java.io.DataOutputStream;
  23  import java.io.InputStreamReader;
  24  import java.io.BufferedReader;
  25  import java.net.Socket;
  26  import java.net.URL;
  27  import java.util.Random;
  28  import javax.net.ssl.TrustManager;
  29  import javax.net.ssl.X509TrustManager;
  30  import javax.net.ssl.SSLContext;
  31  
  32  import java.net.UnknownHostException;
  33  import java.io.IOException;
  34  import java.io.FileNotFoundException;
  35  import java.io.UnsupportedEncodingException;
  36  
  37  import java.io.InputStream;
  38  import java.awt.image.BufferedImage;
  39  import javax.imageio.ImageIO;
  40  import java.awt.Graphics2D;
  41  import java.awt.RenderingHints;
  42  import java.io.ByteArrayOutputStream;
  43  import java.io.ByteArrayInputStream;
  44  
  45  public class UploadThread extends Thread{
  46  
  47      private File file;
  48      private Main main;
  49      private int attempts, finalByteSize;
  50      private static final String lotsHyphens="---------------------------";
  51      private static final String lineEnd="\r\n";
  52      private String header, footer, request, reply, afterContent;
  53      private InputStream fileStream;
  54      private URL url;
  55      private String boundary;
  56      private Socket sock;
  57      private boolean addPngToFileName;
  58      private boolean doUpload;
  59  
  60      public UploadThread(URL u, File f, Main m) throws IOException, UnknownHostException{
  61  
  62          url = u;
  63          file = f;
  64          main = m;
  65          attempts = 0;
  66          doUpload = true;
  67      }
  68  
  69      public void run(){
  70          try {
  71              upload();
  72          }
  73          catch (FileNotFoundException fnfe) {
  74              // A file has been moved or deleted. This file will NOT
  75              // be uploaded.
  76              // Set the progress to include this file.
  77              main.fileNotFound(file);
  78              main.setProgress((int)file.length());
  79          }
  80          catch (IOException ioe){
  81              // No idea what could have caused this, so simply call this.run() again.
  82              this.run();
  83              // This could end up looping. Probably need to find out what could cause this.
  84              // I guess I could count the number of attempts!
  85              main.errorMessage("IOException: UploadThread");
  86          }
  87      }
  88  
  89      public void cancelUpload(){
  90          doUpload = false;
  91      }
  92      private void upload() throws FileNotFoundException, IOException{
  93  
  94          this.uploadFile();
  95          // Check to see if the file was uploaded
  96          if (reply != null && reply.indexOf("POSTLET:NO")>0) {
  97              if (reply.indexOf("POSTLET:RETRY")>0){
  98                  reply = "";
  99                  if (attempts<3) {
 100                      main.setProgress(-(int)file.length());
 101                      main.setProgress(finalByteSize); // Has to be added after whole file is removed.
 102                      attempts++;
 103                      this.upload();
 104                  }
 105                  else {
 106                      main.fileUploadFailed(file);
 107                      main.setProgress(finalByteSize);
 108                  }
 109              } else {
 110                  if(reply.indexOf("POSTLET:FILE TYPE NOT ALLOWED")>0){
 111                      main.fileNotAllowed(file);
 112                  }
 113                  else {
 114                      main.fileUploadFailed(file);
 115                  }
 116                  attempts = 5;
 117                  main.setProgress(finalByteSize);
 118              }
 119          }
 120          else {
 121              // Set the progress, that this file has uploaded.
 122              main.addUploadedFile(file);
 123              main.setProgress(finalByteSize);
 124          }
 125      }
 126  
 127      private synchronized void uploadFile() throws FileNotFoundException, IOException{
 128  
 129          // Get the file stream first, as this is needed for the content-length
 130          // header.
 131          this.setInputStream();
 132          
 133          sock = getSocket();
 134  
 135          this.setBoundary(40);
 136          this.setHeaderAndFooter();
 137          // Output stream, for writing to the socket.
 138          DataOutputStream output = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
 139          // Reader for accepting the reply from the server.
 140          BufferedReader input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
 141  
 142          // Write the request, and the header.
 143          output.writeBytes(request);
 144          try {
 145              output.write(header.getBytes("UTF-8")); }// Write in UTF-8! - May change all
 146          catch (UnsupportedEncodingException uee){
 147              // Just ignore this error, and instead write out the bytes without
 148              // getting as UTF-8!
 149              main.errorMessage("Couldn't get header in UTF-8");
 150              output.writeBytes(header);
 151          }
 152  
 153          output.flush();
 154  
 155          // Create a ReadLine thread to read the possible output.
 156          // Possible catching of errors here if the return isn't 100 continue
 157          ReadLine rl = new ReadLine(input, this);
 158          rl.start();
 159          try {
 160              // Should be dynamically setting this.
 161              wait(1000);
 162          }
 163          catch (InterruptedException ie){
 164              // Thread was interuppted, which means there was probably
 165              // some output!
 166          }
 167          output.writeBytes(afterContent);
 168          // Debug: Show that the above has passed!
 169  
 170          // Following reads the file, and streams it.
 171          /////////////////////////////////////////////////////////////
 172          //FileInputStream fileStream = new FileInputStream(file);
 173          int numBytes = 0;
 174  
 175          if (file.length()>Integer.MAX_VALUE){
 176              throw new IOException("*** FILE TOO BIG ***");
 177          }
 178  
 179          // Size of buffer - May need reducing if users encounter
 180          // memory issues.
 181          int maxBufferSize = 1024;
 182          int bytesAvailable = fileStream.available();
 183          int bufferSize = Math.min(bytesAvailable,maxBufferSize);
 184          finalByteSize = 0; // Needs to be passed to the upload method!
 185  
 186          byte buffer [] = new byte[bufferSize];
 187  
 188          int bytesRead = fileStream.read(buffer, 0, bufferSize);
 189          while (bytesAvailable > 0 && doUpload)
 190          {
 191              output.write(buffer, 0, bufferSize);
 192              if (bufferSize == maxBufferSize)
 193                  main.setProgress(bufferSize);
 194              else
 195                  finalByteSize = bufferSize;
 196              bytesAvailable = fileStream.available();
 197              bufferSize = Math.min(bytesAvailable,maxBufferSize);
 198              bytesRead = fileStream.read(buffer, 0, bufferSize);
 199          }
 200          ///////////////////////////////////////////////////////////
 201          if (doUpload){
 202              output.writeBytes(footer);
 203              output.writeBytes(lineEnd);
 204  
 205              output.flush();
 206  
 207              try {
 208                  // Should be dynamically setting this.
 209                  wait(1000);
 210              }
 211              catch (InterruptedException ie){
 212                  // Thread was interuppted, which means there was probably
 213                  // some output!
 214              }
 215              reply = rl.getRead();
 216              main.errorMessage("REPLY");
 217              main.errorMessage(reply);
 218              main.errorMessage("END REPLY");
 219          }
 220          // Close the socket and streams.
 221          input.close();
 222          output.close();
 223          sock.close();
 224      }
 225  
 226      // Each UploadThread gets a new Socket.
 227      // This is bad, especially when talking to HTTP/1.1 servers
 228      // which are able to keep a connection alive. May change this
 229      // to have the UploadManager create the threads, and reuse them
 230      // passing them to each of the UploadThreads.
 231      private Socket getSocket() throws IOException, UnknownHostException{
 232          if (url.getProtocol().equalsIgnoreCase("https")){
 233              // Create a trust manager that does not validate certificate chains
 234              TrustManager[] trustAllCerts = new TrustManager[]{
 235                  new X509TrustManager() {
 236                      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
 237                          return null;
 238                      }
 239                      public void checkClientTrusted(
 240                              java.security.cert.X509Certificate[] certs, String authType) {
 241                      }
 242                      public void checkServerTrusted(
 243                              java.security.cert.X509Certificate[] certs, String authType) {
 244                      }
 245                  }
 246              };
 247              // Install the all-trusting trust manager
 248              try {
 249                  SSLContext sc = SSLContext.getInstance("SSL");
 250                  sc.init(null, trustAllCerts, new java.security.SecureRandom());
 251                  int port = url.getPort();
 252                  if (url.getPort()>0)
 253                      return sc.getSocketFactory().createSocket(url.getHost(),url.getPort());
 254                  else
 255                      return sc.getSocketFactory().createSocket(url.getHost(),443);
 256              }
 257              catch (Exception e) {
 258              }
 259          }
 260          else {
 261              try {
 262                  ProxyInfo info[] = ProxyService.getProxyInfo(url);
 263                  if(info != null && info.length>0){
 264                      String proxyHost = info[0].getHost();
 265                      int proxyPort = info[0].getPort();
 266                      main.errorMessage("PROXY = " + proxyHost + ":" + proxyPort);
 267                      return new Socket(proxyHost, proxyPort);
 268                  }
 269              }catch (Exception ex) {
 270                  main.errorMessage("could not retrieve proxy configuration, attempting direct connection.");
 271              }
 272              Socket s;
 273              String proxyHost = System.getProperties().getProperty("deployment.proxy.http.host");
 274              String proxyPort = System.getProperties().getProperty("deployment.proxy.http.port");
 275              String proxyType = System.getProperties().getProperty("deployment.proxy.type");
 276              if ( (proxyHost == null || proxyType == null) || (proxyHost.equalsIgnoreCase("") || proxyType.equalsIgnoreCase("0") || proxyType.equalsIgnoreCase("2") || proxyType.equalsIgnoreCase("-1") )){
 277                  if(!main.getProxy().equals("")){
 278                      String proxyParts[] = main.getProxy().split(":");
 279                      try{
 280                          s = new Socket(proxyParts[0],Integer.parseInt(proxyParts[1]));
 281                          main.errorMessage("Proxy (parameter) - "+proxyParts[0]+":"+proxyParts[1]);
 282                      }
 283                      catch (NumberFormatException badPort){
 284                          main.errorMessage("bad proxy parameter");
 285                          if (url.getPort()>0)
 286                              s = new Socket(url.getHost(),url.getPort());
 287                          else
 288                              s = new Socket(url.getHost(),80);                        
 289                      }
 290                  }
 291                  if (url.getPort()>0)
 292                      s = new Socket(url.getHost(),url.getPort());
 293                  else
 294                      s = new Socket(url.getHost(),80);
 295              }
 296              else{
 297                  // Show when a Proxy is being user.
 298                  main.errorMessage("Proxy (browser) - "+proxyHost+" - "+proxyPort+" - "+proxyType);
 299                  try {
 300                      s = new Socket(proxyHost,Integer.parseInt(proxyPort));}
 301                  catch (NumberFormatException badPort){
 302                      // Probably not a bad idea to try a list of standard Proxy ports
 303                      // here (8080, 3128 ..), then default to trying the final one.
 304                      // This could possibly be causing problems, display of an
 305                      // error message is probably also a good idea.
 306                      main.errorMessage("bad proxy from browser");
 307                      if (url.getPort()>0)
 308                          s = new Socket(url.getHost(),url.getPort());
 309                      else
 310                          s = new Socket(url.getHost(),80);
 311                  }
 312              }
 313              return s;
 314          }
 315          return null;// Add an error here!
 316      }
 317      
 318      private void setInputStream() throws FileNotFoundException{
 319          //check    if the file is an image from its extention
 320          String fileExt = file.getName();
 321          fileExt=fileExt.substring(fileExt.lastIndexOf(".")+1);
 322          
 323          // If file is an image supported by Java (Currently only JPEG, GIF and PNG)
 324          if((fileExt.equalsIgnoreCase("gif")
 325              ||fileExt.equalsIgnoreCase("jpg")
 326              ||fileExt.equalsIgnoreCase("jpeg")
 327              ||fileExt.equalsIgnoreCase("png")) && main.getMaxPixels()>0){
 328              try    {
 329                  BufferedImage buf=ImageIO.read(file);
 330                  int currentPixels = buf.getWidth()*buf.getHeight();
 331                  int maxPixels = main.getMaxPixels();                
 332                  if    (currentPixels>maxPixels){
 333                      double reduceBy = Math.sqrt(maxPixels)/Math.sqrt(currentPixels);
 334                      int    newWidth=(int)Math.round(buf.getWidth()*reduceBy);
 335                      int    newHeigth=(int)Math.round(buf.getHeight()*reduceBy);
 336                      BufferedImage bufFinal=new BufferedImage(newWidth,newHeigth,BufferedImage.TYPE_INT_RGB);
 337                      Graphics2D g=(Graphics2D)bufFinal.getGraphics();
 338                      g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
 339                      g.drawImage(buf,0,0,newWidth,newHeigth,null);
 340                      g.dispose();
 341                      ByteArrayOutputStream baos=new ByteArrayOutputStream();
 342                      if    (fileExt.equalsIgnoreCase("jpg")||fileExt.equalsIgnoreCase("jpeg"))
 343                          ImageIO.write(bufFinal,"JPG",baos);
 344                      else {// Note, GIF is converted to PNG, we need to change the filename
 345                          ImageIO.write(bufFinal,"PNG",baos);
 346                          if (fileExt.equalsIgnoreCase("gif")){
 347                              // File is a gif, hence, add png to the filename
 348                              addPngToFileName = true;
 349                          }
 350                      }
 351                      
 352                      // Set the progress to increase by the amount that the image
 353                      // is reduced in size
 354                      main.setProgress((int)file.length()-baos.size());
 355                      fileStream = new ByteArrayInputStream(baos.toByteArray());
 356                  }
 357                  else{
 358                      //if image don't need resize
 359                      fileStream = new FileInputStream(file);
 360                  }
 361              }
 362              catch (IOException e){
 363                  // Error somewhere
 364                  fileStream = new FileInputStream(file);
 365              }
 366          }
 367          else{
 368              //if the file is not an image, or maxPixels is not set
 369              fileStream = new FileInputStream(file);
 370          }
 371      }
 372  
 373      private void setBoundary(int length){
 374  
 375          char [] alphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
 376          Random r = new Random();
 377          String boundaryString ="";
 378          for (int i=0; i< length; i++)
 379              boundaryString += alphabet[r.nextInt(alphabet.length)];
 380          boundary = boundaryString;
 381      }
 382  
 383      private void setHeaderAndFooter() throws IOException{
 384  
 385          header = new String();
 386          footer = new String();
 387          request = new String();
 388  
 389          // AfterContent is what is sent after the Content-Length header field,
 390          // but before the file itself. The length of this, is what is required
 391          // by the content-length header (along with the length of the file).
 392          afterContent = lotsHyphens +"--"+ boundary + lineEnd +
 393                                      "Content-Disposition: form-data; name=\"userfile\"; filename=\""+file.getName();
 394          if (addPngToFileName)
 395              afterContent += ".png";
 396          afterContent += "\""+lineEnd+
 397                                      "Content-Type: application/octet-stream"+lineEnd+lineEnd;
 398  
 399          //footer = lineEnd + lineEnd + "--"+ lotsHyphens+boundary+"--";
 400          // LineEnd removed as it was adding an extra byte to the uploaded file
 401          footer = lineEnd + "--"+ lotsHyphens+boundary+"--" + lineEnd;
 402  
 403          // The request includes the absolute URI to the script which will
 404          // accept the file upload. This is perfectly valid, although it is
 405          // normally only used by a client when connecting to a proxy server.
 406          // COULD CREATE PROBLEMS WITH SOME WEB SERVERS.
 407          request="POST " + url.toExternalForm() + " HTTP/1.1" + lineEnd;
 408  
 409          // Host that we are sending to (not necesarily connecting to, if behind
 410          // a proxy)
 411          header +="Host: " + url.getHost() + lineEnd;
 412  
 413          // Give a user agent just for completeness. This could be changed so that
 414          // access by the Postlet applet can be logged.
 415          //header +="User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10)" + lineEnd;
 416          //Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8)
 417          header +="User-Agent: Mozilla/5.0 (Java/Postlet; rv:" + main.postletVersion + ")" + lineEnd;
 418  
 419  
 420          // Expect a 100-Continue message
 421          // header +="Expect: 100-continue" + lineEnd;
 422  
 423          // Standard accept
 424          header +="Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"+ lineEnd;
 425          header +="Accept-Language: en-us,en;q=0.5" + lineEnd;
 426          header +="Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + lineEnd;
 427  
 428          // Add the cookie if it is set in the browser
 429          String cookie = main.getCookie();
 430          if (cookie.length()>0){
 431              header +="Cookie: "+cookie+lineEnd;
 432          }
 433  
 434          header +="Connection: close" + lineEnd;
 435  
 436          // What we are sending.
 437          header +="Content-Type: multipart/form-data; boundary=" + lotsHyphens + boundary + lineEnd;
 438  
 439          // Length of what we are sending.
 440          header +="Content-Length: ";
 441          header += ""+(fileStream.available()+afterContent.length()+footer.length())+lineEnd+lineEnd;
 442      }
 443  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7