1 61 62 63 package org.apache.commons.fileupload; 64 65 66 import java.io.IOException ; 67 import java.io.InputStream ; 68 import java.io.OutputStream ; 69 import java.util.ArrayList ; 70 import java.util.HashMap ; 71 import java.util.List ; 72 import java.util.Map ; 73 import javax.servlet.http.HttpServletRequest ; 74 75 76 99 public abstract class FileUploadBase 100 { 101 102 104 105 114 public static final boolean isMultipartContent(HttpServletRequest req) 115 { 116 String contentType = req.getHeader(CONTENT_TYPE); 117 if (contentType == null) 118 { 119 return false; 120 } 121 if (contentType.startsWith(MULTIPART)) 122 { 123 return true; 124 } 125 return false; 126 } 127 128 129 131 132 135 public static final String CONTENT_TYPE = "Content-type"; 136 137 138 141 public static final String CONTENT_DISPOSITION = "Content-disposition"; 142 143 144 147 public static final String FORM_DATA = "form-data"; 148 149 150 153 public static final String ATTACHMENT = "attachment"; 154 155 156 159 public static final String MULTIPART = "multipart/"; 160 161 162 165 public static final String MULTIPART_FORM_DATA = "multipart/form-data"; 166 167 168 171 public static final String MULTIPART_MIXED = "multipart/mixed"; 172 173 174 178 public static final int MAX_HEADER_SIZE = 1024; 179 180 181 183 184 188 private long sizeMax = -1; 189 190 191 194 private String headerEncoding; 195 196 197 199 200 205 public abstract FileItemFactory getFileItemFactory(); 206 207 208 213 public abstract void setFileItemFactory(FileItemFactory factory); 214 215 216 224 public long getSizeMax() 225 { 226 return sizeMax; 227 } 228 229 230 238 public void setSizeMax(long sizeMax) 239 { 240 this.sizeMax = sizeMax; 241 } 242 243 244 251 public String getHeaderEncoding() 252 { 253 return headerEncoding; 254 } 255 256 257 264 public void setHeaderEncoding(String encoding) 265 { 266 headerEncoding = encoding; 267 } 268 269 270 272 273 286 public List parseRequest(HttpServletRequest req) 287 throws FileUploadException 288 { 289 if (null == req) 290 { 291 throw new NullPointerException ("req parameter"); 292 } 293 294 ArrayList items = new ArrayList (); 295 String contentType = req.getHeader(CONTENT_TYPE); 296 297 if ((null == contentType) || (!contentType.startsWith(MULTIPART))) 298 { 299 throw new InvalidContentTypeException( 300 "the request doesn't contain a " 301 + MULTIPART_FORM_DATA 302 + " or " 303 + MULTIPART_MIXED 304 + " stream, content type header is " 305 + contentType); 306 } 307 int requestSize = req.getContentLength(); 308 309 if (requestSize == -1) 310 { 311 throw new UnknownSizeException( 312 "the request was rejected because it's size is unknown"); 313 } 314 315 if (sizeMax >= 0 && requestSize > sizeMax) 316 { 317 throw new SizeLimitExceededException( 318 "the request was rejected because " 319 + "it's size exceeds allowed range"); 320 } 321 322 try 323 { 324 int boundaryIndex = contentType.indexOf("boundary="); 325 if (boundaryIndex < 0) 326 { 327 throw new FileUploadException( 328 "the request was rejected because " 329 + "no multipart boundary was found"); 330 } 331 byte[] boundary = contentType.substring( 332 boundaryIndex + 9).getBytes(); 333 334 InputStream input = req.getInputStream(); 335 336 MultipartStream multi = new MultipartStream(input, boundary); 337 multi.setHeaderEncoding(headerEncoding); 338 339 boolean nextPart = multi.skipPreamble(); 340 while (nextPart) 341 { 342 Map headers = parseHeaders(multi.readHeaders()); 343 String fieldName = getFieldName(headers); 344 if (fieldName != null) 345 { 346 String subContentType = getHeader(headers, CONTENT_TYPE); 347 if (subContentType != null && subContentType 348 .startsWith(MULTIPART_MIXED)) 349 { 350 byte[] subBoundary = 352 subContentType.substring( 353 subContentType 354 .indexOf("boundary=") + 9).getBytes(); 355 multi.setBoundary(subBoundary); 356 boolean nextSubPart = multi.skipPreamble(); 357 while (nextSubPart) 358 { 359 headers = parseHeaders(multi.readHeaders()); 360 if (getFileName(headers) != null) 361 { 362 FileItem item = 363 createItem(headers, false); 364 OutputStream os = item.getOutputStream(); 365 try 366 { 367 multi.readBodyData(os); 368 } 369 finally 370 { 371 os.close(); 372 } 373 items.add(item); 374 } 375 else 376 { 377 multi.discardBodyData(); 380 } 381 nextSubPart = multi.readBoundary(); 382 } 383 multi.setBoundary(boundary); 384 } 385 else 386 { 387 if (getFileName(headers) != null) 388 { 389 FileItem item = createItem(headers, false); 391 OutputStream os = item.getOutputStream(); 392 try 393 { 394 multi.readBodyData(os); 395 } 396 finally 397 { 398 os.close(); 399 } 400 items.add(item); 401 } 402 else 403 { 404 FileItem item = createItem(headers, true); 406 OutputStream os = item.getOutputStream(); 407 try 408 { 409 multi.readBodyData(os); 410 } 411 finally 412 { 413 os.close(); 414 } 415 items.add(item); 416 } 417 } 418 } 419 else 420 { 421 multi.discardBodyData(); 423 } 424 nextPart = multi.readBoundary(); 425 } 426 } 427 catch (IOException e) 428 { 429 throw new FileUploadException( 430 "Processing of " + MULTIPART_FORM_DATA 431 + " request failed. " + e.getMessage()); 432 } 433 434 return items; 435 } 436 437 438 440 441 449 protected String getFileName(Map headers) 450 { 451 String fileName = null; 452 String cd = getHeader(headers, CONTENT_DISPOSITION); 453 if (cd.startsWith(FORM_DATA) || cd.startsWith(ATTACHMENT)) 454 { 455 int start = cd.indexOf("filename=\""); 456 int end = cd.indexOf('"', start + 10); 457 if (start != -1 && end != -1) 458 { 459 fileName = cd.substring(start + 10, end).trim(); 460 } 461 } 462 return fileName; 463 } 464 465 466 474 protected String getFieldName(Map headers) 475 { 476 String fieldName = null; 477 String cd = getHeader(headers, CONTENT_DISPOSITION); 478 if (cd != null && cd.startsWith(FORM_DATA)) 479 { 480 int start = cd.indexOf("name=\""); 481 int end = cd.indexOf('"', start + 6); 482 if (start != -1 && end != -1) 483 { 484 fieldName = cd.substring(start + 6, end); 485 } 486 } 487 return fieldName; 488 } 489 490 491 503 protected FileItem createItem(Map headers, 504 boolean isFormField) 505 throws FileUploadException 506 { 507 return getFileItemFactory().createItem(getFieldName(headers), 508 getHeader(headers, CONTENT_TYPE), 509 isFormField, 510 getFileName(headers)); 511 } 512 513 514 526 protected Map parseHeaders(String headerPart) 527 { 528 Map headers = new HashMap (); 529 char buffer[] = new char[MAX_HEADER_SIZE]; 530 boolean done = false; 531 int j = 0; 532 int i; 533 String header, headerName, headerValue; 534 try 535 { 536 while (!done) 537 { 538 i = 0; 539 while (i < 2 || buffer[i - 2] != '\r' || buffer[i - 1] != '\n') 542 { 543 buffer[i++] = headerPart.charAt(j++); 544 } 545 header = new String (buffer, 0, i - 2); 546 if (header.equals("")) 547 { 548 done = true; 549 } 550 else 551 { 552 if (header.indexOf(':') == -1) 553 { 554 continue; 556 } 557 headerName = header.substring(0, header.indexOf(':')) 558 .trim().toLowerCase(); 559 headerValue = 560 header.substring(header.indexOf(':') + 1).trim(); 561 if (getHeader(headers, headerName) != null) 562 { 563 headers.put(headerName, 566 getHeader(headers, headerName) + ',' 567 + headerValue); 568 } 569 else 570 { 571 headers.put(headerName, headerValue); 572 } 573 } 574 } 575 } 576 catch (IndexOutOfBoundsException e) 577 { 578 } 581 return headers; 582 } 583 584 585 595 protected final String getHeader(Map headers, 596 String name) 597 { 598 return (String ) headers.get(name.toLowerCase()); 599 } 600 601 602 605 public static class InvalidContentTypeException 606 extends FileUploadException 607 { 608 612 public InvalidContentTypeException() 613 { 614 super(); 615 } 616 617 623 public InvalidContentTypeException(String message) 624 { 625 super(message); 626 } 627 } 628 629 630 633 public static class UnknownSizeException 634 extends FileUploadException 635 { 636 640 public UnknownSizeException() 641 { 642 super(); 643 } 644 645 651 public UnknownSizeException(String message) 652 { 653 super(message); 654 } 655 } 656 657 658 661 public static class SizeLimitExceededException 662 extends FileUploadException 663 { 664 668 public SizeLimitExceededException() 669 { 670 super(); 671 } 672 673 679 public SizeLimitExceededException(String message) 680 { 681 super(message); 682 } 683 } 684 685 } 686 | Popular Tags |