| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |