1 16 package net.jforum.util.legacy.commons.fileupload; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.OutputStream ; 21 import java.io.UnsupportedEncodingException ; 22 import java.util.ArrayList ; 23 import java.util.HashMap ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import javax.servlet.http.HttpServletRequest ; 28 29 import net.jforum.util.legacy.commons.fileupload.servlet.ServletRequestContext; 30 31 54 public abstract class FileUploadBase { 55 56 58 59 73 public static final boolean isMultipartContent(RequestContext ctx) { 74 String contentType = ctx.getContentType(); 75 if (contentType == null) { 76 return false; 77 } 78 if (contentType.toLowerCase().startsWith(MULTIPART)) { 79 return true; 80 } 81 return false; 82 } 83 84 85 96 public static final boolean isMultipartContent(HttpServletRequest req) { 97 if (!"post".equals(req.getMethod().toLowerCase())) { 98 return false; 99 } 100 String contentType = req.getContentType(); 101 if (contentType == null) { 102 return false; 103 } 104 if (contentType.toLowerCase().startsWith(MULTIPART)) { 105 return true; 106 } 107 return false; 108 } 109 110 111 113 114 117 public static final String CONTENT_TYPE = "Content-type"; 118 119 120 123 public static final String CONTENT_DISPOSITION = "Content-disposition"; 124 125 126 129 public static final String FORM_DATA = "form-data"; 130 131 132 135 public static final String ATTACHMENT = "attachment"; 136 137 138 141 public static final String MULTIPART = "multipart/"; 142 143 144 147 public static final String MULTIPART_FORM_DATA = "multipart/form-data"; 148 149 150 153 public static final String MULTIPART_MIXED = "multipart/mixed"; 154 155 156 160 public static final int MAX_HEADER_SIZE = 1024; 161 162 163 165 166 170 private long sizeMax = -1; 171 172 173 176 private String headerEncoding; 177 178 179 181 182 187 public abstract FileItemFactory getFileItemFactory(); 188 189 190 195 public abstract void setFileItemFactory(FileItemFactory factory); 196 197 198 206 public long getSizeMax() { 207 return sizeMax; 208 } 209 210 211 219 public void setSizeMax(long sizeMax) { 220 this.sizeMax = sizeMax; 221 } 222 223 224 231 public String getHeaderEncoding() { 232 return headerEncoding; 233 } 234 235 236 243 public void setHeaderEncoding(String encoding) { 244 headerEncoding = encoding; 245 } 246 247 248 250 251 265 public List parseRequest(HttpServletRequest req) 266 throws FileUploadException { 267 return parseRequest(new ServletRequestContext(req)); 268 } 269 270 282 public List parseRequest(RequestContext ctx) 283 throws FileUploadException { 284 if (ctx == null) { 285 throw new NullPointerException ("ctx parameter"); 286 } 287 288 ArrayList items = new ArrayList (); 289 String contentType = ctx.getContentType(); 290 291 if ((null == contentType) 292 || (!contentType.toLowerCase().startsWith(MULTIPART))) { 293 throw new InvalidContentTypeException( 294 "the request doesn't contain a " 295 + MULTIPART_FORM_DATA 296 + " or " 297 + MULTIPART_MIXED 298 + " stream, content type header is " 299 + contentType); 300 } 301 int requestSize = ctx.getContentLength(); 302 303 if (requestSize == -1) { 304 throw new UnknownSizeException( 305 "the request was rejected because its size is unknown"); 306 } 307 308 if (sizeMax >= 0 && requestSize > sizeMax) { 309 throw new SizeLimitExceededException( 310 "the request was rejected because " 311 + "its size exceeds allowed range"); 312 } 313 314 try { 315 byte[] boundary = getBoundary(contentType); 316 if (boundary == null) { 317 throw new FileUploadException( 318 "the request was rejected because " 319 + "no multipart boundary was found"); 320 } 321 322 InputStream input = ctx.getInputStream(); 323 324 MultipartStream multi = new MultipartStream(input, boundary); 325 multi.setHeaderEncoding(headerEncoding); 326 327 boolean nextPart = multi.skipPreamble(); 328 while (nextPart) { 329 Map headers = parseHeaders(multi.readHeaders()); 330 String fieldName = getFieldName(headers); 331 if (fieldName != null) { 332 String subContentType = getHeader(headers, CONTENT_TYPE); 333 if (subContentType != null && subContentType 334 .toLowerCase().startsWith(MULTIPART_MIXED)) { 335 byte[] subBoundary = getBoundary(subContentType); 337 multi.setBoundary(subBoundary); 338 boolean nextSubPart = multi.skipPreamble(); 339 while (nextSubPart) { 340 headers = parseHeaders(multi.readHeaders()); 341 if (getFileName(headers) != null) { 342 FileItem item = 343 createItem(headers, false); 344 OutputStream os = item.getOutputStream(); 345 try { 346 multi.readBodyData(os); 347 } finally { 348 os.close(); 349 } 350 items.add(item); 351 } else { 352 multi.discardBodyData(); 355 } 356 nextSubPart = multi.readBoundary(); 357 } 358 multi.setBoundary(boundary); 359 } else { 360 FileItem item = createItem(headers, 361 getFileName(headers) == null); 362 OutputStream os = item.getOutputStream(); 363 try { 364 multi.readBodyData(os); 365 } finally { 366 os.close(); 367 } 368 items.add(item); 369 } 370 } else { 371 multi.discardBodyData(); 373 } 374 nextPart = multi.readBoundary(); 375 } 376 } catch (IOException e) { 377 throw new FileUploadException( 378 "Processing of " + MULTIPART_FORM_DATA 379 + " request failed. " + e.getMessage()); 380 } 381 382 return items; 383 } 384 385 386 388 389 397 protected byte[] getBoundary(String contentType) { 398 ParameterParser parser = new ParameterParser(); 399 parser.setLowerCaseNames(true); 400 Map params = parser.parse(contentType, ';'); 402 String boundaryStr = (String ) params.get("boundary"); 403 404 if (boundaryStr == null) { 405 return null; 406 } 407 byte[] boundary; 408 try { 409 boundary = boundaryStr.getBytes("ISO-8859-1"); 410 } catch (UnsupportedEncodingException e) { 411 boundary = boundaryStr.getBytes(); 412 } 413 return boundary; 414 } 415 416 417 425 protected String getFileName(Map headers) { 426 String fileName = null; 427 String cd = getHeader(headers, CONTENT_DISPOSITION); 428 if (cd.startsWith(FORM_DATA) || cd.startsWith(ATTACHMENT)) { 429 ParameterParser parser = new ParameterParser(); 430 parser.setLowerCaseNames(true); 431 Map params = parser.parse(cd, ';'); 433 if (params.containsKey("filename")) { 434 fileName = (String ) params.get("filename"); 435 if (fileName != null) { 436 fileName = fileName.trim(); 437 } else { 438 fileName = ""; 441 } 442 } 443 } 444 return fileName; 445 } 446 447 448 456 protected String getFieldName(Map headers) { 457 String fieldName = null; 458 String cd = getHeader(headers, CONTENT_DISPOSITION); 459 if (cd != null && cd.startsWith(FORM_DATA)) { 460 461 ParameterParser parser = new ParameterParser(); 462 parser.setLowerCaseNames(true); 463 Map params = parser.parse(cd, ';'); 465 fieldName = (String ) params.get("name"); 466 if (fieldName != null) { 467 fieldName = fieldName.trim(); 468 } 469 } 470 return fieldName; 471 } 472 473 474 486 protected FileItem createItem(Map headers, 487 boolean isFormField) { 488 return getFileItemFactory().createItem(getFieldName(headers), 489 getHeader(headers, CONTENT_TYPE), 490 isFormField, 491 getFileName(headers)); 492 } 493 494 495 507 protected Map parseHeaders(String headerPart) { 508 Map headers = new HashMap (); 509 char[] buffer = new char[MAX_HEADER_SIZE]; 510 boolean done = false; 511 int j = 0; 512 int i; 513 String header, headerName, headerValue; 514 try { 515 while (!done) { 516 i = 0; 517 while (i < 2 520 || buffer[i - 2] != '\r' || buffer[i - 1] != '\n') { 521 buffer[i++] = headerPart.charAt(j++); 522 } 523 header = new String (buffer, 0, i - 2); 524 if (header.equals("")) { 525 done = true; 526 } else { 527 if (header.indexOf(':') == -1) { 528 continue; 530 } 531 headerName = header.substring(0, header.indexOf(':')) 532 .trim().toLowerCase(); 533 headerValue = 534 header.substring(header.indexOf(':') + 1).trim(); 535 if (getHeader(headers, headerName) != null) { 536 headers.put(headerName, 539 getHeader(headers, headerName) + ',' 540 + headerValue); 541 } else { 542 headers.put(headerName, headerValue); 543 } 544 } 545 } 546 } catch (IndexOutOfBoundsException e) { 547 } 550 return headers; 551 } 552 553 554 564 protected final String getHeader(Map headers, 565 String name) { 566 return (String ) headers.get(name.toLowerCase()); 567 } 568 569 570 573 public static class InvalidContentTypeException 574 extends FileUploadException { 575 579 public InvalidContentTypeException() { 580 super(); 581 } 582 583 589 public InvalidContentTypeException(String message) { 590 super(message); 591 } 592 } 593 594 595 598 public static class UnknownSizeException 599 extends FileUploadException { 600 604 public UnknownSizeException() { 605 super(); 606 } 607 608 614 public UnknownSizeException(String message) { 615 super(message); 616 } 617 } 618 619 620 623 public static class SizeLimitExceededException 624 extends FileUploadException { 625 629 public SizeLimitExceededException() { 630 super(); 631 } 632 633 639 public SizeLimitExceededException(String message) { 640 super(message); 641 } 642 } 643 644 } 645 | Popular Tags |