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