commons-fileupload-1.3.1-src/ 40755 0 0 0 12274740131 13131 5ustar 0 0 commons-fileupload-1.3.1-src/src/ 40755 0 0 0 12274737402 13727 5ustar 0 0 commons-fileupload-1.3.1-src/src/changes/ 40755 0 0 0 12274737402 15337 5ustar 0 0 commons-fileupload-1.3.1-src/src/checkstyle/ 40755 0 0 0 12274737400 16063 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/ 40755 0 0 0 12274737401 14652 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/assembly/ 40755 0 0 0 12274737401 16471 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/ 40755 0 0 0 12274737401 15573 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/ 40755 0 0 0 12274737401 16362 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/ 40755 0 0 0 12274737401 17603 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/ 40755 0 0 0 12274737401 21256 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/ 40755 0 0 0 12274737402 23403 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/disk/ 40755 0 0 0 12274737402 24335 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/ 40755 0 0 0 12274737402 25074 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/ 40755 0 0 0 12274737402 25067 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/ 40755 0 0 0 12274737401 24357 5ustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/ 40755 0 0 0 12274737401 25306 5ustar 0 0 commons-fileupload-1.3.1-src/src/media/ 40755 0 0 0 12274737401 15005 5ustar 0 0 commons-fileupload-1.3.1-src/src/site/ 40755 0 0 0 12274737402 14673 5ustar 0 0 commons-fileupload-1.3.1-src/src/site/fml/ 40755 0 0 0 12274737402 15451 5ustar 0 0 commons-fileupload-1.3.1-src/src/site/resources/ 40755 0 0 0 12274737402 16705 5ustar 0 0 commons-fileupload-1.3.1-src/src/site/resources/images/ 40755 0 0 0 12274737402 20152 5ustar 0 0 commons-fileupload-1.3.1-src/src/site/xdoc/ 40755 0 0 0 12274737402 15630 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/ 40755 0 0 0 12274737401 14705 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/ 40755 0 0 0 12274737401 15626 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/ 40755 0 0 0 12274737401 16415 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/ 40755 0 0 0 12274737401 17636 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/ 40755 0 0 0 12274737401 21311 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/ 40755 0 0 0 12274737401 23435 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/ 40755 0 0 0 12274737401 24412 5ustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/ 40755 0 0 0 12274737401 25341 5ustar 0 0 commons-fileupload-1.3.1-src/build-gump.xml100644 0 0 3061 12274737400 16022 0ustar 0 0 commons-fileupload-1.3.1-src/build.properties100644 0 0 7703 12274737402 16461 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #Generated by Maven Ant Plugin - DO NOT EDIT THIS FILE! #Fri Mar 08 12:53:27 CET 2013 commons.compiler.compilerVersion= maven.compile.source=1.5 commons.release.2.name=commons-fileupload-${commons.release.2.version} commons.release.desc= maven.build.srcDir.0=src/main/java commons.binary.suffix=-bin commons.manifestfile=${maven.build.outputDir}/osgi/MANIFEST.MF maven.build.timestamp.format=yyyy-MM-dd HH\:mm\:ssZ commons.project-info.version=2.6 maven.build.resourceDir.1=. maven.build.resourceDir.0=src/main/resources project.build.sourceEncoding=iso-8859-1 sourceReleaseAssemblyDescriptor=source-release commons.release.3.name=commons-fileupload-${commons.release.3.version} maven.build.outputDir=${maven.build.dir}/classes commons.componentid=fileupload commons.site.path=commons-fileupload maven.repo.local=${user.home}/.m2/repository maven.build.finalName=commons-fileupload-1.3-SNAPSHOT commons.osgi.private= maven.build.testDir.0=src/test/java commons.javadoc.javaee.link=http\://download.oracle.com/javaee/6/api/ commons.osgi.export=org.apache.commons.*;version\=1.3-SNAPSHOT;-noimport\:\=true commons.release.2.binary.suffix=-bin maven.reporting.outputDirectory=${maven.build.dir}/site commons.compiler.javac= commons.encoding=iso-8859-1 organization.logo=http\://www.apache.org/images/asf_logo_wide.gif commons.scmPubUrl=https\://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-fileupload sonar.host.url=https\://analysis.apache.org/ commons.rc.version=RC1 commons.cobertura.version=2.5.2 commons.release.name=commons-fileupload-1.3 minSeverity=info maven.build.testOutputDir=${maven.build.dir}/test-classes project.reporting.outputEncoding=iso-8859-1 maven.build.dir=target maven.test.reports=${maven.build.dir}/test-reports gpg.useagent=true commons.javadoc.version=2.9 commons.surefire.version=2.13 commons.changes.version=2.8 commons.release.version=1.3 commons.jxr.version=2.3 commons.surefire-report.version=2.13 commons.rat.version=0.8 commons.site.cache=/Users/stripodi/commons-sites project.build.outputDirectory=${maven.build.outputDir} commons.docEncoding=iso-8859-1 commons.javadoc.java.link=http\://download.oracle.com/javase/6/docs/api/ commons.deployment.protocol=scp maven.settings.offline=false distMgmtSnapshotsName=Apache Development Snapshot Repository maven.settings.interactiveMode=true maven.compile.target=1.5 commons.release.2.desc= commons.jira.pid=12310476 project.build.directory=${maven.build.dir} arguments= commons.surefire-report.aggregate=false commons.release.3.binary.suffix=-bin commons.wagon-ssh.version=2.3 distMgmtSnapshotsUrl=https\://repository.apache.org/content/repositories/snapshots maven.build.testResourceDir.1=. maven.build.testResourceDir.0=src/test/resources commons.osgi.dynamicImport=javax.portlet commons.compiler.fork=false commons.jdepend.version=2.0-beta-2 commons.release.3.desc= implementation.build=${scmBranch}@r${buildNumber}; 2013-03-08 12\:53\:21+0100 commons.site-plugin.version=3.2 commons.osgi.symbolicName=org.apache.commons.fileupload commons.surefire.java= commons.osgi.import=\!javax.portlet,* commons.jira.id=FILEUPLOAD commons.clirr.version=2.5 commons-fileupload-1.3.1-src/build.xml100644 0 0 36317 12274737402 15110 0ustar 0 0 =================================== WARNING =================================== JUnit is not present in your $ANT_HOME/lib directory. Tests not executed. =============================================================================== commons-fileupload-1.3.1-src/gump.xml100644 0 0 4015 12274737400 14725 0ustar 0 0 File upload component. org.apache.commons.fileupload commons-fileupload-1.3.1-src/LICENSE.txt100644 0 0 26450 12274737400 15105 0ustar 0 0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. commons-fileupload-1.3.1-src/NOTICE.txt100644 0 0 270 12274737402 14736 0ustar 0 0 Apache Commons FileUpload Copyright 2002-2014 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). commons-fileupload-1.3.1-src/pom.xml100644 0 0 23664 12274737556 14617 0ustar 0 0 4.0.0 org.apache.commons commons-parent 32 commons-fileupload commons-fileupload 1.3.1 Apache Commons FileUpload The Apache Commons FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications. http://commons.apache.org/proper/commons-fileupload/ 2002 Martin Cooper martinc martinc@apache.org Yahoo! dIon Gillard dion dion@apache.org Multitask Consulting John McNally jmcnally jmcnally@collab.net CollabNet Daniel Rall dlr dlr@finemaltcoding.com CollabNet Jason van Zyl jvanzyl jason@zenplex.com Zenplex Robert Burrell Donkin rdonkin rdonkin@apache.org Sean C. Sullivan sullis sean |at| seansullivan |dot| com Jochen Wiedmann jochen jochen.wiedmann@gmail.com Simone Tripodi simonetripodi simonetripodi@apache.org Adobe Gary Gregory ggregory ggregory@apache.org Aaron Freeman aaron@sendthisfile.com Daniel Fabian dfabian@google.com Jörg Heinicke joerg.heinicke@gmx.de Stepan Koltsov yozh@mx1.ru Michael Macaluso michael.public@wavecorp.com Amichai Rothman amichai2@amichais.net Alexander Sova bird@noir.crocodile.org Paul Spurr pspurr@gmail.com Thomas Vandahl tv@apache.org Henry Yandell bayard@apache.org Jan Novotný novotnaci@gmail.com frank mailsurfie@gmail.com Rafal Krzewski Rafal.Krzewski@e-point.pl Sean Legassick sean@informage.net Oleg Kalnichevski oleg@ural.ru David Sean Taylor taylor@apache.org scm:svn:http://svn.apache.org/repos/asf/commons/proper/fileupload/trunk scm:svn:https://svn.apache.org/repos/asf/commons/proper/fileupload/trunk http://svn.apache.org/viewvc/commons/proper/fileupload/trunk jira http://issues.apache.org/jira/browse/FILEUPLOAD 1.5 1.5 ISO-8859-1 fileupload 1.3.1 RC1 FILEUPLOAD 12310476 !org.apache.commons.fileupload.util.mime,org.apache.commons.*;version=${project.version};-noimport:=true !javax.portlet,* javax.portlet junit junit 4.11 test javax.servlet servlet-api 2.4 provided portlet-api portlet-api 1.0 provided commons-io commons-io 2.2 maven-assembly-plugin ${basedir}/src/main/assembly/bin.xml ${basedir}/src/main/assembly/src.xml gnu maven-release-plugin clean site verify deploy org.apache.maven.plugins maven-changes-plugin ${commons.changes.version} %URL%/../%ISSUE% changes-report org.apache.maven.plugins maven-checkstyle-plugin 2.10 ${basedir}/src/checkstyle/fileupload_checks.xml ${basedir}/src/checkstyle/checkstyle-suppressions.xml false ${basedir}/src/checkstyle/license-header.txt org.apache.maven.plugins maven-pmd-plugin 2.7.1 ${maven.compiler.target} ${basedir}/src/checkstyle/fileupload_basic.xml org.codehaus.mojo clirr-maven-plugin ${commons.clirr.version} commons-fileupload commons-fileupload 1.3 commons-fileupload-1.3.1-src/RELEASE-NOTES.txt100644 0 0 3035 12274737400 15743 0ustar 0 0 Apache Commons FileUpload 1.3.1 RELEASE NOTES The Apache Commons FileUpload team is pleased to announce the release of Apache Commons FileUpload 1.3.1. The Apache Commons FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications. Version 1.3 onwards requires Java 5 or later. No client code changes are required to migrate from version 1.3.0 to 1.3.1. This is a security and maintenance release that includes an important security fix as well as a small number of bugfixes. Changes in version 1.3.1 include: Fixed Bugs: o SECURITY - CVE-2014-0050. Specially crafted input can trigger a DoS if the buffer used by the MultipartStream is not big enough. When constructing MultipartStream enforce the requirements for buffer size by throwing an IllegalArgumentException if the requested buffer size is too small. This prevents the DoS. o When deserializing DiskFileItems ensure that the repository location, if any, is a valid one. Thanks to Arun Babu Neelicattu. o Correct example in usage documentation so it compiles. For complete information on Apache Commons FileUpload, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache Apache Commons FileUpload website: http://commons.apache.org/proper/commons-fileupload/ commons-fileupload-1.3.1-src/src/changes/changes.xml100644 0 0 63551 12274737402 17620 0ustar 0 0 Release Notes Martin Cooper SECURITY - CVE-2014-0050. Specially crafted input can trigger a DoS if the buffer used by the MultipartStream is not big enough. When constructing MultipartStream enforce the requirements for buffer size by throwing an IllegalArgumentException if the requested buffer size is too small. This prevents the DoS. When deserializing DiskFileItems ensure that the repository location, if any, is a valid one. Correct example in usage documentation so it compiles. SECURITY - CVE-2013-0248. Update the Javadoc and documentation to make it clear that setting a repository is required for a secure configuration if there are local, untrusted users. Update the project tree dirs according to default Maven conventions drop JDK1.3 support and update to Java5 Update version in POM upgrade tests to JUnit 4 replace package.html with package-info.java FileItemHeadersImpl can now use LinkedHashMap Mark @deprecated classes/methods with @Deprecated annotation Base64Decoder doesn't correctly implement RFC 4648 "Stream ended unexpectedly" when posting from a Flash client Manifest for OSGi has invalid syntax commons-io dependency does not get loaded by maven if only dependency to commons-fileupload is specified http://commons.apache.org/fileupload/index.html is out of date http://commons.apache.org/fileupload/index.html should not mention nightly builds DiskFileItemFactory use of FileCleaningTracker is documented or coded wrong - proposal submitted by Jan Novotný Error reading the file size larger than 2 gb - pull request from Gergely ServletFileUpload isMultipartContent method does not support HTTP PUT - thanks Roy T. Fielding and Jochen Wiedmann Uploads have unexpected results for files with non-ASCII names - support RFC2047 - thanks Thomas Neidhart Exceptions resulting from upload size limitations (fileSizeMax, sizeMax) are now correctly propagated to the caller (these could be encountered formerly as MalformedStreamException: "Stream ended unexpectedly"). FileItem.getHeaders() returns always null. The sizeMax parameter within FileUpload is now correctly enforced if no content length header is provided. ServletFileUpload only accepts POST requests (Servlet|Portlet)RequestContext#contentLength() must return request.getContentLength() if Content-length header is not available toLowerCase() is Locale-dependent; should use toLowerCase(Locale.ENGLISH) instead There are no unit tests for the new utils.mime classes Documentation: add simple HTML form example to fileupload user guide enhance file read/write performance - patch provided by frank Add Support for Generic Types Process HTTP Requests Into Maps Update commons-io dependency to latest version that supports JDK1.5 Avoid string concatenations while parsing headers, use buffers instead Replace java.rmi.server.UID() with java.util.UUID DiskFileItem.counter could be converted to AtomicInteger (or AtomicLong?) Private immutable fields which could be final Update to JDK 1.5 and bump IO dependency to 2.0.1 version 1.3 improvement tasks Added a check for file names containing a NULL characters. Such file names are now triggering an InvalidFileNameException since the file name cannot be used as provided to create the file since it will be truncated at the NUL character on most (all?) operating systems. E.g. a file name like "test.foo0.bar" would result in "test.foo" being created. Temporary files have not been deleted, if an error occurred in FileUploadBase.parseRequest(); Fixed example in MultipartStream Javadocs. Ensured, that the ProgressListener is called for all items. Made the ProgressNotifier public. Multiple documentation fixes. Fixed the error message for FileSizeLimitExceededException from "too many characters" to "too many bytes". A FileSizeLimitExceededException does now contain the file and field name of the item, which caused the problem. The FileItemHeader stuff hasn't been actually working. Upgrade to commons-io-1.4-SNAPSHOT, in order to use the new FileCleaningTracker and fix issues with FileCleaner. Made the MockHttpServletRequest comply to the servlet 2.4 specification by applying http://www.sourcelabs.com/dashboards/sash-1.2/patches/commons-fileupload-1.1-1/SUP-520.diff Added support for accessing the file item headers. A MalformedStreamException is now thrown, if the size of an items headers exceeds HEADER_PART_SIZE_MAX; DiskFileItem.toString() could throw an NPE. Short files could cause an unexpected end of the item stream. A FileSizeLimitExceededException was deferred until the complete file has been uploaded. Additionally, the FileSizeLimitException is now thrown immediately, if the attachments headers contain a content-length value, which exceeds the configured limit. Fixed a classpath problem when building with Sun JDK 1.3.1 and Ant. Made Streams.asString static. Eliminated duplicate code. Added a streaming API. Eliminated the necessity of a content-length header. Eliminated the limitation of a maximum size for a single header line. (The total size of all headers is already limited, so there's no need for another limit.) Added the ProgressListener, which allows to implement a progress bar. Added support for header continuation lines. It is now possible to limit the actual file size and not the request size. Added the FileCleanerCleanup as an example for how to close down the FileCleaner's reaper thread nicely. A descriptive NPE is now thrown, if the FileItemFactory has not been set. Cache disk file item size when it is moved to a new location. File names were being inadvertently converted to lower case. Updates for FileUpload 1.1-RC1. Added release notes for FileUpload 1.1. Update the User Guide to document the "right" way of using FileUpload 1.1, rather than the older, and thus deprecated, ways that are compatible with FileUpload 1.0. Add this change log, including all changes since the Commons FileUpload 1.0 release. Update Commons IO dependency to version 1.1. Add custom PMD configuration. Make inner exception classes static, which they should have been all along. Fix Checkstyle warnings. Remove Javadoc warnings. Build updates:
  • Include NOTICE.txt in the jar file and distributions.
  • Include xdocs in source distribution.
  • Create MD5 checksums for distributions.
Add custom Checkstyle configuration. Update dependencies in POM, and add comments and scope. Standardise on @throws instead of having a mixture of that and @exception. Make DiskFileItem serializable. Thanks to Niall Pemberton for the suggestion and patch. Make the temporary file names unique across class loaders, not just within them, by including a UID in the file name. Include the actual and permitted sizes in both the exception message and the exception itself. If an explicit header encoding is not specified, use the one from the appropriate context (i.e. ServletRequest or ActionRequest). Add getCharacterEncoding to the request context. Null check and case insensitivity fixes. Web site updates:
  • Add detail pages for Source Repository and Issue Tracking, based on those for IO and Validator.
  • Improvements to FileUpload home page, based on similar recent changes to IO and Validator home pages.
  • The Bugzilla component name has a space in it. Fix the URLs.
  • Add an FAQ page, using the Maven plugin to generate it.
Fixes to POMs Setting source and target for Java 1.3 Fix typos in Javadoc code examples. Fix typos in exception messages. Obtain request content type from container instead of headers. New mock objects from Jetspeed-2, and new FileUpload test cases. added toString() methods Fix up the existing package.html file and add new ones for the newly introduced packages. Fairly minimal, but with a link to the user guide. Substantial refactoring and additions:
  • The core package is now independent of servlet / portlet / other distinctions, as well as persistence schemes, other than deprecated classes and methods retained for backwards compatibility.
  • Servlet specific functionality has been moved to a new 'servlet' package. Existing users should migrate to this as soon as possible, since the servlet specific functionality in the generic package will be removed in the release after FileUpload 1.1.
  • Support for portlets (JSR 168) has been added, in a new 'portlet' package. This is not well tested at this point, and feedback would be very much appreciated. (This also resolves bug #23620.)
  • The disk-based file item implementation has been moved into a 'disk' package, and renamed from Default* to Disk* to reflect what it really is. The Default* classes have been retained in the top level package for backwards compatibility, but are now deprecated, and will be removed in the release after FileUpload 1.1.
  • The isMultipartRequest method is an unfortunate casualty of this refactoring. That method should really be moved to ServletFileUpload, but since the method is static, it can only exist in either FileUploadBase or ServletFileUpload. Backwards compatibility dictates the former for now, but the latter is the desired state, which implies some future breakage. Fair warning...
Specify the encoding (ISO-8859-1) when converting the boundary to a byte array. Convert to Sun coding guidelines. DeferredFileOutputStream moved to Commons IO. Workaround for Mac IE5 bug. Thanks to Justin Sampson for the patch and tests for this vexing issue. Handle unquoted header parameters. Some documentation on interaction with virus scanners. More unit tests from Justin Sampson. Use FileCleaner from Commons IO to clean up temp files, rather than File.deleteOnExit(), which can cause serious problems in long-running processes. Check that HTTP method is POST as part of multipart check. Switch to Commons IO version of DeferredFileOutputStream. Adding IO as a dependency will allow us to take advantage of other classes in that component to fix additional FileUpload bugs. handle quoted boundary specification. use case-independent comparisons for encoding types. Fix comments to avoid break iterator complaints. Fix typos in comments. Add support for character sets specified for individual parts. Change to Apache License 2.0 Correct the comment for the no-args constructor to reflect the fact that a factory needs to be set before parsing uploads. Collapse some all but duplicated code. Fix example showing FileItem.write to use a File object. Check for null before attempting to close streams in write(). Correction to sample code in the docs.
commons-fileupload-1.3.1-src/src/changes/release-notes.vm100644 0 0 7541 12274737402 20555 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. ${project.name} ${version} RELEASE NOTES The ${developmentTeam} is pleased to announce the release of ${project.name} ${version}. The Apache Commons FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications. Version 1.3 onwards requires Java 5 or later. No client code changes are required to migrate from version 1.3.0 to 1.3.1. ## N.B. the available variables are described here: ## http://maven.apache.org/plugins/maven-changes-plugin/examples/using-a-custom-announcement-template.html ## ## Hack to get line breaks to work in release description. For this to work, each line break in the ## release description attribute in changes.xml needs to be preceded by a single space. #set( $desc = $release.description ) #set( $desc2 = $desc.replace($esc.newline, " ") ) #set( $d = $desc2.replace(" ",$esc.newline) ) ${d} ## set up indent sizes. Only change indent1 #set($props=${project.properties}) #set($jiralen=$props.get("commons.jira.id").length()) ## indent1 = POOL-nnnn: #set($blanklen=$jiralen+6)## +6 for "-nnnn:" ## must be at least as long as the longest JIRA id #set($blanks=" ") #set($indent1=$blanks.substring(0,$blanklen)) ## indent2 allows for issue wrapper #set($indent2="$indent1 ") ## #macro ( processaction ) ## Use replaceAll to fix up LF-only line ends on Windows. #set($action=$actionItem.getAction().replaceAll("\n"," ")) ## Fix up indentation for multi-line action descriptions #set($action=$action.replaceAll("(?m)^ +",$indent2)) #if ($actionItem.getIssue()) #set($issue="$actionItem.getIssue():") ## Pad shorter issue numbers #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end #else #set($issue=$indent1) #end #if ($actionItem.getDueTo()) #set($dueto=" Thanks to $actionItem.getDueTo().") #else #set($dueto="") #end o $issue ${action}$dueto #set($action="") #set($issue="") #set($dueto="") #end ## #if ($release.getActions().size() == 0) No changes defined in this version. #else Changes in version ${version} include: #if ($release.getActions('add').size() !=0) New features: #foreach($actionItem in $release.getActions('add')) #processaction() #end #end #if ($release.getActions('fix').size() !=0) Fixed Bugs: #foreach($actionItem in $release.getActions('fix')) #processaction() #end #end #if ($release.getActions('update').size() !=0) Changes: #foreach($actionItem in $release.getActions('update')) #processaction() #end #end #if ($release.getActions('remove').size() !=0) Removed: #foreach($actionItem in $release.getActions('remove')) #processaction() #end #end ## End of main loop #end For complete information on ${project.name}, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache ${project.name} website: ${project.url} commons-fileupload-1.3.1-src/src/checkstyle/checkstyle-suppressions.xml100644 0 0 2062 12274737400 23613 0ustar 0 0 commons-fileupload-1.3.1-src/src/checkstyle/fileupload_basic.xml100644 0 0 2016 12274737400 22166 0ustar 0 0 PMD Basic Ruleset minus the EmptyCatchBlock rule. commons-fileupload-1.3.1-src/src/checkstyle/fileupload_checks.xml100644 0 0 22762 12274737400 22377 0ustar 0 0 commons-fileupload-1.3.1-src/src/checkstyle/license-header.txt100644 0 0 1557 12274737400 21601 0ustar 0 0 /\*\s* \*\s*Licensed to the Apache Software Foundation \(ASF\) under one or more \*\s*contributor license agreements. See the NOTICE file distributed with \*\s*this work for additional information regarding copyright ownership\. \*\s*The ASF licenses this file to You under the Apache License, Version 2\.0 \*\s*\(the "License"\); you may not use this file except in compliance with \*\s*the License\. You may obtain a copy of the License at \*\s* \*\s*http://www\.apache\.org/licenses/LICENSE\-2\.0 \*\s* \*\s*Unless required by applicable law or agreed to in writing, software \*\s*distributed under the License is distributed on an "AS IS" BASIS, \*\s*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. \*\s*See the License for the specific language governing permissions and \*\s*limitations under the License\. \*/\s* commons-fileupload-1.3.1-src/src/main/assembly/bin.xml100644 0 0 3336 12274737401 20065 0ustar 0 0 bin tar.gz zip ${project.build.finalName}-bin true LICENSE.txt NOTICE.txt ${project.build.directory} lib ${project.build.finalName}.jar commons-fileupload-1.3.1-src/src/main/assembly/src.xml100644 0 0 3461 12274737401 20103 0ustar 0 0 src tar.gz zip ${project.build.finalName}-src ${basedir} **/.classpath **/.project **/.settings/ **/.checkstyle/ **/doap_*.rdf **/bin/ **/.externalToolBuilders/ **/${project.build.directory}/ **/download*.cgi commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/DefaultFileItem.java100644 0 0 6520 12274737401 27350 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.File; import org.apache.commons.fileupload.disk.DiskFileItem; /** *

The default implementation of the * {@link org.apache.commons.fileupload.FileItem FileItem} interface. * *

After retrieving an instance of this class from a {@link * org.apache.commons.fileupload.DiskFileUpload DiskFileUpload} instance (see * {@link org.apache.commons.fileupload.DiskFileUpload * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * either request all contents of file at once using {@link #get()} or * request an {@link java.io.InputStream InputStream} with * {@link #getInputStream()} and process the file without attempting to load * it into memory, which may come handy with large files. * * @version $Id: DefaultFileItem.java 1454690 2013-03-09 12:08:48Z simonetripodi $ * * @deprecated 1.1 Use DiskFileItem instead. */ @Deprecated public class DefaultFileItem extends DiskFileItem { // ----------------------------------------------------------- Constructors /** * The UID to use when serializing this instance. */ private static final long serialVersionUID = 4088572813833518255L; /** * Constructs a new DefaultFileItem instance. * * @param fieldName The name of the form field. * @param contentType The content type passed by the browser or * null if not specified. * @param isFormField Whether or not this item is a plain form field, as * opposed to a file upload. * @param fileName The original filename in the user's filesystem, or * null if not specified. * @param sizeThreshold The threshold, in bytes, below which items will be * retained in memory and above which they will be * stored as a file. * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. * * @deprecated 1.1 Use DiskFileItem instead. */ @Deprecated public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); } } ././@LongLink100644 0 0 145 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/DefaultFileItemFactory.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/DefaultFileItemFactory.java100644 0 0 10223 12274737401 30713 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.File; import org.apache.commons.fileupload.disk.DiskFileItemFactory; /** *

The default {@link org.apache.commons.fileupload.FileItemFactory} * implementation. This implementation creates * {@link org.apache.commons.fileupload.FileItem} instances which keep their * content either in memory, for smaller items, or in a temporary file on disk, * for larger items. The size threshold, above which content will be stored on * disk, is configurable, as is the directory in which temporary files will be * created.

* *

If not otherwise configured, the default configuration values are as * follows: *

    *
  • Size threshold is 10KB.
  • *
  • Repository is the system default temp directory, as returned by * System.getProperty("java.io.tmpdir").
  • *
*

* * @version $Id: DefaultFileItemFactory.java 1454690 2013-03-09 12:08:48Z simonetripodi $ * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public class DefaultFileItemFactory extends DiskFileItemFactory { // ----------------------------------------------------------- Constructors /** * Constructs an unconfigured instance of this class. The resulting factory * may be configured by calling the appropriate setter methods. * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public DefaultFileItemFactory() { super(); } /** * Constructs a preconfigured instance of this class. * * @param sizeThreshold The threshold, in bytes, below which items will be * retained in memory and above which they will be * stored as a file. * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public DefaultFileItemFactory(int sizeThreshold, File repository) { super(sizeThreshold, repository); } // --------------------------------------------------------- Public Methods /** * Create a new {@link org.apache.commons.fileupload.DefaultFileItem} * instance from the supplied parameters and the local factory * configuration. * * @param fieldName The name of the form field. * @param contentType The content type of the form field. * @param isFormField true if this is a plain form field; * false otherwise. * @param fileName The name of the uploaded file, if any, as supplied * by the browser or other client. * * @return The newly created file item. * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Override @Deprecated public FileItem createItem( String fieldName, String contentType, boolean isFormField, String fileName ) { return new DefaultFileItem(fieldName, contentType, isFormField, fileName, getSizeThreshold(), getRepository()); } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java100644 0 0 60067 12274737402 27637 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.disk; import static java.lang.String.format; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemHeaders; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ParameterParser; import org.apache.commons.fileupload.util.Streams; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.DeferredFileOutputStream; /** *

The default implementation of the * {@link org.apache.commons.fileupload.FileItem FileItem} interface. * *

After retrieving an instance of this class from a {@link * DiskFileItemFactory} instance (see * {@link org.apache.commons.fileupload.servlet.ServletFileUpload * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * either request all contents of file at once using {@link #get()} or * request an {@link java.io.InputStream InputStream} with * {@link #getInputStream()} and process the file without attempting to load * it into memory, which may come handy with large files. * *

Temporary files, which are created for file items, should be * deleted later on. The best way to do this is using a * {@link org.apache.commons.io.FileCleaningTracker}, which you can set on the * {@link DiskFileItemFactory}. However, if you do use such a tracker, * then you must consider the following: Temporary files are automatically * deleted as soon as they are no longer needed. (More precisely, when the * corresponding instance of {@link java.io.File} is garbage collected.) * This is done by the so-called reaper thread, which is started and stopped * automatically by the {@link org.apache.commons.io.FileCleaningTracker} when * there are files to be tracked. * It might make sense to terminate that thread, for example, if * your web application ends. See the section on "Resource cleanup" * in the users guide of commons-fileupload.

* * @since FileUpload 1.1 * * @version $Id: DiskFileItem.java 1565192 2014-02-06 12:14:16Z markt $ */ public class DiskFileItem implements FileItem { // ----------------------------------------------------- Manifest constants /** * The UID to use when serializing this instance. */ private static final long serialVersionUID = 2237570099615271025L; /** * Default content charset to be used when no explicit charset * parameter is provided by the sender. Media subtypes of the * "text" type are defined to have a default charset value of * "ISO-8859-1" when received via HTTP. */ public static final String DEFAULT_CHARSET = "ISO-8859-1"; // ----------------------------------------------------------- Data members /** * UID used in unique file name generation. */ private static final String UID = UUID.randomUUID().toString().replace('-', '_'); /** * Counter used in unique identifier generation. */ private static final AtomicInteger COUNTER = new AtomicInteger(0); /** * The name of the form field as provided by the browser. */ private String fieldName; /** * The content type passed by the browser, or null if * not defined. */ private final String contentType; /** * Whether or not this item is a simple form field. */ private boolean isFormField; /** * The original filename in the user's filesystem. */ private final String fileName; /** * The size of the item, in bytes. This is used to cache the size when a * file item is moved from its original location. */ private long size = -1; /** * The threshold above which uploads will be stored on disk. */ private final int sizeThreshold; /** * The directory in which uploaded files will be stored, if stored on disk. */ private final File repository; /** * Cached contents of the file. */ private byte[] cachedContent; /** * Output stream for this item. */ private transient DeferredFileOutputStream dfos; /** * The temporary file to use. */ private transient File tempFile; /** * File to allow for serialization of the content of this item. */ private File dfosFile; /** * The file items headers. */ private FileItemHeaders headers; // ----------------------------------------------------------- Constructors /** * Constructs a new DiskFileItem instance. * * @param fieldName The name of the form field. * @param contentType The content type passed by the browser or * null if not specified. * @param isFormField Whether or not this item is a plain form field, as * opposed to a file upload. * @param fileName The original filename in the user's filesystem, or * null if not specified. * @param sizeThreshold The threshold, in bytes, below which items will be * retained in memory and above which they will be * stored as a file. * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. */ public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { this.fieldName = fieldName; this.contentType = contentType; this.isFormField = isFormField; this.fileName = fileName; this.sizeThreshold = sizeThreshold; this.repository = repository; } // ------------------------------- Methods from javax.activation.DataSource /** * Returns an {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @return An {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @throws IOException if an error occurs. */ public InputStream getInputStream() throws IOException { if (!isInMemory()) { return new FileInputStream(dfos.getFile()); } if (cachedContent == null) { cachedContent = dfos.getData(); } return new ByteArrayInputStream(cachedContent); } /** * Returns the content type passed by the agent or null if * not defined. * * @return The content type passed by the agent or null if * not defined. */ public String getContentType() { return contentType; } /** * Returns the content charset passed by the agent or null if * not defined. * * @return The content charset passed by the agent or null if * not defined. */ public String getCharSet() { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input Map params = parser.parse(getContentType(), ';'); return params.get("charset"); } /** * Returns the original filename in the client's filesystem. * * @return The original filename in the client's filesystem. * @throws org.apache.commons.fileupload.InvalidFileNameException The file name contains a NUL character, * which might be an indicator of a security attack. If you intend to * use the file name anyways, catch the exception and use * {@link org.apache.commons.fileupload.InvalidFileNameException#getName()}. */ public String getName() { return Streams.checkFileName(fileName); } // ------------------------------------------------------- FileItem methods /** * Provides a hint as to whether or not the file contents will be read * from memory. * * @return true if the file contents will be read * from memory; false otherwise. */ public boolean isInMemory() { if (cachedContent != null) { return true; } return dfos.isInMemory(); } /** * Returns the size of the file. * * @return The size of the file, in bytes. */ public long getSize() { if (size >= 0) { return size; } else if (cachedContent != null) { return cachedContent.length; } else if (dfos.isInMemory()) { return dfos.getData().length; } else { return dfos.getFile().length(); } } /** * Returns the contents of the file as an array of bytes. If the * contents of the file were not yet cached in memory, they will be * loaded from the disk storage and cached. * * @return The contents of the file as an array of bytes. */ public byte[] get() { if (isInMemory()) { if (cachedContent == null) { cachedContent = dfos.getData(); } return cachedContent; } byte[] fileData = new byte[(int) getSize()]; InputStream fis = null; try { fis = new BufferedInputStream(new FileInputStream(dfos.getFile())); fis.read(fileData); } catch (IOException e) { fileData = null; } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { // ignore } } } return fileData; } /** * Returns the contents of the file as a String, using the specified * encoding. This method uses {@link #get()} to retrieve the * contents of the file. * * @param charset The charset to use. * * @return The contents of the file, as a string. * * @throws UnsupportedEncodingException if the requested character * encoding is not available. */ public String getString(final String charset) throws UnsupportedEncodingException { return new String(get(), charset); } /** * Returns the contents of the file as a String, using the default * character encoding. This method uses {@link #get()} to retrieve the * contents of the file. * * TODO Consider making this method throw UnsupportedEncodingException. * * @return The contents of the file, as a string. */ public String getString() { byte[] rawdata = get(); String charset = getCharSet(); if (charset == null) { charset = DEFAULT_CHARSET; } try { return new String(rawdata, charset); } catch (UnsupportedEncodingException e) { return new String(rawdata); } } /** * A convenience method to write an uploaded item to disk. The client code * is not concerned with whether or not the item is stored in memory, or on * disk in a temporary location. They just want to write the uploaded item * to a file. *

* This implementation first attempts to rename the uploaded item to the * specified destination file, if the item was originally written to disk. * Otherwise, the data will be copied to the specified file. *

* This method is only guaranteed to work once, the first time it * is invoked for a particular item. This is because, in the event that the * method renames a temporary file, that file will no longer be available * to copy or rename again at a later time. * * @param file The File into which the uploaded item should * be stored. * * @throws Exception if an error occurs. */ public void write(File file) throws Exception { if (isInMemory()) { FileOutputStream fout = null; try { fout = new FileOutputStream(file); fout.write(get()); } finally { if (fout != null) { fout.close(); } } } else { File outputFile = getStoreLocation(); if (outputFile != null) { // Save the length of the file size = outputFile.length(); /* * The uploaded file is being stored on disk * in a temporary location so move it to the * desired file. */ if (!outputFile.renameTo(file)) { BufferedInputStream in = null; BufferedOutputStream out = null; try { in = new BufferedInputStream( new FileInputStream(outputFile)); out = new BufferedOutputStream( new FileOutputStream(file)); IOUtils.copy(in, out); } finally { if (in != null) { try { in.close(); } catch (IOException e) { // ignore } } if (out != null) { try { out.close(); } catch (IOException e) { // ignore } } } } } else { /* * For whatever reason we cannot write the * file to disk. */ throw new FileUploadException( "Cannot write uploaded file to disk!"); } } } /** * Deletes the underlying storage for a file item, including deleting any * associated temporary disk file. Although this storage will be deleted * automatically when the FileItem instance is garbage * collected, this method can be used to ensure that this is done at an * earlier time, thus preserving system resources. */ public void delete() { cachedContent = null; File outputFile = getStoreLocation(); if (outputFile != null && outputFile.exists()) { outputFile.delete(); } } /** * Returns the name of the field in the multipart form corresponding to * this file item. * * @return The name of the form field. * * @see #setFieldName(java.lang.String) * */ public String getFieldName() { return fieldName; } /** * Sets the field name used to reference this file item. * * @param fieldName The name of the form field. * * @see #getFieldName() * */ public void setFieldName(String fieldName) { this.fieldName = fieldName; } /** * Determines whether or not a FileItem instance represents * a simple form field. * * @return true if the instance represents a simple form * field; false if it represents an uploaded file. * * @see #setFormField(boolean) * */ public boolean isFormField() { return isFormField; } /** * Specifies whether or not a FileItem instance represents * a simple form field. * * @param state true if the instance represents a simple form * field; false if it represents an uploaded file. * * @see #isFormField() * */ public void setFormField(boolean state) { isFormField = state; } /** * Returns an {@link java.io.OutputStream OutputStream} that can * be used for storing the contents of the file. * * @return An {@link java.io.OutputStream OutputStream} that can be used * for storing the contensts of the file. * * @throws IOException if an error occurs. */ public OutputStream getOutputStream() throws IOException { if (dfos == null) { File outputFile = getTempFile(); dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); } return dfos; } // --------------------------------------------------------- Public methods /** * Returns the {@link java.io.File} object for the FileItem's * data's temporary location on the disk. Note that for * FileItems that have their data stored in memory, * this method will return null. When handling large * files, you can use {@link java.io.File#renameTo(java.io.File)} to * move the file to new location without copying the data, if the * source and destination locations reside within the same logical * volume. * * @return The data file, or null if the data is stored in * memory. */ public File getStoreLocation() { if (dfos == null) { return null; } return dfos.getFile(); } // ------------------------------------------------------ Protected methods /** * Removes the file contents from the temporary storage. */ @Override protected void finalize() { File outputFile = dfos.getFile(); if (outputFile != null && outputFile.exists()) { outputFile.delete(); } } /** * Creates and returns a {@link java.io.File File} representing a uniquely * named temporary file in the configured repository path. The lifetime of * the file is tied to the lifetime of the FileItem instance; * the file will be deleted when the instance is garbage collected. * * @return The {@link java.io.File File} to be used for temporary storage. */ protected File getTempFile() { if (tempFile == null) { File tempDir = repository; if (tempDir == null) { tempDir = new File(System.getProperty("java.io.tmpdir")); } String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId()); tempFile = new File(tempDir, tempFileName); } return tempFile; } // -------------------------------------------------------- Private methods /** * Returns an identifier that is unique within the class loader used to * load this class, but does not have random-like apearance. * * @return A String with the non-random looking instance identifier. */ private static String getUniqueId() { final int limit = 100000000; int current = COUNTER.getAndIncrement(); String id = Integer.toString(current); // If you manage to get more than 100 million of ids, you'll // start getting ids longer than 8 characters. if (current < limit) { id = ("00000000" + id).substring(id.length()); } return id; } /** * Returns a string representation of this object. * * @return a string representation of this object. */ @Override public String toString() { return format("name=%s, StoreLocation=%s, size=%s bytes, isFormField=%s, FieldName=%s", getName(), getStoreLocation(), Long.valueOf(getSize()), Boolean.valueOf(isFormField()), getFieldName()); } // -------------------------------------------------- Serialization methods /** * Writes the state of this object during serialization. * * @param out The stream to which the state should be written. * * @throws IOException if an error occurs. */ private void writeObject(ObjectOutputStream out) throws IOException { // Read the data if (dfos.isInMemory()) { cachedContent = get(); } else { cachedContent = null; dfosFile = dfos.getFile(); } // write out values out.defaultWriteObject(); } /** * Reads the state of this object during deserialization. * * @param in The stream from which the state should be read. * * @throws IOException if an error occurs. * @throws ClassNotFoundException if class cannot be found. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // read values in.defaultReadObject(); /* One expected use of serialization is to migrate HTTP sessions * containing a DiskFileItem between JVMs. Particularly if the JVMs are * on different machines It is possible that the repository location is * not valid so validate it. */ if (repository != null) { if (repository.isDirectory()) { // Check path for nulls if (repository.getPath().contains("\0")) { throw new IOException(format( "The repository [%s] contains a null character", repository.getPath())); } } else { throw new IOException(format( "The repository [%s] is not a directory", repository.getAbsolutePath())); } } OutputStream output = getOutputStream(); if (cachedContent != null) { output.write(cachedContent); } else { FileInputStream input = new FileInputStream(dfosFile); IOUtils.copy(input, output); dfosFile.delete(); dfosFile = null; } output.close(); cachedContent = null; } /** * Returns the file item headers. * @return The file items headers. */ public FileItemHeaders getHeaders() { return headers; } /** * Sets the file item headers. * @param pHeaders The file items headers. */ public void setHeaders(FileItemHeaders pHeaders) { headers = pHeaders; } } ././@LongLink100644 0 0 147 12274740161 10261 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.ja100644 0 0 21125 12274737402 30630 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.disk; import java.io.File; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.io.FileCleaningTracker; /** *

The default {@link org.apache.commons.fileupload.FileItemFactory} * implementation. This implementation creates * {@link org.apache.commons.fileupload.FileItem} instances which keep their * content either in memory, for smaller items, or in a temporary file on disk, * for larger items. The size threshold, above which content will be stored on * disk, is configurable, as is the directory in which temporary files will be * created.

* *

If not otherwise configured, the default configuration values are as * follows:

*
    *
  • Size threshold is 10KB.
  • *
  • Repository is the system default temp directory, as returned by * System.getProperty("java.io.tmpdir").
  • *
*

* NOTE: Files are created in the system default temp directory with * predictable names. This means that a local attacker with write access to that * directory can perform a TOUTOC attack to replace any uploaded file with a * file of the attackers choice. The implications of this will depend on how the * uploaded file is used but could be significant. When using this * implementation in an environment with local, untrusted users, * {@link #setRepository(File)} MUST be used to configure a repository location * that is not publicly writable. In a Servlet container the location identified * by the ServletContext attribute javax.servlet.context.tempdir * may be used. *

* *

Temporary files, which are created for file items, should be * deleted later on. The best way to do this is using a * {@link FileCleaningTracker}, which you can set on the * {@link DiskFileItemFactory}. However, if you do use such a tracker, * then you must consider the following: Temporary files are automatically * deleted as soon as they are no longer needed. (More precisely, when the * corresponding instance of {@link java.io.File} is garbage collected.) * This is done by the so-called reaper thread, which is started and stopped * automatically by the {@link FileCleaningTracker} when there are files to be * tracked. * It might make sense to terminate that thread, for example, if * your web application ends. See the section on "Resource cleanup" * in the users guide of commons-fileupload.

* * @since FileUpload 1.1 * * @version $Id: DiskFileItemFactory.java 1564788 2014-02-05 14:36:41Z markt $ */ public class DiskFileItemFactory implements FileItemFactory { // ----------------------------------------------------- Manifest constants /** * The default threshold above which uploads will be stored on disk. */ public static final int DEFAULT_SIZE_THRESHOLD = 10240; // ----------------------------------------------------- Instance Variables /** * The directory in which uploaded files will be stored, if stored on disk. */ private File repository; /** * The threshold above which uploads will be stored on disk. */ private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; /** *

The instance of {@link FileCleaningTracker}, which is responsible * for deleting temporary files.

*

May be null, if tracking files is not required.

*/ private FileCleaningTracker fileCleaningTracker; // ----------------------------------------------------------- Constructors /** * Constructs an unconfigured instance of this class. The resulting factory * may be configured by calling the appropriate setter methods. */ public DiskFileItemFactory() { this(DEFAULT_SIZE_THRESHOLD, null); } /** * Constructs a preconfigured instance of this class. * * @param sizeThreshold The threshold, in bytes, below which items will be * retained in memory and above which they will be * stored as a file. * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. */ public DiskFileItemFactory(int sizeThreshold, File repository) { this.sizeThreshold = sizeThreshold; this.repository = repository; } // ------------------------------------------------------------- Properties /** * Returns the directory used to temporarily store files that are larger * than the configured size threshold. * * @return The directory in which temporary files will be located. * * @see #setRepository(java.io.File) * */ public File getRepository() { return repository; } /** * Sets the directory used to temporarily store files that are larger * than the configured size threshold. * * @param repository The directory in which temporary files will be located. * * @see #getRepository() * */ public void setRepository(File repository) { this.repository = repository; } /** * Returns the size threshold beyond which files are written directly to * disk. The default value is 10240 bytes. * * @return The size threshold, in bytes. * * @see #setSizeThreshold(int) */ public int getSizeThreshold() { return sizeThreshold; } /** * Sets the size threshold beyond which files are written directly to disk. * * @param sizeThreshold The size threshold, in bytes. * * @see #getSizeThreshold() * */ public void setSizeThreshold(int sizeThreshold) { this.sizeThreshold = sizeThreshold; } // --------------------------------------------------------- Public Methods /** * Create a new {@link org.apache.commons.fileupload.disk.DiskFileItem} * instance from the supplied parameters and the local factory * configuration. * * @param fieldName The name of the form field. * @param contentType The content type of the form field. * @param isFormField true if this is a plain form field; * false otherwise. * @param fileName The name of the uploaded file, if any, as supplied * by the browser or other client. * * @return The newly created file item. */ public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); FileCleaningTracker tracker = getFileCleaningTracker(); if (tracker != null) { tracker.track(result.getTempFile(), result); } return result; } /** * Returns the tracker, which is responsible for deleting temporary * files. * * @return An instance of {@link FileCleaningTracker}, or null * (default), if temporary files aren't tracked. */ public FileCleaningTracker getFileCleaningTracker() { return fileCleaningTracker; } /** * Sets the tracker, which is responsible for deleting temporary * files. * * @param pTracker An instance of {@link FileCleaningTracker}, * which will from now on track the created files, or null * (default), to disable tracking. */ public void setFileCleaningTracker(FileCleaningTracker pTracker) { fileCleaningTracker = pTracker; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/disk/package-info.java100644 0 0 4630 12274737402 27624 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** *

* A disk-based implementation of the * {@link org.apache.commons.fileupload.FileItem FileItem} * interface. This implementation retains smaller items in memory, while * writing larger ones to disk. The threshold between these two is * configurable, as is the location of files that are written to disk. *

*

* In typical usage, an instance of * {@link org.apache.commons.fileupload.disk.DiskFileItemFactory DiskFileItemFactory} * would be created, configured, and then passed to a * {@link org.apache.commons.fileupload.FileUpload FileUpload} * implementation such as * {@link org.apache.commons.fileupload.servlet.ServletFileUpload ServletFileUpload} * or * {@link org.apache.commons.fileupload.portlet.PortletFileUpload PortletFileUpload}. *

*

* The following code fragment demonstrates this usage. *

*
 *        DiskFileItemFactory factory = new DiskFileItemFactory();
 *        // maximum size that will be stored in memory
 *        factory.setSizeThreshold(4096);
 *        // the location for saving data that is larger than getSizeThreshold()
 *        factory.setRepository(new File("/tmp"));
 *
 *        ServletFileUpload upload = new ServletFileUpload(factory);
 * 
*

* Please see the FileUpload * User Guide * for further details and examples of how to use this package. *

*/ package org.apache.commons.fileupload.disk; commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/DiskFileUpload.java100644 0 0 16121 12274737401 27222 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.File; import java.util.List; import javax.servlet.http.HttpServletRequest; /** *

High level API for processing file uploads.

* *

This class handles multiple files per single HTML widget, sent using * multipart/mixed encoding type, as specified by * RFC 1867. Use {@link * #parseRequest(HttpServletRequest)} to acquire a list of {@link * org.apache.commons.fileupload.FileItem}s associated with a given HTML * widget.

* *

Individual parts will be stored in temporary disk storage or in memory, * depending on their size, and will be available as {@link * org.apache.commons.fileupload.FileItem}s.

* * @version $Id: DiskFileUpload.java 1454690 2013-03-09 12:08:48Z simonetripodi $ * * @deprecated 1.1 Use ServletFileUpload together with * DiskFileItemFactory instead. */ @Deprecated public class DiskFileUpload extends FileUploadBase { // ----------------------------------------------------------- Data members /** * The factory to use to create new form items. */ private DefaultFileItemFactory fileItemFactory; // ----------------------------------------------------------- Constructors /** * Constructs an instance of this class which uses the default factory to * create FileItem instances. * * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) * * @deprecated 1.1 Use FileUpload instead. */ @Deprecated public DiskFileUpload() { super(); this.fileItemFactory = new DefaultFileItemFactory(); } /** * Constructs an instance of this class which uses the supplied factory to * create FileItem instances. * * @see #DiskFileUpload() * @param fileItemFactory The file item factory to use. * * @deprecated 1.1 Use FileUpload instead. */ @Deprecated public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { super(); this.fileItemFactory = fileItemFactory; } // ----------------------------------------------------- Property accessors /** * Returns the factory class used when creating file items. * * @return The factory class for new file items. * * @deprecated 1.1 Use FileUpload instead. */ @Override @Deprecated public FileItemFactory getFileItemFactory() { return fileItemFactory; } /** * Sets the factory class to use when creating file items. The factory must * be an instance of DefaultFileItemFactory or a subclass * thereof, or else a ClassCastException will be thrown. * * @param factory The factory class for new file items. * * @deprecated 1.1 Use FileUpload instead. */ @Override @Deprecated public void setFileItemFactory(FileItemFactory factory) { this.fileItemFactory = (DefaultFileItemFactory) factory; } /** * Returns the size threshold beyond which files are written directly to * disk. * * @return The size threshold, in bytes. * * @see #setSizeThreshold(int) * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public int getSizeThreshold() { return fileItemFactory.getSizeThreshold(); } /** * Sets the size threshold beyond which files are written directly to disk. * * @param sizeThreshold The size threshold, in bytes. * * @see #getSizeThreshold() * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public void setSizeThreshold(int sizeThreshold) { fileItemFactory.setSizeThreshold(sizeThreshold); } /** * Returns the location used to temporarily store files that are larger * than the configured size threshold. * * @return The path to the temporary file location. * * @see #setRepositoryPath(String) * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public String getRepositoryPath() { return fileItemFactory.getRepository().getPath(); } /** * Sets the location used to temporarily store files that are larger * than the configured size threshold. * * @param repositoryPath The path to the temporary file location. * * @see #getRepositoryPath() * * @deprecated 1.1 Use DiskFileItemFactory instead. */ @Deprecated public void setRepositoryPath(String repositoryPath) { fileItemFactory.setRepository(new File(repositoryPath)); } // --------------------------------------------------------- Public methods /** * Processes an RFC 1867 * compliant multipart/form-data stream. If files are stored * on disk, the path is given by getRepository(). * * @param req The servlet request to be parsed. Must be non-null. * @param sizeThreshold The max size in bytes to be stored in memory. * @param sizeMax The maximum allowed upload size, in bytes. * @param path The location where the files should be stored. * * @return A list of FileItem instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * * @deprecated 1.1 Use ServletFileUpload instead. */ @Deprecated public List parseRequest(HttpServletRequest req, int sizeThreshold, long sizeMax, String path) throws FileUploadException { setSizeThreshold(sizeThreshold); setSizeMax(sizeMax); setRepositoryPath(path); return parseRequest(req); } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItem.java100644 0 0 17421 12274737401 26065 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.io.UnsupportedEncodingException; /** *

This class represents a file or form item that was received within a * multipart/form-data POST request. * *

After retrieving an instance of this class from a {@link * org.apache.commons.fileupload.FileUpload FileUpload} instance (see * {@link org.apache.commons.fileupload.servlet.ServletFileUpload * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * either request all contents of the file at once using {@link #get()} or * request an {@link java.io.InputStream InputStream} with * {@link #getInputStream()} and process the file without attempting to load * it into memory, which may come handy with large files. * *

While this interface does not extend * javax.activation.DataSource per se (to avoid a seldom used * dependency), several of the defined methods are specifically defined with * the same signatures as methods in that interface. This allows an * implementation of this interface to also implement * javax.activation.DataSource with minimal additional work. * * @version $Id: FileItem.java 1454690 2013-03-09 12:08:48Z simonetripodi $ * @since 1.3 additionally implements FileItemHeadersSupport */ public interface FileItem extends Serializable, FileItemHeadersSupport { // ------------------------------- Methods from javax.activation.DataSource /** * Returns an {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @return An {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @throws IOException if an error occurs. */ InputStream getInputStream() throws IOException; /** * Returns the content type passed by the browser or null if * not defined. * * @return The content type passed by the browser or null if * not defined. */ String getContentType(); /** * Returns the original filename in the client's filesystem, as provided by * the browser (or other client software). In most cases, this will be the * base file name, without path information. However, some clients, such as * the Opera browser, do include path information. * * @return The original filename in the client's filesystem. * @throws InvalidFileNameException The file name contains a NUL character, * which might be an indicator of a security attack. If you intend to * use the file name anyways, catch the exception and use * InvalidFileNameException#getName(). */ String getName(); // ------------------------------------------------------- FileItem methods /** * Provides a hint as to whether or not the file contents will be read * from memory. * * @return true if the file contents will be read from memory; * false otherwise. */ boolean isInMemory(); /** * Returns the size of the file item. * * @return The size of the file item, in bytes. */ long getSize(); /** * Returns the contents of the file item as an array of bytes. * * @return The contents of the file item as an array of bytes. */ byte[] get(); /** * Returns the contents of the file item as a String, using the specified * encoding. This method uses {@link #get()} to retrieve the * contents of the item. * * @param encoding The character encoding to use. * * @return The contents of the item, as a string. * * @throws UnsupportedEncodingException if the requested character * encoding is not available. */ String getString(String encoding) throws UnsupportedEncodingException; /** * Returns the contents of the file item as a String, using the default * character encoding. This method uses {@link #get()} to retrieve the * contents of the item. * * @return The contents of the item, as a string. */ String getString(); /** * A convenience method to write an uploaded item to disk. The client code * is not concerned with whether or not the item is stored in memory, or on * disk in a temporary location. They just want to write the uploaded item * to a file. *

* This method is not guaranteed to succeed if called more than once for * the same item. This allows a particular implementation to use, for * example, file renaming, where possible, rather than copying all of the * underlying data, thus gaining a significant performance benefit. * * @param file The File into which the uploaded item should * be stored. * * @throws Exception if an error occurs. */ void write(File file) throws Exception; /** * Deletes the underlying storage for a file item, including deleting any * associated temporary disk file. Although this storage will be deleted * automatically when the FileItem instance is garbage * collected, this method can be used to ensure that this is done at an * earlier time, thus preserving system resources. */ void delete(); /** * Returns the name of the field in the multipart form corresponding to * this file item. * * @return The name of the form field. */ String getFieldName(); /** * Sets the field name used to reference this file item. * * @param name The name of the form field. */ void setFieldName(String name); /** * Determines whether or not a FileItem instance represents * a simple form field. * * @return true if the instance represents a simple form * field; false if it represents an uploaded file. */ boolean isFormField(); /** * Specifies whether or not a FileItem instance represents * a simple form field. * * @param state true if the instance represents a simple form * field; false if it represents an uploaded file. */ void setFormField(boolean state); /** * Returns an {@link java.io.OutputStream OutputStream} that can * be used for storing the contents of the file. * * @return An {@link java.io.OutputStream OutputStream} that can be used * for storing the contensts of the file. * * @throws IOException if an error occurs. */ OutputStream getOutputStream() throws IOException; } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemFactory.java100644 0 0 3655 12274737401 27401 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** *

A factory interface for creating {@link FileItem} instances. Factories * can provide their own custom configuration, over and above that provided * by the default file upload implementation.

* * @version $Id: FileItemFactory.java 1454690 2013-03-09 12:08:48Z simonetripodi $ */ public interface FileItemFactory { /** * Create a new {@link FileItem} instance from the supplied parameters and * any local factory configuration. * * @param fieldName The name of the form field. * @param contentType The content type of the form field. * @param isFormField true if this is a plain form field; * false otherwise. * @param fileName The name of the uploaded file, if any, as supplied * by the browser or other client. * * @return The newly created file item. */ FileItem createItem( String fieldName, String contentType, boolean isFormField, String fileName ); } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemHeaders.java100644 0 0 5546 12274737401 27346 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.util.Iterator; /** *

This class provides support for accessing the headers for a file or form * item that was received within a multipart/form-data POST * request.

* * @since 1.2.1 * * @version $Id$ */ public interface FileItemHeaders { /** * Returns the value of the specified part header as a String. * * If the part did not include a header of the specified name, this method * return null. If there are multiple headers with the same * name, this method returns the first header in the item. The header * name is case insensitive. * * @param name a String specifying the header name * @return a String containing the value of the requested * header, or null if the item does not have a header * of that name */ String getHeader(String name); /** *

* Returns all the values of the specified item header as an * Iterator of String objects. *

*

* If the item did not include any headers of the specified name, this * method returns an empty Iterator. The header name is * case insensitive. *

* * @param name a String specifying the header name * @return an Iterator containing the values of the * requested header. If the item does not have any headers of * that name, return an empty Iterator */ Iterator getHeaders(String name); /** *

* Returns an Iterator of all the header names. *

* * @return an Iterator containing all of the names of * headers provided with this file item. If the item does not have * any headers return an empty Iterator */ Iterator getHeaderNames(); } ././@LongLink100644 0 0 145 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemHeadersSupport.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemHeadersSupport.java100644 0 0 3354 12274737401 30736 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** * Interface that will indicate that {@link FileItem} or {@link FileItemStream} * implementations will accept the headers read for the item. * * @since 1.2.1 * * @see FileItem * @see FileItemStream * * @version $Id$ */ public interface FileItemHeadersSupport { /** * Returns the collection of headers defined locally within this item. * * @return the {@link FileItemHeaders} present for this item. */ FileItemHeaders getHeaders(); /** * Sets the headers read from within an item. Implementations of * {@link FileItem} or {@link FileItemStream} should implement this * interface to be able to get the raw headers found within the item * header block. * * @param headers the instance that holds onto the headers * for this instance. */ void setHeaders(FileItemHeaders headers); } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemIterator.java100644 0 0 4053 12274737402 27555 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.IOException; /** * An iterator, as returned by * {@link FileUploadBase#getItemIterator(RequestContext)}. * * @version $Id: FileItemIterator.java 1454691 2013-03-09 12:15:54Z simonetripodi $ */ public interface FileItemIterator { /** * Returns, whether another instance of {@link FileItemStream} * is available. * * @throws FileUploadException Parsing or processing the * file item failed. * @throws IOException Reading the file item failed. * @return True, if one or more additional file items * are available, otherwise false. */ boolean hasNext() throws FileUploadException, IOException; /** * Returns the next available {@link FileItemStream}. * * @throws java.util.NoSuchElementException No more items are available. Use * {@link #hasNext()} to prevent this exception. * @throws FileUploadException Parsing or processing the * file item failed. * @throws IOException Reading the file item failed. * @return FileItemStream instance, which provides * access to the next file item. */ FileItemStream next() throws FileUploadException, IOException; } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileItemStream.java100644 0 0 7711 12274737402 27223 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.IOException; import java.io.InputStream; /** *

This interface provides access to a file or form item that was * received within a multipart/form-data POST request. * The items contents are retrieved by calling {@link #openStream()}.

*

Instances of this class are created by accessing the * iterator, returned by * {@link FileUploadBase#getItemIterator(RequestContext)}.

*

Note: There is an interaction between the iterator and * its associated instances of {@link FileItemStream}: By invoking * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, * which hasn't been read so far from the previous data.

* * @version $Id: FileItemStream.java 1454691 2013-03-09 12:15:54Z simonetripodi $ */ public interface FileItemStream extends FileItemHeadersSupport { /** * This exception is thrown, if an attempt is made to read * data from the {@link InputStream}, which has been returned * by {@link FileItemStream#openStream()}, after * {@link java.util.Iterator#hasNext()} has been invoked on the * iterator, which created the {@link FileItemStream}. */ public static class ItemSkippedException extends IOException { /** * The exceptions serial version UID, which is being used * when serializing an exception instance. */ private static final long serialVersionUID = -7280778431581963740L; } /** * Creates an {@link InputStream}, which allows to read the * items contents. * * @return The input stream, from which the items data may * be read. * @throws IllegalStateException The method was already invoked on * this item. It is not possible to recreate the data stream. * @throws IOException An I/O error occurred. * @see ItemSkippedException */ InputStream openStream() throws IOException; /** * Returns the content type passed by the browser or null if * not defined. * * @return The content type passed by the browser or null if * not defined. */ String getContentType(); /** * Returns the original filename in the client's filesystem, as provided by * the browser (or other client software). In most cases, this will be the * base file name, without path information. However, some clients, such as * the Opera browser, do include path information. * * @return The original filename in the client's filesystem. */ String getName(); /** * Returns the name of the field in the multipart form corresponding to * this file item. * * @return The name of the form field. */ String getFieldName(); /** * Determines whether or not a FileItem instance represents * a simple form field. * * @return true if the instance represents a simple form * field; false if it represents an uploaded file. */ boolean isFormField(); } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileUpload.java100644 0 0 6247 12274737401 26377 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** *

High level API for processing file uploads.

* *

This class handles multiple files per single HTML widget, sent using * multipart/mixed encoding type, as specified by * RFC 1867. Use {@link * #parseRequest(RequestContext)} to acquire a list * of {@link org.apache.commons.fileupload.FileItem FileItems} associated * with a given HTML widget.

* *

How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.

* * @version $Id: FileUpload.java 1454690 2013-03-09 12:08:48Z simonetripodi $ */ public class FileUpload extends FileUploadBase { // ----------------------------------------------------------- Data members /** * The factory to use to create new form items. */ private FileItemFactory fileItemFactory; // ----------------------------------------------------------- Constructors /** * Constructs an uninitialised instance of this class. * * A factory must be * configured, using setFileItemFactory(), before attempting * to parse requests. * * @see #FileUpload(FileItemFactory) */ public FileUpload() { super(); } /** * Constructs an instance of this class which uses the supplied factory to * create FileItem instances. * * @see #FileUpload() * @param fileItemFactory The factory to use for creating file items. */ public FileUpload(FileItemFactory fileItemFactory) { super(); this.fileItemFactory = fileItemFactory; } // ----------------------------------------------------- Property accessors /** * Returns the factory class used when creating file items. * * @return The factory class for new file items. */ @Override public FileItemFactory getFileItemFactory() { return fileItemFactory; } /** * Sets the factory class to use when creating file items. * * @param factory The factory class for new file items. */ @Override public void setFileItemFactory(FileItemFactory factory) { this.fileItemFactory = factory; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileUploadBase.java100644 0 0 150132 12274737401 27223 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static java.lang.String.format; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.MultipartStream.ItemInputStream; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.commons.fileupload.util.Closeable; import org.apache.commons.fileupload.util.FileItemHeadersImpl; import org.apache.commons.fileupload.util.LimitedInputStream; import org.apache.commons.fileupload.util.Streams; /** *

High level API for processing file uploads.

* *

This class handles multiple files per single HTML widget, sent using * multipart/mixed encoding type, as specified by * RFC 1867. Use {@link * #parseRequest(RequestContext)} to acquire a list of {@link * org.apache.commons.fileupload.FileItem}s associated with a given HTML * widget.

* *

How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.

* * @version $Id: FileUploadBase.java 1565194 2014-02-06 12:16:30Z markt $ */ public abstract class FileUploadBase { // ---------------------------------------------------------- Class methods /** *

Utility method that determines whether the request contains multipart * content.

* *

NOTE:This method will be moved to the * ServletFileUpload class after the FileUpload 1.1 release. * Unfortunately, since this method is static, it is not possible to * provide its replacement until this method is removed.

* * @param ctx The request context to be evaluated. Must be non-null. * * @return true if the request is multipart; * false otherwise. */ public static final boolean isMultipartContent(RequestContext ctx) { String contentType = ctx.getContentType(); if (contentType == null) { return false; } if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) { return true; } return false; } /** * Utility method that determines whether the request contains multipart * content. * * @param req The servlet request to be evaluated. Must be non-null. * * @return true if the request is multipart; * false otherwise. * * @deprecated 1.1 Use the method on ServletFileUpload instead. */ @Deprecated public static boolean isMultipartContent(HttpServletRequest req) { return ServletFileUpload.isMultipartContent(req); } // ----------------------------------------------------- Manifest constants /** * HTTP content type header name. */ public static final String CONTENT_TYPE = "Content-type"; /** * HTTP content disposition header name. */ public static final String CONTENT_DISPOSITION = "Content-disposition"; /** * HTTP content length header name. */ public static final String CONTENT_LENGTH = "Content-length"; /** * Content-disposition value for form data. */ public static final String FORM_DATA = "form-data"; /** * Content-disposition value for file attachment. */ public static final String ATTACHMENT = "attachment"; /** * Part of HTTP content type header. */ public static final String MULTIPART = "multipart/"; /** * HTTP content type header for multipart forms. */ public static final String MULTIPART_FORM_DATA = "multipart/form-data"; /** * HTTP content type header for multiple uploads. */ public static final String MULTIPART_MIXED = "multipart/mixed"; /** * The maximum length of a single header line that will be parsed * (1024 bytes). * @deprecated This constant is no longer used. As of commons-fileupload * 1.2, the only applicable limit is the total size of a parts headers, * {@link MultipartStream#HEADER_PART_SIZE_MAX}. */ @Deprecated public static final int MAX_HEADER_SIZE = 1024; // ----------------------------------------------------------- Data members /** * The maximum size permitted for the complete request, as opposed to * {@link #fileSizeMax}. A value of -1 indicates no maximum. */ private long sizeMax = -1; /** * The maximum size permitted for a single uploaded file, as opposed * to {@link #sizeMax}. A value of -1 indicates no maximum. */ private long fileSizeMax = -1; /** * The content encoding to use when reading part headers. */ private String headerEncoding; /** * The progress listener. */ private ProgressListener listener; // ----------------------------------------------------- Property accessors /** * Returns the factory class used when creating file items. * * @return The factory class for new file items. */ public abstract FileItemFactory getFileItemFactory(); /** * Sets the factory class to use when creating file items. * * @param factory The factory class for new file items. */ public abstract void setFileItemFactory(FileItemFactory factory); /** * Returns the maximum allowed size of a complete request, as opposed * to {@link #getFileSizeMax()}. * * @return The maximum allowed size, in bytes. The default value of * -1 indicates, that there is no limit. * * @see #setSizeMax(long) * */ public long getSizeMax() { return sizeMax; } /** * Sets the maximum allowed size of a complete request, as opposed * to {@link #setFileSizeMax(long)}. * * @param sizeMax The maximum allowed size, in bytes. The default value of * -1 indicates, that there is no limit. * * @see #getSizeMax() * */ public void setSizeMax(long sizeMax) { this.sizeMax = sizeMax; } /** * Returns the maximum allowed size of a single uploaded file, * as opposed to {@link #getSizeMax()}. * * @see #setFileSizeMax(long) * @return Maximum size of a single uploaded file. */ public long getFileSizeMax() { return fileSizeMax; } /** * Sets the maximum allowed size of a single uploaded file, * as opposed to {@link #getSizeMax()}. * * @see #getFileSizeMax() * @param fileSizeMax Maximum size of a single uploaded file. */ public void setFileSizeMax(long fileSizeMax) { this.fileSizeMax = fileSizeMax; } /** * Retrieves the character encoding used when reading the headers of an * individual part. When not specified, or null, the request * encoding is used. If that is also not specified, or null, * the platform default encoding is used. * * @return The encoding used to read part headers. */ public String getHeaderEncoding() { return headerEncoding; } /** * Specifies the character encoding to be used when reading the headers of * individual part. When not specified, or null, the request * encoding is used. If that is also not specified, or null, * the platform default encoding is used. * * @param encoding The encoding used to read part headers. */ public void setHeaderEncoding(String encoding) { headerEncoding = encoding; } // --------------------------------------------------------- Public methods /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param req The servlet request to be parsed. * * @return A list of FileItem instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * * @deprecated 1.1 Use {@link ServletFileUpload#parseRequest(HttpServletRequest)} instead. */ @Deprecated public List parseRequest(HttpServletRequest req) throws FileUploadException { return parseRequest(new ServletRequestContext(req)); } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param ctx The context for the request to be parsed. * * @return An iterator to instances of FileItemStream * parsed from the request, in the order that they were * transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * @throws IOException An I/O error occurred. This may be a network * error while communicating with the client or a problem while * storing the uploaded content. */ public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { try { return new FileItemIteratorImpl(ctx); } catch (FileUploadIOException e) { // unwrap encapsulated SizeException throw (FileUploadException) e.getCause(); } } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param ctx The context for the request to be parsed. * * @return A list of FileItem instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. */ public List parseRequest(RequestContext ctx) throws FileUploadException { List items = new ArrayList(); boolean successful = false; try { FileItemIterator iter = getItemIterator(ctx); FileItemFactory fac = getFileItemFactory(); if (fac == null) { throw new NullPointerException("No FileItemFactory has been set."); } while (iter.hasNext()) { final FileItemStream item = iter.next(); // Don't use getName() here to prevent an InvalidFileNameException. final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); items.add(fileItem); try { Streams.copy(item.openStream(), fileItem.getOutputStream(), true); } catch (FileUploadIOException e) { throw (FileUploadException) e.getCause(); } catch (IOException e) { throw new IOFileUploadException(format("Processing of %s request failed. %s", MULTIPART_FORM_DATA, e.getMessage()), e); } final FileItemHeaders fih = item.getHeaders(); fileItem.setHeaders(fih); } successful = true; return items; } catch (FileUploadIOException e) { throw (FileUploadException) e.getCause(); } catch (IOException e) { throw new FileUploadException(e.getMessage(), e); } finally { if (!successful) { for (FileItem fileItem : items) { try { fileItem.delete(); } catch (Throwable e) { // ignore it } } } } } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param ctx The context for the request to be parsed. * * @return A map of FileItem instances parsed from the request. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * * @since 1.3 */ public Map> parseParameterMap(RequestContext ctx) throws FileUploadException { final List items = parseRequest(ctx); final Map> itemsMap = new HashMap>(items.size()); for (FileItem fileItem : items) { String fieldName = fileItem.getFieldName(); List mappedItems = itemsMap.get(fieldName); if (mappedItems == null) { mappedItems = new ArrayList(); itemsMap.put(fieldName, mappedItems); } mappedItems.add(fileItem); } return itemsMap; } // ------------------------------------------------------ Protected methods /** * Retrieves the boundary from the Content-type header. * * @param contentType The value of the content type header from which to * extract the boundary value. * * @return The boundary, as a byte array. */ protected byte[] getBoundary(String contentType) { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input Map params = parser.parse(contentType, new char[] {';', ','}); String boundaryStr = params.get("boundary"); if (boundaryStr == null) { return null; } byte[] boundary; try { boundary = boundaryStr.getBytes("ISO-8859-1"); } catch (UnsupportedEncodingException e) { boundary = boundaryStr.getBytes(); // Intentionally falls back to default charset } return boundary; } /** * Retrieves the file name from the Content-disposition * header. * * @param headers A Map containing the HTTP request headers. * * @return The file name for the current encapsulation. * @deprecated 1.2.1 Use {@link #getFileName(FileItemHeaders)}. */ @Deprecated protected String getFileName(Map headers) { return getFileName(getHeader(headers, CONTENT_DISPOSITION)); } /** * Retrieves the file name from the Content-disposition * header. * * @param headers The HTTP headers object. * * @return The file name for the current encapsulation. */ protected String getFileName(FileItemHeaders headers) { return getFileName(headers.getHeader(CONTENT_DISPOSITION)); } /** * Returns the given content-disposition headers file name. * @param pContentDisposition The content-disposition headers value. * @return The file name */ private String getFileName(String pContentDisposition) { String fileName = null; if (pContentDisposition != null) { String cdl = pContentDisposition.toLowerCase(Locale.ENGLISH); if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input Map params = parser.parse(pContentDisposition, ';'); if (params.containsKey("filename")) { fileName = params.get("filename"); if (fileName != null) { fileName = fileName.trim(); } else { // Even if there is no value, the parameter is present, // so we return an empty file name rather than no file // name. fileName = ""; } } } } return fileName; } /** * Retrieves the field name from the Content-disposition * header. * * @param headers A Map containing the HTTP request headers. * * @return The field name for the current encapsulation. */ protected String getFieldName(FileItemHeaders headers) { return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); } /** * Returns the field name, which is given by the content-disposition * header. * @param pContentDisposition The content-dispositions header value. * @return The field jake */ private String getFieldName(String pContentDisposition) { String fieldName = null; if (pContentDisposition != null && pContentDisposition.toLowerCase(Locale.ENGLISH).startsWith(FORM_DATA)) { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); // Parameter parser can handle null input Map params = parser.parse(pContentDisposition, ';'); fieldName = params.get("name"); if (fieldName != null) { fieldName = fieldName.trim(); } } return fieldName; } /** * Retrieves the field name from the Content-disposition * header. * * @param headers A Map containing the HTTP request headers. * * @return The field name for the current encapsulation. * @deprecated 1.2.1 Use {@link #getFieldName(FileItemHeaders)}. */ @Deprecated protected String getFieldName(Map headers) { return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); } /** * Creates a new {@link FileItem} instance. * * @param headers A Map containing the HTTP request * headers. * @param isFormField Whether or not this item is a form field, as * opposed to a file. * * @return A newly created FileItem instance. * * @throws FileUploadException if an error occurs. * @deprecated 1.2 This method is no longer used in favour of * internally created instances of {@link FileItem}. */ @Deprecated protected FileItem createItem(Map headers, boolean isFormField) throws FileUploadException { return getFileItemFactory().createItem(getFieldName(headers), getHeader(headers, CONTENT_TYPE), isFormField, getFileName(headers)); } /** *

Parses the header-part and returns as key/value * pairs. * *

If there are multiple headers of the same names, the name * will map to a comma-separated list containing the values. * * @param headerPart The header-part of the current * encapsulation. * * @return A Map containing the parsed HTTP request headers. */ protected FileItemHeaders getParsedHeaders(String headerPart) { final int len = headerPart.length(); FileItemHeadersImpl headers = newFileItemHeaders(); int start = 0; for (;;) { int end = parseEndOfLine(headerPart, start); if (start == end) { break; } StringBuilder header = new StringBuilder(headerPart.substring(start, end)); start = end + 2; while (start < len) { int nonWs = start; while (nonWs < len) { char c = headerPart.charAt(nonWs); if (c != ' ' && c != '\t') { break; } ++nonWs; } if (nonWs == start) { break; } // Continuation line found end = parseEndOfLine(headerPart, nonWs); header.append(" ").append(headerPart.substring(nonWs, end)); start = end + 2; } parseHeaderLine(headers, header.toString()); } return headers; } /** * Creates a new instance of {@link FileItemHeaders}. * @return The new instance. */ protected FileItemHeadersImpl newFileItemHeaders() { return new FileItemHeadersImpl(); } /** *

Parses the header-part and returns as key/value * pairs. * *

If there are multiple headers of the same names, the name * will map to a comma-separated list containing the values. * * @param headerPart The header-part of the current * encapsulation. * * @return A Map containing the parsed HTTP request headers. * @deprecated 1.2.1 Use {@link #getParsedHeaders(String)} */ @Deprecated protected Map parseHeaders(String headerPart) { FileItemHeaders headers = getParsedHeaders(headerPart); Map result = new HashMap(); for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { String headerName = iter.next(); Iterator iter2 = headers.getHeaders(headerName); StringBuilder headerValue = new StringBuilder(iter2.next()); while (iter2.hasNext()) { headerValue.append(",").append(iter2.next()); } result.put(headerName, headerValue.toString()); } return result; } /** * Skips bytes until the end of the current line. * @param headerPart The headers, which are being parsed. * @param end Index of the last byte, which has yet been * processed. * @return Index of the \r\n sequence, which indicates * end of line. */ private int parseEndOfLine(String headerPart, int end) { int index = end; for (;;) { int offset = headerPart.indexOf('\r', index); if (offset == -1 || offset + 1 >= headerPart.length()) { throw new IllegalStateException( "Expected headers to be terminated by an empty line."); } if (headerPart.charAt(offset + 1) == '\n') { return offset; } index = offset + 1; } } /** * Reads the next header line. * @param headers String with all headers. * @param header Map where to store the current header. */ private void parseHeaderLine(FileItemHeadersImpl headers, String header) { final int colonOffset = header.indexOf(':'); if (colonOffset == -1) { // This header line is malformed, skip it. return; } String headerName = header.substring(0, colonOffset).trim(); String headerValue = header.substring(header.indexOf(':') + 1).trim(); headers.addHeader(headerName, headerValue); } /** * Returns the header with the specified name from the supplied map. The * header lookup is case-insensitive. * * @param headers A Map containing the HTTP request headers. * @param name The name of the header to return. * * @return The value of specified header, or a comma-separated list if * there were multiple headers of that name. * @deprecated 1.2.1 Use {@link FileItemHeaders#getHeader(String)}. */ @Deprecated protected final String getHeader(Map headers, String name) { return headers.get(name.toLowerCase(Locale.ENGLISH)); } /** * The iterator, which is returned by * {@link FileUploadBase#getItemIterator(RequestContext)}. */ private class FileItemIteratorImpl implements FileItemIterator { /** * Default implementation of {@link FileItemStream}. */ class FileItemStreamImpl implements FileItemStream { /** * The file items content type. */ private final String contentType; /** * The file items field name. */ private final String fieldName; /** * The file items file name. */ private final String name; /** * Whether the file item is a form field. */ private final boolean formField; /** * The file items input stream. */ private final InputStream stream; /** * Whether the file item was already opened. */ private boolean opened; /** * The headers, if any. */ private FileItemHeaders headers; /** * Creates a new instance. * * @param pName The items file name, or null. * @param pFieldName The items field name. * @param pContentType The items content type, or null. * @param pFormField Whether the item is a form field. * @param pContentLength The items content length, if known, or -1 * @throws IOException Creating the file item failed. */ FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { name = pName; fieldName = pFieldName; contentType = pContentType; formField = pFormField; final ItemInputStream itemStream = multi.newInputStream(); InputStream istream = itemStream; if (fileSizeMax != -1) { if (pContentLength != -1 && pContentLength > fileSizeMax) { FileSizeLimitExceededException e = new FileSizeLimitExceededException( format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, Long.valueOf(fileSizeMax)), pContentLength, fileSizeMax); e.setFileName(pName); e.setFieldName(pFieldName); throw new FileUploadIOException(e); } istream = new LimitedInputStream(istream, fileSizeMax) { @Override protected void raiseError(long pSizeMax, long pCount) throws IOException { itemStream.close(true); FileSizeLimitExceededException e = new FileSizeLimitExceededException( format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, Long.valueOf(pSizeMax)), pCount, pSizeMax); e.setFieldName(fieldName); e.setFileName(name); throw new FileUploadIOException(e); } }; } stream = istream; } /** * Returns the items content type, or null. * * @return Content type, if known, or null. */ public String getContentType() { return contentType; } /** * Returns the items field name. * * @return Field name. */ public String getFieldName() { return fieldName; } /** * Returns the items file name. * * @return File name, if known, or null. * @throws InvalidFileNameException The file name contains a NUL character, * which might be an indicator of a security attack. If you intend to * use the file name anyways, catch the exception and use * InvalidFileNameException#getName(). */ public String getName() { return Streams.checkFileName(name); } /** * Returns, whether this is a form field. * * @return True, if the item is a form field, * otherwise false. */ public boolean isFormField() { return formField; } /** * Returns an input stream, which may be used to * read the items contents. * * @return Opened input stream. * @throws IOException An I/O error occurred. */ public InputStream openStream() throws IOException { if (opened) { throw new IllegalStateException( "The stream was already opened."); } if (((Closeable) stream).isClosed()) { throw new FileItemStream.ItemSkippedException(); } return stream; } /** * Closes the file item. * * @throws IOException An I/O error occurred. */ void close() throws IOException { stream.close(); } /** * Returns the file item headers. * * @return The items header object */ public FileItemHeaders getHeaders() { return headers; } /** * Sets the file item headers. * * @param pHeaders The items header object */ public void setHeaders(FileItemHeaders pHeaders) { headers = pHeaders; } } /** * The multi part stream to process. */ private final MultipartStream multi; /** * The notifier, which used for triggering the * {@link ProgressListener}. */ private final MultipartStream.ProgressNotifier notifier; /** * The boundary, which separates the various parts. */ private final byte[] boundary; /** * The item, which we currently process. */ private FileItemStreamImpl currentItem; /** * The current items field name. */ private String currentFieldName; /** * Whether we are currently skipping the preamble. */ private boolean skipPreamble; /** * Whether the current item may still be read. */ private boolean itemValid; /** * Whether we have seen the end of the file. */ private boolean eof; /** * Creates a new instance. * * @param ctx The request context. * @throws FileUploadException An error occurred while * parsing the request. * @throws IOException An I/O error occurred. */ FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { if (ctx == null) { throw new NullPointerException("ctx parameter"); } String contentType = ctx.getContentType(); if ((null == contentType) || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) { throw new InvalidContentTypeException( format("the request doesn't contain a %s or %s stream, content type header is %s", MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); } InputStream input = ctx.getInputStream(); @SuppressWarnings("deprecation") // still has to be backward compatible final int contentLengthInt = ctx.getContentLength(); final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass()) // Inline conditional is OK here CHECKSTYLE:OFF ? ((UploadContext) ctx).contentLength() : contentLengthInt; // CHECKSTYLE:ON if (sizeMax >= 0) { if (requestSize != -1 && requestSize > sizeMax) { throw new SizeLimitExceededException( format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", Long.valueOf(requestSize), Long.valueOf(sizeMax)), requestSize, sizeMax); } input = new LimitedInputStream(input, sizeMax) { @Override protected void raiseError(long pSizeMax, long pCount) throws IOException { FileUploadException ex = new SizeLimitExceededException( format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", Long.valueOf(pCount), Long.valueOf(pSizeMax)), pCount, pSizeMax); throw new FileUploadIOException(ex); } }; } String charEncoding = headerEncoding; if (charEncoding == null) { charEncoding = ctx.getCharacterEncoding(); } boundary = getBoundary(contentType); if (boundary == null) { throw new FileUploadException("the request was rejected because no multipart boundary was found"); } notifier = new MultipartStream.ProgressNotifier(listener, requestSize); try { multi = new MultipartStream(input, boundary, notifier); } catch (IllegalArgumentException iae) { throw new InvalidContentTypeException( format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae); } multi.setHeaderEncoding(charEncoding); skipPreamble = true; findNextItem(); } /** * Called for finding the next item, if any. * * @return True, if an next item was found, otherwise false. * @throws IOException An I/O error occurred. */ private boolean findNextItem() throws IOException { if (eof) { return false; } if (currentItem != null) { currentItem.close(); currentItem = null; } for (;;) { boolean nextPart; if (skipPreamble) { nextPart = multi.skipPreamble(); } else { nextPart = multi.readBoundary(); } if (!nextPart) { if (currentFieldName == null) { // Outer multipart terminated -> No more data eof = true; return false; } // Inner multipart terminated -> Return to parsing the outer multi.setBoundary(boundary); currentFieldName = null; continue; } FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); if (currentFieldName == null) { // We're parsing the outer multipart String fieldName = getFieldName(headers); if (fieldName != null) { String subContentType = headers.getHeader(CONTENT_TYPE); if (subContentType != null && subContentType.toLowerCase(Locale.ENGLISH) .startsWith(MULTIPART_MIXED)) { currentFieldName = fieldName; // Multiple files associated with this field name byte[] subBoundary = getBoundary(subContentType); multi.setBoundary(subBoundary); skipPreamble = true; continue; } String fileName = getFileName(headers); currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); currentItem.setHeaders(headers); notifier.noteItem(); itemValid = true; return true; } } else { String fileName = getFileName(headers); if (fileName != null) { currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); currentItem.setHeaders(headers); notifier.noteItem(); itemValid = true; return true; } } multi.discardBodyData(); } } private long getContentLength(FileItemHeaders pHeaders) { try { return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); } catch (Exception e) { return -1; } } /** * Returns, whether another instance of {@link FileItemStream} * is available. * * @throws FileUploadException Parsing or processing the * file item failed. * @throws IOException Reading the file item failed. * @return True, if one or more additional file items * are available, otherwise false. */ public boolean hasNext() throws FileUploadException, IOException { if (eof) { return false; } if (itemValid) { return true; } try { return findNextItem(); } catch (FileUploadIOException e) { // unwrap encapsulated SizeException throw (FileUploadException) e.getCause(); } } /** * Returns the next available {@link FileItemStream}. * * @throws java.util.NoSuchElementException No more items are * available. Use {@link #hasNext()} to prevent this exception. * @throws FileUploadException Parsing or processing the * file item failed. * @throws IOException Reading the file item failed. * @return FileItemStream instance, which provides * access to the next file item. */ public FileItemStream next() throws FileUploadException, IOException { if (eof || (!itemValid && !hasNext())) { throw new NoSuchElementException(); } itemValid = false; return currentItem; } } /** * This exception is thrown for hiding an inner * {@link FileUploadException} in an {@link IOException}. */ public static class FileUploadIOException extends IOException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = -7047616958165584154L; /** * The exceptions cause; we overwrite the parent * classes field, which is available since Java * 1.4 only. */ private final FileUploadException cause; /** * Creates a FileUploadIOException with the * given cause. * * @param pCause The exceptions cause, if any, or null. */ public FileUploadIOException(FileUploadException pCause) { // We're not doing super(pCause) cause of 1.3 compatibility. cause = pCause; } /** * Returns the exceptions cause. * * @return The exceptions cause, if any, or null. */ @Override public Throwable getCause() { return cause; } } /** * Thrown to indicate that the request is not a multipart request. */ public static class InvalidContentTypeException extends FileUploadException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = -9073026332015646668L; /** * Constructs a InvalidContentTypeException with no * detail message. */ public InvalidContentTypeException() { super(); } /** * Constructs an InvalidContentTypeException with * the specified detail message. * * @param message The detail message. */ public InvalidContentTypeException(String message) { super(message); } /** * Constructs an InvalidContentTypeException with * the specified detail message and cause. * * @param msg The detail message. * @param cause the original cause * * @since 1.3.1 */ public InvalidContentTypeException(String msg, Throwable cause) { super(msg, cause); } } /** * Thrown to indicate an IOException. */ public static class IOFileUploadException extends FileUploadException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = 1749796615868477269L; /** * The exceptions cause; we overwrite the parent * classes field, which is available since Java * 1.4 only. */ private final IOException cause; /** * Creates a new instance with the given cause. * * @param pMsg The detail message. * @param pException The exceptions cause. */ public IOFileUploadException(String pMsg, IOException pException) { super(pMsg); cause = pException; } /** * Returns the exceptions cause. * * @return The exceptions cause, if any, or null. */ @Override public Throwable getCause() { return cause; } } /** * This exception is thrown, if a requests permitted size * is exceeded. */ protected abstract static class SizeException extends FileUploadException { /** * Serial version UID, being used, if serialized. */ private static final long serialVersionUID = -8776225574705254126L; /** * The actual size of the request. */ private final long actual; /** * The maximum permitted size of the request. */ private final long permitted; /** * Creates a new instance. * * @param message The detail message. * @param actual The actual number of bytes in the request. * @param permitted The requests size limit, in bytes. */ protected SizeException(String message, long actual, long permitted) { super(message); this.actual = actual; this.permitted = permitted; } /** * Retrieves the actual size of the request. * * @return The actual size of the request. * @since 1.3 */ public long getActualSize() { return actual; } /** * Retrieves the permitted size of the request. * * @return The permitted size of the request. * @since 1.3 */ public long getPermittedSize() { return permitted; } } /** * Thrown to indicate that the request size is not specified. In other * words, it is thrown, if the content-length header is missing or * contains the value -1. * * @deprecated 1.2 As of commons-fileupload 1.2, the presence of a * content-length header is no longer required. */ @Deprecated public static class UnknownSizeException extends FileUploadException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = 7062279004812015273L; /** * Constructs a UnknownSizeException with no * detail message. */ public UnknownSizeException() { super(); } /** * Constructs an UnknownSizeException with * the specified detail message. * * @param message The detail message. */ public UnknownSizeException(String message) { super(message); } } /** * Thrown to indicate that the request size exceeds the configured maximum. */ public static class SizeLimitExceededException extends SizeException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = -2474893167098052828L; /** * @deprecated 1.2 Replaced by * {@link #SizeLimitExceededException(String, long, long)} */ @Deprecated public SizeLimitExceededException() { this(null, 0, 0); } /** * @deprecated 1.2 Replaced by * {@link #SizeLimitExceededException(String, long, long)} * @param message The exceptions detail message. */ @Deprecated public SizeLimitExceededException(String message) { this(message, 0, 0); } /** * Constructs a SizeExceededException with * the specified detail message, and actual and permitted sizes. * * @param message The detail message. * @param actual The actual request size. * @param permitted The maximum permitted request size. */ public SizeLimitExceededException(String message, long actual, long permitted) { super(message, actual, permitted); } } /** * Thrown to indicate that A files size exceeds the configured maximum. */ public static class FileSizeLimitExceededException extends SizeException { /** * The exceptions UID, for serializing an instance. */ private static final long serialVersionUID = 8150776562029630058L; /** * File name of the item, which caused the exception. */ private String fileName; /** * Field name of the item, which caused the exception. */ private String fieldName; /** * Constructs a SizeExceededException with * the specified detail message, and actual and permitted sizes. * * @param message The detail message. * @param actual The actual request size. * @param permitted The maximum permitted request size. */ public FileSizeLimitExceededException(String message, long actual, long permitted) { super(message, actual, permitted); } /** * Returns the file name of the item, which caused the * exception. * * @return File name, if known, or null. */ public String getFileName() { return fileName; } /** * Sets the file name of the item, which caused the * exception. * * @param pFileName the file name of the item, which caused the exception. */ public void setFileName(String pFileName) { fileName = pFileName; } /** * Returns the field name of the item, which caused the * exception. * * @return Field name, if known, or null. */ public String getFieldName() { return fieldName; } /** * Sets the field name of the item, which caused the * exception. * * @param pFieldName the field name of the item, * which caused the exception. */ public void setFieldName(String pFieldName) { fieldName = pFieldName; } } /** * Returns the progress listener. * * @return The progress listener, if any, or null. */ public ProgressListener getProgressListener() { return listener; } /** * Sets the progress listener. * * @param pListener The progress listener, if any. Defaults to null. */ public void setProgressListener(ProgressListener pListener) { listener = pListener; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/FileUploadException.java100644 0 0 6217 12274737401 30253 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.PrintStream; import java.io.PrintWriter; /** * Exception for errors encountered while processing the request. * * @version $Id: FileUploadException.java 1454690 2013-03-09 12:08:48Z simonetripodi $ */ public class FileUploadException extends Exception { /** * Serial version UID, being used, if the exception * is serialized. */ private static final long serialVersionUID = 8881893724388807504L; /** * The exceptions cause. We overwrite the cause of * the super class, which isn't available in Java 1.3. */ private final Throwable cause; /** * Constructs a new FileUploadException without message. */ public FileUploadException() { this(null, null); } /** * Constructs a new FileUploadException with specified detail * message. * * @param msg the error message. */ public FileUploadException(final String msg) { this(msg, null); } /** * Creates a new FileUploadException with the given * detail message and cause. * * @param msg The exceptions detail message. * @param cause The exceptions cause. */ public FileUploadException(String msg, Throwable cause) { super(msg); this.cause = cause; } /** * Prints this throwable and its backtrace to the specified print stream. * * @param stream PrintStream to use for output */ @Override public void printStackTrace(PrintStream stream) { super.printStackTrace(stream); if (cause != null) { stream.println("Caused by:"); cause.printStackTrace(stream); } } /** * Prints this throwable and its backtrace to the specified * print writer. * * @param writer PrintWriter to use for output */ @Override public void printStackTrace(PrintWriter writer) { super.printStackTrace(writer); if (cause != null) { writer.println("Caused by:"); cause.printStackTrace(writer); } } /** * {@inheritDoc} */ @Override public Throwable getCause() { return cause; } } ././@LongLink100644 0 0 147 12274740161 10261 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/InvalidFileNameException.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/InvalidFileNameException.ja100644 0 0 4345 12274737402 30670 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** * This exception is thrown in case of an invalid file name. * A file name is invalid, if it contains a NUL character. * Attackers might use this to circumvent security checks: * For example, a malicious user might upload a file with the name * "foo.exe\0.png". This file name might pass security checks (i.e. * checks for the extension ".png"), while, depending on the underlying * C library, it might create a file named "foo.exe", as the NUL * character is the string terminator in C. * * @version $Id: InvalidFileNameException.java 1454691 2013-03-09 12:15:54Z simonetripodi $ */ public class InvalidFileNameException extends RuntimeException { /** * Serial version UID, being used, if the exception * is serialized. */ private static final long serialVersionUID = 7922042602454350470L; /** * The file name causing the exception. */ private final String name; /** * Creates a new instance. * * @param pName The file name causing the exception. * @param pMessage A human readable error message. */ public InvalidFileNameException(String pName, String pMessage) { super(pMessage); name = pName; } /** * Returns the invalid file name. * * @return the invalid file name. */ public String getName() { return name; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/MultipartStream.java100644 0 0 102566 12274737401 27551 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static java.lang.String.format; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import org.apache.commons.fileupload.FileUploadBase.FileUploadIOException; import org.apache.commons.fileupload.util.Closeable; import org.apache.commons.fileupload.util.Streams; /** *

Low level API for processing file uploads. * *

This class can be used to process data streams conforming to MIME * 'multipart' format as defined in * RFC 1867. Arbitrarily * large amounts of data in the stream can be processed under constant * memory usage. * *

The format of the stream is defined in the following way:
* * * multipart-body := preamble 1*encapsulation close-delimiter epilogue
* encapsulation := delimiter body CRLF
* delimiter := "--" boundary CRLF
* close-delimiter := "--" boundary "--"
* preamble := <ignore>
* epilogue := <ignore>
* body := header-part CRLF body-part
* header-part := 1*header CRLF
* header := header-name ":" header-value
* header-name := <printable ascii characters except ":">
* header-value := <any ascii characters except CR & LF>
* body-data := <arbitrary data>
*
* *

Note that body-data can contain another mulipart entity. There * is limited support for single pass processing of such nested * streams. The nested stream is required to have a * boundary token of the same length as the parent stream (see {@link * #setBoundary(byte[])}). * *

Here is an example of usage of this class.
* *

 *   try {
 *     MultipartStream multipartStream = new MultipartStream(input, boundary);
 *     boolean nextPart = multipartStream.skipPreamble();
 *     OutputStream output;
 *     while(nextPart) {
 *       String header = multipartStream.readHeaders();
 *       // process headers
 *       // create some output stream
 *       multipartStream.readBodyData(output);
 *       nextPart = multipartStream.readBoundary();
 *     }
 *   } catch(MultipartStream.MalformedStreamException e) {
 *     // the stream failed to follow required syntax
 *   } catch(IOException e) {
 *     // a read or write error occurred
 *   }
 * 
* * @version $Id: MultipartStream.java 1565249 2014-02-06 13:45:33Z ggregory $ */ public class MultipartStream { /** * Internal class, which is used to invoke the * {@link ProgressListener}. */ public static class ProgressNotifier { /** * The listener to invoke. */ private final ProgressListener listener; /** * Number of expected bytes, if known, or -1. */ private final long contentLength; /** * Number of bytes, which have been read so far. */ private long bytesRead; /** * Number of items, which have been read so far. */ private int items; /** * Creates a new instance with the given listener * and content length. * * @param pListener The listener to invoke. * @param pContentLength The expected content length. */ ProgressNotifier(ProgressListener pListener, long pContentLength) { listener = pListener; contentLength = pContentLength; } /** * Called to indicate that bytes have been read. * * @param pBytes Number of bytes, which have been read. */ void noteBytesRead(int pBytes) { /* Indicates, that the given number of bytes have been read from * the input stream. */ bytesRead += pBytes; notifyListener(); } /** * Called to indicate, that a new file item has been detected. */ void noteItem() { ++items; notifyListener(); } /** * Called for notifying the listener. */ private void notifyListener() { if (listener != null) { listener.update(bytesRead, contentLength, items); } } } // ----------------------------------------------------- Manifest constants /** * The Carriage Return ASCII character value. */ public static final byte CR = 0x0D; /** * The Line Feed ASCII character value. */ public static final byte LF = 0x0A; /** * The dash (-) ASCII character value. */ public static final byte DASH = 0x2D; /** * The maximum length of header-part that will be * processed (10 kilobytes = 10240 bytes.). */ public static final int HEADER_PART_SIZE_MAX = 10240; /** * The default length of the buffer used for processing a request. */ protected static final int DEFAULT_BUFSIZE = 4096; /** * A byte sequence that marks the end of header-part * (CRLFCRLF). */ protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF}; /** * A byte sequence that that follows a delimiter that will be * followed by an encapsulation (CRLF). */ protected static final byte[] FIELD_SEPARATOR = {CR, LF}; /** * A byte sequence that that follows a delimiter of the last * encapsulation in the stream (--). */ protected static final byte[] STREAM_TERMINATOR = {DASH, DASH}; /** * A byte sequence that precedes a boundary (CRLF--). */ protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH}; // ----------------------------------------------------------- Data members /** * The input stream from which data is read. */ private final InputStream input; /** * The length of the boundary token plus the leading CRLF--. */ private int boundaryLength; /** * The amount of data, in bytes, that must be kept in the buffer in order * to detect delimiters reliably. */ private int keepRegion; /** * The byte sequence that partitions the stream. */ private byte[] boundary; /** * The length of the buffer used for processing the request. */ private final int bufSize; /** * The buffer used for processing the request. */ private final byte[] buffer; /** * The index of first valid character in the buffer. *
* 0 <= head < bufSize */ private int head; /** * The index of last valid character in the buffer + 1. *
* 0 <= tail <= bufSize */ private int tail; /** * The content encoding to use when reading headers. */ private String headerEncoding; /** * The progress notifier, if any, or null. */ private final ProgressNotifier notifier; // ----------------------------------------------------------- Constructors /** * Creates a new instance. * * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, * ProgressNotifier)} */ @Deprecated public MultipartStream() { this(null, null, null); } /** *

Constructs a MultipartStream with a custom size buffer * and no progress notifier. * *

Note that the buffer must be at least big enough to contain the * boundary string, plus 4 characters for CR/LF and double dash, plus at * least one byte of data. Too small a buffer size setting will degrade * performance. * * @param input The InputStream to serve as a data source. * @param boundary The token used for dividing the stream into * encapsulations. * @param bufSize The size of the buffer to be used, in bytes. * * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, * ProgressNotifier)}. */ @Deprecated public MultipartStream(InputStream input, byte[] boundary, int bufSize) { this(input, boundary, bufSize, null); } /** *

Constructs a MultipartStream with a custom size buffer. * *

Note that the buffer must be at least big enough to contain the * boundary string, plus 4 characters for CR/LF and double dash, plus at * least one byte of data. Too small a buffer size setting will degrade * performance. * * @param input The InputStream to serve as a data source. * @param boundary The token used for dividing the stream into * encapsulations. * @param bufSize The size of the buffer to be used, in bytes. * @param pNotifier The notifier, which is used for calling the * progress listener, if any. * * @throws IllegalArgumentException If the buffer size is too small * * @since 1.3.1 */ public MultipartStream(InputStream input, byte[] boundary, int bufSize, ProgressNotifier pNotifier) { if (boundary == null) { throw new IllegalArgumentException("boundary may not be null"); } this.input = input; this.bufSize = bufSize; this.buffer = new byte[bufSize]; this.notifier = pNotifier; // We prepend CR/LF to the boundary to chop trailing CR/LF from // body-data tokens. this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; if (bufSize < this.boundaryLength + 1) { throw new IllegalArgumentException( "The buffer size specified for the MultipartStream is too small"); } this.boundary = new byte[this.boundaryLength]; this.keepRegion = this.boundary.length; System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, BOUNDARY_PREFIX.length); System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length); head = 0; tail = 0; } /** *

Constructs a MultipartStream with a default size buffer. * * @param input The InputStream to serve as a data source. * @param boundary The token used for dividing the stream into * encapsulations. * @param pNotifier An object for calling the progress listener, if any. * * * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) */ MultipartStream(InputStream input, byte[] boundary, ProgressNotifier pNotifier) { this(input, boundary, DEFAULT_BUFSIZE, pNotifier); } /** *

Constructs a MultipartStream with a default size buffer. * * @param input The InputStream to serve as a data source. * @param boundary The token used for dividing the stream into * encapsulations. * * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, * ProgressNotifier)}. */ @Deprecated public MultipartStream(InputStream input, byte[] boundary) { this(input, boundary, DEFAULT_BUFSIZE, null); } // --------------------------------------------------------- Public methods /** * Retrieves the character encoding used when reading the headers of an * individual part. When not specified, or null, the platform * default encoding is used. * * @return The encoding used to read part headers. */ public String getHeaderEncoding() { return headerEncoding; } /** * Specifies the character encoding to be used when reading the headers of * individual parts. When not specified, or null, the platform * default encoding is used. * * @param encoding The encoding used to read part headers. */ public void setHeaderEncoding(String encoding) { headerEncoding = encoding; } /** * Reads a byte from the buffer, and refills it as * necessary. * * @return The next byte from the input stream. * * @throws IOException if there is no more data available. */ public byte readByte() throws IOException { // Buffer depleted ? if (head == tail) { head = 0; // Refill. tail = input.read(buffer, head, bufSize); if (tail == -1) { // No more data available. throw new IOException("No more data is available"); } if (notifier != null) { notifier.noteBytesRead(tail); } } return buffer[head++]; } /** * Skips a boundary token, and checks whether more * encapsulations are contained in the stream. * * @return true if there are more encapsulations in * this stream; false otherwise. * * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits * @throws MalformedStreamException if the stream ends unexpectedly or * fails to follow required syntax. */ public boolean readBoundary() throws FileUploadIOException, MalformedStreamException { byte[] marker = new byte[2]; boolean nextChunk = false; head += boundaryLength; try { marker[0] = readByte(); if (marker[0] == LF) { // Work around IE5 Mac bug with input type=image. // Because the boundary delimiter, not including the trailing // CRLF, must not appear within any file (RFC 2046, section // 5.1.1), we know the missing CR is due to a buggy browser // rather than a file containing something similar to a // boundary. return true; } marker[1] = readByte(); if (arrayequals(marker, STREAM_TERMINATOR, 2)) { nextChunk = false; } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { nextChunk = true; } else { throw new MalformedStreamException( "Unexpected characters follow a boundary"); } } catch (FileUploadIOException e) { // wraps a SizeException, re-throw as it will be unwrapped later throw e; } catch (IOException e) { throw new MalformedStreamException("Stream ended unexpectedly"); } return nextChunk; } /** *

Changes the boundary token used for partitioning the stream. * *

This method allows single pass processing of nested multipart * streams. * *

The boundary token of the nested stream is required * to be of the same length as the boundary token in parent stream. * *

Restoring the parent stream boundary token after processing of a * nested stream is left to the application. * * @param boundary The boundary to be used for parsing of the nested * stream. * * @throws IllegalBoundaryException if the boundary * has a different length than the one * being currently parsed. */ public void setBoundary(byte[] boundary) throws IllegalBoundaryException { if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { throw new IllegalBoundaryException( "The length of a boundary token can not be changed"); } System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length); } /** *

Reads the header-part of the current * encapsulation. * *

Headers are returned verbatim to the input stream, including the * trailing CRLF marker. Parsing is left to the * application. * *

TODO allow limiting maximum header size to * protect against abuse. * * @return The header-part of the current encapsulation. * * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits. * @throws MalformedStreamException if the stream ends unexpectedly. */ public String readHeaders() throws FileUploadIOException, MalformedStreamException { int i = 0; byte b; // to support multi-byte characters ByteArrayOutputStream baos = new ByteArrayOutputStream(); int size = 0; while (i < HEADER_SEPARATOR.length) { try { b = readByte(); } catch (FileUploadIOException e) { // wraps a SizeException, re-throw as it will be unwrapped later throw e; } catch (IOException e) { throw new MalformedStreamException("Stream ended unexpectedly"); } if (++size > HEADER_PART_SIZE_MAX) { throw new MalformedStreamException( format("Header section has more than %s bytes (maybe it is not properly terminated)", Integer.valueOf(HEADER_PART_SIZE_MAX))); } if (b == HEADER_SEPARATOR[i]) { i++; } else { i = 0; } baos.write(b); } String headers = null; if (headerEncoding != null) { try { headers = baos.toString(headerEncoding); } catch (UnsupportedEncodingException e) { // Fall back to platform default if specified encoding is not // supported. headers = baos.toString(); } } else { headers = baos.toString(); } return headers; } /** *

Reads body-data from the current * encapsulation and writes its contents into the * output Stream. * *

Arbitrary large amounts of data can be processed by this * method using a constant size buffer. (see {@link * #MultipartStream(InputStream,byte[],int, * MultipartStream.ProgressNotifier) constructor}). * * @param output The Stream to write data into. May * be null, in which case this method is equivalent * to {@link #discardBodyData()}. * * @return the amount of data written. * * @throws MalformedStreamException if the stream ends unexpectedly. * @throws IOException if an i/o error occurs. */ public int readBodyData(OutputStream output) throws MalformedStreamException, IOException { final InputStream istream = newInputStream(); return (int) Streams.copy(istream, output, false); } /** * Creates a new {@link ItemInputStream}. * @return A new instance of {@link ItemInputStream}. */ ItemInputStream newInputStream() { return new ItemInputStream(); } /** *

Reads body-data from the current * encapsulation and discards it. * *

Use this method to skip encapsulations you don't need or don't * understand. * * @return The amount of data discarded. * * @throws MalformedStreamException if the stream ends unexpectedly. * @throws IOException if an i/o error occurs. */ public int discardBodyData() throws MalformedStreamException, IOException { return readBodyData(null); } /** * Finds the beginning of the first encapsulation. * * @return true if an encapsulation was found in * the stream. * * @throws IOException if an i/o error occurs. */ public boolean skipPreamble() throws IOException { // First delimiter may be not preceeded with a CRLF. System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); boundaryLength = boundary.length - 2; try { // Discard all data up to the delimiter. discardBodyData(); // Read boundary - if succeeded, the stream contains an // encapsulation. return readBoundary(); } catch (MalformedStreamException e) { return false; } finally { // Restore delimiter. System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); boundaryLength = boundary.length; boundary[0] = CR; boundary[1] = LF; } } /** * Compares count first bytes in the arrays * a and b. * * @param a The first array to compare. * @param b The second array to compare. * @param count How many bytes should be compared. * * @return true if count first bytes in arrays * a and b are equal. */ public static boolean arrayequals(byte[] a, byte[] b, int count) { for (int i = 0; i < count; i++) { if (a[i] != b[i]) { return false; } } return true; } /** * Searches for a byte of specified value in the buffer, * starting at the specified position. * * @param value The value to find. * @param pos The starting position for searching. * * @return The position of byte found, counting from beginning of the * buffer, or -1 if not found. */ protected int findByte(byte value, int pos) { for (int i = pos; i < tail; i++) { if (buffer[i] == value) { return i; } } return -1; } /** * Searches for the boundary in the buffer * region delimited by head and tail. * * @return The position of the boundary found, counting from the * beginning of the buffer, or -1 if * not found. */ protected int findSeparator() { int first; int match = 0; int maxpos = tail - boundaryLength; for (first = head; first <= maxpos && match != boundaryLength; first++) { first = findByte(boundary[0], first); if (first == -1 || first > maxpos) { return -1; } for (match = 1; match < boundaryLength; match++) { if (buffer[first + match] != boundary[match]) { break; } } } if (match == boundaryLength) { return first - 1; } return -1; } /** * Thrown to indicate that the input stream fails to follow the * required syntax. */ public static class MalformedStreamException extends IOException { /** * The UID to use when serializing this instance. */ private static final long serialVersionUID = 6466926458059796677L; /** * Constructs a MalformedStreamException with no * detail message. */ public MalformedStreamException() { super(); } /** * Constructs an MalformedStreamException with * the specified detail message. * * @param message The detail message. */ public MalformedStreamException(String message) { super(message); } } /** * Thrown upon attempt of setting an invalid boundary token. */ public static class IllegalBoundaryException extends IOException { /** * The UID to use when serializing this instance. */ private static final long serialVersionUID = -161533165102632918L; /** * Constructs an IllegalBoundaryException with no * detail message. */ public IllegalBoundaryException() { super(); } /** * Constructs an IllegalBoundaryException with * the specified detail message. * * @param message The detail message. */ public IllegalBoundaryException(String message) { super(message); } } /** * An {@link InputStream} for reading an items contents. */ public class ItemInputStream extends InputStream implements Closeable { /** * The number of bytes, which have been read so far. */ private long total; /** * The number of bytes, which must be hold, because * they might be a part of the boundary. */ private int pad; /** * The current offset in the buffer. */ private int pos; /** * Whether the stream is already closed. */ private boolean closed; /** * Creates a new instance. */ ItemInputStream() { findSeparator(); } /** * Called for finding the separator. */ private void findSeparator() { pos = MultipartStream.this.findSeparator(); if (pos == -1) { if (tail - head > keepRegion) { pad = keepRegion; } else { pad = tail - head; } } } /** * Returns the number of bytes, which have been read * by the stream. * * @return Number of bytes, which have been read so far. */ public long getBytesRead() { return total; } /** * Returns the number of bytes, which are currently * available, without blocking. * * @throws IOException An I/O error occurs. * @return Number of bytes in the buffer. */ @Override public int available() throws IOException { if (pos == -1) { return tail - head - pad; } return pos - head; } /** * Offset when converting negative bytes to integers. */ private static final int BYTE_POSITIVE_OFFSET = 256; /** * Returns the next byte in the stream. * * @return The next byte in the stream, as a non-negative * integer, or -1 for EOF. * @throws IOException An I/O error occurred. */ @Override public int read() throws IOException { if (closed) { throw new FileItemStream.ItemSkippedException(); } if (available() == 0 && makeAvailable() == 0) { return -1; } ++total; int b = buffer[head++]; if (b >= 0) { return b; } return b + BYTE_POSITIVE_OFFSET; } /** * Reads bytes into the given buffer. * * @param b The destination buffer, where to write to. * @param off Offset of the first byte in the buffer. * @param len Maximum number of bytes to read. * @return Number of bytes, which have been actually read, * or -1 for EOF. * @throws IOException An I/O error occurred. */ @Override public int read(byte[] b, int off, int len) throws IOException { if (closed) { throw new FileItemStream.ItemSkippedException(); } if (len == 0) { return 0; } int res = available(); if (res == 0) { res = makeAvailable(); if (res == 0) { return -1; } } res = Math.min(res, len); System.arraycopy(buffer, head, b, off, res); head += res; total += res; return res; } /** * Closes the input stream. * * @throws IOException An I/O error occurred. */ @Override public void close() throws IOException { close(false); } /** * Closes the input stream. * * @param pCloseUnderlying Whether to close the underlying stream * (hard close) * @throws IOException An I/O error occurred. */ public void close(boolean pCloseUnderlying) throws IOException { if (closed) { return; } if (pCloseUnderlying) { closed = true; input.close(); } else { for (;;) { int av = available(); if (av == 0) { av = makeAvailable(); if (av == 0) { break; } } skip(av); } } closed = true; } /** * Skips the given number of bytes. * * @param bytes Number of bytes to skip. * @return The number of bytes, which have actually been * skipped. * @throws IOException An I/O error occurred. */ @Override public long skip(long bytes) throws IOException { if (closed) { throw new FileItemStream.ItemSkippedException(); } int av = available(); if (av == 0) { av = makeAvailable(); if (av == 0) { return 0; } } long res = Math.min(av, bytes); head += res; return res; } /** * Attempts to read more data. * * @return Number of available bytes * @throws IOException An I/O error occurred. */ private int makeAvailable() throws IOException { if (pos != -1) { return 0; } // Move the data to the beginning of the buffer. total += tail - head - pad; System.arraycopy(buffer, tail - pad, buffer, 0, pad); // Refill buffer with new data. head = 0; tail = pad; for (;;) { int bytesRead = input.read(buffer, tail, bufSize - tail); if (bytesRead == -1) { // The last pad amount is left in the buffer. // Boundary can't be in there so signal an error // condition. final String msg = "Stream ended unexpectedly"; throw new MalformedStreamException(msg); } if (notifier != null) { notifier.noteBytesRead(bytesRead); } tail += bytesRead; findSeparator(); int av = available(); if (av > 0 || pos != -1) { return av; } } } /** * Returns, whether the stream is closed. * * @return True, if the stream is closed, otherwise false. */ public boolean isClosed() { return closed; } } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/package-info.java100644 0 0 7471 12274737401 26677 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** *

* A component for handling HTML file uploads as specified by * RFC 1867. * This component provides support for uploads within both servlets (JSR 53) * and portlets (JSR 168). *

*

* While this package provides the generic functionality for file uploads, * these classes are not typically used directly. Instead, normal usage * involves one of the provided extensions of * {@link org.apache.commons.fileupload.FileUpload FileUpload} such as * {@link org.apache.commons.fileupload.servlet.ServletFileUpload ServletFileUpload} * or * {@link org.apache.commons.fileupload.portlet.PortletFileUpload PortletFileUpload}, * together with a factory for * {@link org.apache.commons.fileupload.FileItem FileItem} instances, * such as * {@link org.apache.commons.fileupload.disk.DiskFileItemFactory DiskFileItemFactory}. *

*

* The following is a brief example of typical usage in a servlet, storing * the uploaded files on disk. *

*
public void doPost(HttpServletRequest req, HttpServletResponse res) {
 *   DiskFileItemFactory factory = new DiskFileItemFactory();
 *   // maximum size that will be stored in memory
 *   factory.setSizeThreshold(4096);
 *   // the location for saving data that is larger than getSizeThreshold()
 *   factory.setRepository(new File("/tmp"));
 *
 *   ServletFileUpload upload = new ServletFileUpload(factory);
 *   // maximum size before a FileUploadException will be thrown
 *   upload.setSizeMax(1000000);
 *
 *   List fileItems = upload.parseRequest(req);
 *   // assume we know there are two files. The first file is a small
 *   // text file, the second is unknown and is written to a file on
 *   // the server
 *   Iterator i = fileItems.iterator();
 *   String comment = ((FileItem)i.next()).getString();
 *   FileItem fi = (FileItem)i.next();
 *   // filename on the client
 *   String fileName = fi.getName();
 *   // save comment and filename to database
 *   ...
 *   // write the file
 *   fi.write(new File("/www/uploads/", fileName));
 * }
 * 
*

* In the example above, the first file is loaded into memory as a * String. Before calling the getString method, * the data may have been in memory or on disk depending on its size. The * second file we assume it will be large and therefore never explicitly * load it into memory, though if it is less than 4096 bytes it will be * in memory before it is written to its final location. When writing to * the final location, if the data is larger than the threshold, an attempt * is made to rename the temporary file to the given location. If it cannot * be renamed, it is streamed to the new location. *

*

* Please see the FileUpload * User Guide * for further details and examples of how to use this package. *

*/ package org.apache.commons.fileupload; commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/ParameterParser.java100644 0 0 24771 12274737401 27472 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.commons.fileupload.util.mime.MimeUtility; /** * A simple parser intended to parse sequences of name/value pairs. * * Parameter values are expected to be enclosed in quotes if they * contain unsafe characters, such as '=' characters or separators. * Parameter values are optional and can be omitted. * *

* param1 = value; param2 = "anything goes; really"; param3 *

* * @version $Id: ParameterParser.java 1565253 2014-02-06 13:48:16Z ggregory $ */ public class ParameterParser { /** * String to be parsed. */ private char[] chars = null; /** * Current position in the string. */ private int pos = 0; /** * Maximum position in the string. */ private int len = 0; /** * Start of a token. */ private int i1 = 0; /** * End of a token. */ private int i2 = 0; /** * Whether names stored in the map should be converted to lower case. */ private boolean lowerCaseNames = false; /** * Default ParameterParser constructor. */ public ParameterParser() { super(); } /** * Are there any characters left to parse? * * @return true if there are unparsed characters, * false otherwise. */ private boolean hasChar() { return this.pos < this.len; } /** * A helper method to process the parsed token. This method removes * leading and trailing blanks as well as enclosing quotation marks, * when necessary. * * @param quoted true if quotation marks are expected, * false otherwise. * @return the token */ private String getToken(boolean quoted) { // Trim leading white spaces while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { i1++; } // Trim trailing white spaces while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { i2--; } // Strip away quotation marks if necessary if (quoted && ((i2 - i1) >= 2) && (chars[i1] == '"') && (chars[i2 - 1] == '"')) { i1++; i2--; } String result = null; if (i2 > i1) { result = new String(chars, i1, i2 - i1); } return result; } /** * Tests if the given character is present in the array of characters. * * @param ch the character to test for presense in the array of characters * @param charray the array of characters to test against * * @return true if the character is present in the array of * characters, false otherwise. */ private boolean isOneOf(char ch, final char[] charray) { boolean result = false; for (char element : charray) { if (ch == element) { result = true; break; } } return result; } /** * Parses out a token until any of the given terminators * is encountered. * * @param terminators the array of terminating characters. Any of these * characters when encountered signify the end of the token * * @return the token */ private String parseToken(final char[] terminators) { char ch; i1 = pos; i2 = pos; while (hasChar()) { ch = chars[pos]; if (isOneOf(ch, terminators)) { break; } i2++; pos++; } return getToken(false); } /** * Parses out a token until any of the given terminators * is encountered outside the quotation marks. * * @param terminators the array of terminating characters. Any of these * characters when encountered outside the quotation marks signify the end * of the token * * @return the token */ private String parseQuotedToken(final char[] terminators) { char ch; i1 = pos; i2 = pos; boolean quoted = false; boolean charEscaped = false; while (hasChar()) { ch = chars[pos]; if (!quoted && isOneOf(ch, terminators)) { break; } if (!charEscaped && ch == '"') { quoted = !quoted; } charEscaped = (!charEscaped && ch == '\\'); i2++; pos++; } return getToken(true); } /** * Returns true if parameter names are to be converted to lower * case when name/value pairs are parsed. * * @return true if parameter names are to be * converted to lower case when name/value pairs are parsed. * Otherwise returns false */ public boolean isLowerCaseNames() { return this.lowerCaseNames; } /** * Sets the flag if parameter names are to be converted to lower case when * name/value pairs are parsed. * * @param b true if parameter names are to be * converted to lower case when name/value pairs are parsed. * false otherwise. */ public void setLowerCaseNames(boolean b) { this.lowerCaseNames = b; } /** * Extracts a map of name/value pairs from the given string. Names are * expected to be unique. Multiple separators may be specified and * the earliest found in the input string is used. * * @param str the string that contains a sequence of name/value pairs * @param separators the name/value pairs separators * * @return a map of name/value pairs */ public Map parse(final String str, char[] separators) { if (separators == null || separators.length == 0) { return new HashMap(); } char separator = separators[0]; if (str != null) { int idx = str.length(); for (char separator2 : separators) { int tmp = str.indexOf(separator2); if (tmp != -1 && tmp < idx) { idx = tmp; separator = separator2; } } } return parse(str, separator); } /** * Extracts a map of name/value pairs from the given string. Names are * expected to be unique. * * @param str the string that contains a sequence of name/value pairs * @param separator the name/value pairs separator * * @return a map of name/value pairs */ public Map parse(final String str, char separator) { if (str == null) { return new HashMap(); } return parse(str.toCharArray(), separator); } /** * Extracts a map of name/value pairs from the given array of * characters. Names are expected to be unique. * * @param charArray the array of characters that contains a sequence of * name/value pairs * @param separator the name/value pairs separator * * @return a map of name/value pairs */ public Map parse(final char[] charArray, char separator) { if (charArray == null) { return new HashMap(); } return parse(charArray, 0, charArray.length, separator); } /** * Extracts a map of name/value pairs from the given array of * characters. Names are expected to be unique. * * @param charArray the array of characters that contains a sequence of * name/value pairs * @param offset - the initial offset. * @param length - the length. * @param separator the name/value pairs separator * * @return a map of name/value pairs */ public Map parse( final char[] charArray, int offset, int length, char separator) { if (charArray == null) { return new HashMap(); } HashMap params = new HashMap(); this.chars = charArray; this.pos = offset; this.len = length; String paramName = null; String paramValue = null; while (hasChar()) { paramName = parseToken(new char[] { '=', separator }); paramValue = null; if (hasChar() && (charArray[pos] == '=')) { pos++; // skip '=' paramValue = parseQuotedToken(new char[] { separator }); if (paramValue != null) { try { paramValue = MimeUtility.decodeText(paramValue); } catch (UnsupportedEncodingException e) { // let's keep the original value in this case } } } if (hasChar() && (charArray[pos] == separator)) { pos++; // skip separator } if ((paramName != null) && (paramName.length() > 0)) { if (this.lowerCaseNames) { paramName = paramName.toLowerCase(Locale.ENGLISH); } params.put(paramName, paramValue); } } return params; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/package-info.java100644 0 0 3757 12274737402 30374 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** *

* An implementation of * {@link org.apache.commons.fileupload.FileUpload FileUpload} * for use in portlets conforming to JSR 168. This implementation requires * only access to the portlet's current ActionRequest instance, * and a suitable * {@link org.apache.commons.fileupload.FileItemFactory FileItemFactory} * implementation, such as * {@link org.apache.commons.fileupload.disk.DiskFileItemFactory DiskFileItemFactory}. *

*

* The following code fragment demonstrates typical usage. *

*
 *       DiskFileItemFactory factory = new DiskFileItemFactory();
 *        // Configure the factory here, if desired.
 *        PortletFileUpload upload = new PortletFileUpload(factory);
 *        // Configure the uploader here, if desired.
 *        List fileItems = upload.parseRequest(request);
 * 
*

* Please see the FileUpload * User Guide * for further details and examples of how to use this package. *

*/ package org.apache.commons.fileupload.portlet; ././@LongLink100644 0 0 150 12274740161 10253 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/PortletFileUpload.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/PortletFileUpload.j100644 0 0 13525 12274737402 30770 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.portlet; import java.io.IOException; import java.util.List; import java.util.Map; import javax.portlet.ActionRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileUpload; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; /** *

High level API for processing file uploads.

* *

This class handles multiple files per single HTML widget, sent using * multipart/mixed encoding type, as specified by * RFC 1867. Use * {@link org.apache.commons.fileupload.servlet.ServletFileUpload * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list * of {@link org.apache.commons.fileupload.FileItem FileItems} associated * with a given HTML widget.

* *

How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.

* * @since FileUpload 1.1 * * @version $Id: PortletFileUpload.java 1455537 2013-03-12 14:06:11Z simonetripodi $ */ public class PortletFileUpload extends FileUpload { // ---------------------------------------------------------- Class methods /** * Utility method that determines whether the request contains multipart * content. * * @param request The portlet request to be evaluated. Must be non-null. * * @return true if the request is multipart; * false otherwise. */ public static final boolean isMultipartContent(ActionRequest request) { return FileUploadBase.isMultipartContent( new PortletRequestContext(request)); } // ----------------------------------------------------------- Constructors /** * Constructs an uninitialised instance of this class. A factory must be * configured, using setFileItemFactory(), before attempting * to parse requests. * * @see FileUpload#FileUpload(FileItemFactory) */ public PortletFileUpload() { super(); } /** * Constructs an instance of this class which uses the supplied factory to * create FileItem instances. * * @see FileUpload#FileUpload() * @param fileItemFactory The factory to use for creating file items. */ public PortletFileUpload(FileItemFactory fileItemFactory) { super(fileItemFactory); } // --------------------------------------------------------- Public methods /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The portlet request to be parsed. * * @return A list of FileItem instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. */ public List parseRequest(ActionRequest request) throws FileUploadException { return parseRequest(new PortletRequestContext(request)); } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The portlet request to be parsed. * * @return A map of FileItem instances parsed from the request. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * * @since 1.3 */ public Map> parseParameterMap(ActionRequest request) throws FileUploadException { return parseParameterMap(new PortletRequestContext(request)); } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The portlet request to be parsed. * * @return An iterator to instances of FileItemStream * parsed from the request, in the order that they were * transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * @throws IOException An I/O error occurred. This may be a network * error while communicating with the client or a problem while * storing the uploaded content. */ public FileItemIterator getItemIterator(ActionRequest request) throws FileUploadException, IOException { return super.getItemIterator(new PortletRequestContext(request)); } } ././@LongLink100644 0 0 154 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/PortletRequestContext.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/portlet/PortletRequestConte100644 0 0 7451 12274737402 31116 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.portlet; import static java.lang.String.format; import java.io.IOException; import java.io.InputStream; import javax.portlet.ActionRequest; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.UploadContext; /** *

Provides access to the request information needed for a request made to * a portlet.

* * @since FileUpload 1.1 * * @version $Id: PortletRequestContext.java 1564788 2014-02-05 14:36:41Z markt $ */ public class PortletRequestContext implements UploadContext { // ----------------------------------------------------- Instance Variables /** * The request for which the context is being provided. */ private final ActionRequest request; // ----------------------------------------------------------- Constructors /** * Construct a context for this request. * * @param request The request to which this context applies. */ public PortletRequestContext(ActionRequest request) { this.request = request; } // --------------------------------------------------------- Public Methods /** * Retrieve the character encoding for the request. * * @return The character encoding for the request. */ public String getCharacterEncoding() { return request.getCharacterEncoding(); } /** * Retrieve the content type of the request. * * @return The content type of the request. */ public String getContentType() { return request.getContentType(); } /** * Retrieve the content length of the request. * * @return The content length of the request. * @deprecated 1.3 Use {@link #contentLength()} instead */ @Deprecated public int getContentLength() { return request.getContentLength(); } /** * Retrieve the content length of the request. * * @return The content length of the request. * @since 1.3 */ public long contentLength() { long size; try { size = Long.parseLong(request.getProperty(FileUploadBase.CONTENT_LENGTH)); } catch (NumberFormatException e) { size = request.getContentLength(); } return size; } /** * Retrieve the input stream for the request. * * @return The input stream for the request. * * @throws IOException if a problem occurs. */ public InputStream getInputStream() throws IOException { return request.getPortletInputStream(); } /** * Returns a string representation of this object. * * @return a string representation of this object. */ @Override public String toString() { return format("ContentLength=%s, ContentType=%s", Long.valueOf(this.contentLength()), this.getContentType()); } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/ProgressListener.java100644 0 0 3111 12274737402 27651 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** * The {@link ProgressListener} may be used to display a progress bar * or do stuff like that. * * @version $Id: ProgressListener.java 1454691 2013-03-09 12:15:54Z simonetripodi $ */ public interface ProgressListener { /** * Updates the listeners status information. * * @param pBytesRead The total number of bytes, which have been read * so far. * @param pContentLength The total number of bytes, which are being * read. May be -1, if this number is unknown. * @param pItems The number of the field, which is currently being * read. (0 = no item so far, 1 = first item is being read, ...) */ void update(long pBytesRead, long pContentLength, int pItems); } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/RequestContext.java100644 0 0 4121 12274737401 27335 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.InputStream; import java.io.IOException; /** *

Abstracts access to the request information needed for file uploads. This * interface should be implemented for each type of request that may be * handled by FileUpload, such as servlets and portlets.

* * @since FileUpload 1.1 * * @version $Id: RequestContext.java 1455861 2013-03-13 10:12:09Z simonetripodi $ */ public interface RequestContext { /** * Retrieve the character encoding for the request. * * @return The character encoding for the request. */ String getCharacterEncoding(); /** * Retrieve the content type of the request. * * @return The content type of the request. */ String getContentType(); /** * Retrieve the content length of the request. * * @return The content length of the request. * @deprecated 1.3 Use {@link UploadContext#contentLength()} instead */ @Deprecated int getContentLength(); /** * Retrieve the input stream for the request. * * @return The input stream for the request. * * @throws IOException if a problem occurs. */ InputStream getInputStream() throws IOException; } ././@LongLink100644 0 0 151 12274740161 10254 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.100644 0 0 6561 12274737401 30655 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import org.apache.commons.io.FileCleaningTracker; /** * A servlet context listener, which ensures that the * {@link FileCleaningTracker}'s reaper thread is terminated, * when the web application is destroyed. * * @version $Id: FileCleanerCleanup.java 1564788 2014-02-05 14:36:41Z markt $ */ public class FileCleanerCleanup implements ServletContextListener { /** * Attribute name, which is used for storing an instance of * {@link FileCleaningTracker} in the web application. */ public static final String FILE_CLEANING_TRACKER_ATTRIBUTE = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; /** * Returns the instance of {@link FileCleaningTracker}, which is * associated with the given {@link ServletContext}. * * @param pServletContext The servlet context to query * @return The contexts tracker */ public static FileCleaningTracker getFileCleaningTracker(ServletContext pServletContext) { return (FileCleaningTracker) pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); } /** * Sets the instance of {@link FileCleaningTracker}, which is * associated with the given {@link ServletContext}. * * @param pServletContext The servlet context to modify * @param pTracker The tracker to set */ public static void setFileCleaningTracker(ServletContext pServletContext, FileCleaningTracker pTracker) { pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); } /** * Called when the web application is initialized. Does * nothing. * * @param sce The servlet context, used for calling * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. */ public void contextInitialized(ServletContextEvent sce) { setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); } /** * Called when the web application is being destroyed. * Calls {@link FileCleaningTracker#exitWhenFinished()}. * * @param sce The servlet context, used for calling * {@link #getFileCleaningTracker(ServletContext)}. */ public void contextDestroyed(ServletContextEvent sce) { getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/package-info.java100644 0 0 3764 12274737401 30364 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** *

* An implementation of * {@link org.apache.commons.fileupload.FileUpload FileUpload} * for use in servlets conforming to JSR 53. This implementation requires * only access to the servlet's current HttpServletRequest * instance, and a suitable * {@link org.apache.commons.fileupload.FileItemFactory FileItemFactory} * implementation, such as * {@link org.apache.commons.fileupload.disk.DiskFileItemFactory DiskFileItemFactory}. *

*

* The following code fragment demonstrates typical usage. *

*
 *        DiskFileItemFactory factory = new DiskFileItemFactory();
 *        // Configure the factory here, if desired.
 *        ServletFileUpload upload = new ServletFileUpload(factory);
 *        // Configure the uploader here, if desired.
 *        List fileItems = upload.parseRequest(request);
 * 
*

* Please see the FileUpload * User Guide * for further details and examples of how to use this package. *

*/ package org.apache.commons.fileupload.servlet; ././@LongLink100644 0 0 150 12274740161 10253 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/ServletFileUpload.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/ServletFileUpload.j100644 0 0 13723 12274737401 30755 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.servlet; import java.io.IOException; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileUpload; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; /** *

High level API for processing file uploads.

* *

This class handles multiple files per single HTML widget, sent using * multipart/mixed encoding type, as specified by * RFC 1867. Use {@link * #parseRequest(HttpServletRequest)} to acquire a list of {@link * org.apache.commons.fileupload.FileItem}s associated with a given HTML * widget.

* *

How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.

* * @version $Id: ServletFileUpload.java 1455949 2013-03-13 14:14:44Z simonetripodi $ */ public class ServletFileUpload extends FileUpload { /** * Constant for HTTP POST method. */ private static final String POST_METHOD = "POST"; // ---------------------------------------------------------- Class methods /** * Utility method that determines whether the request contains multipart * content. * * @param request The servlet request to be evaluated. Must be non-null. * * @return true if the request is multipart; * false otherwise. */ public static final boolean isMultipartContent( HttpServletRequest request) { if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) { return false; } return FileUploadBase.isMultipartContent(new ServletRequestContext(request)); } // ----------------------------------------------------------- Constructors /** * Constructs an uninitialised instance of this class. A factory must be * configured, using setFileItemFactory(), before attempting * to parse requests. * * @see FileUpload#FileUpload(FileItemFactory) */ public ServletFileUpload() { super(); } /** * Constructs an instance of this class which uses the supplied factory to * create FileItem instances. * * @see FileUpload#FileUpload() * @param fileItemFactory The factory to use for creating file items. */ public ServletFileUpload(FileItemFactory fileItemFactory) { super(fileItemFactory); } // --------------------------------------------------------- Public methods /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The servlet request to be parsed. * * @return A list of FileItem instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. */ @Override public List parseRequest(HttpServletRequest request) throws FileUploadException { return parseRequest(new ServletRequestContext(request)); } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The servlet request to be parsed. * * @return A map of FileItem instances parsed from the request. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * * @since 1.3 */ public Map> parseParameterMap(HttpServletRequest request) throws FileUploadException { return parseParameterMap(new ServletRequestContext(request)); } /** * Processes an RFC 1867 * compliant multipart/form-data stream. * * @param request The servlet request to be parsed. * * @return An iterator to instances of FileItemStream * parsed from the request, in the order that they were * transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. * @throws IOException An I/O error occurred. This may be a network * error while communicating with the client or a problem while * storing the uploaded content. */ public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { return super.getItemIterator(new ServletRequestContext(request)); } } ././@LongLink100644 0 0 154 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/ServletRequestContext.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/servlet/ServletRequestConte100644 0 0 7452 12274737401 31104 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.servlet; import static java.lang.String.format; import java.io.IOException; import java.io.InputStream; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.UploadContext; /** *

Provides access to the request information needed for a request made to * an HTTP servlet.

* * @since FileUpload 1.1 * * @version $Id: ServletRequestContext.java 1564788 2014-02-05 14:36:41Z markt $ */ public class ServletRequestContext implements UploadContext { // ----------------------------------------------------- Instance Variables /** * The request for which the context is being provided. */ private final HttpServletRequest request; // ----------------------------------------------------------- Constructors /** * Construct a context for this request. * * @param request The request to which this context applies. */ public ServletRequestContext(HttpServletRequest request) { this.request = request; } // --------------------------------------------------------- Public Methods /** * Retrieve the character encoding for the request. * * @return The character encoding for the request. */ public String getCharacterEncoding() { return request.getCharacterEncoding(); } /** * Retrieve the content type of the request. * * @return The content type of the request. */ public String getContentType() { return request.getContentType(); } /** * Retrieve the content length of the request. * * @return The content length of the request. * @deprecated 1.3 Use {@link #contentLength()} instead */ @Deprecated public int getContentLength() { return request.getContentLength(); } /** * Retrieve the content length of the request. * * @return The content length of the request. * @since 1.3 */ public long contentLength() { long size; try { size = Long.parseLong(request.getHeader(FileUploadBase.CONTENT_LENGTH)); } catch (NumberFormatException e) { size = request.getContentLength(); } return size; } /** * Retrieve the input stream for the request. * * @return The input stream for the request. * * @throws IOException if a problem occurs. */ public InputStream getInputStream() throws IOException { return request.getInputStream(); } /** * Returns a string representation of this object. * * @return a string representation of this object. */ @Override public String toString() { return format("ContentLength=%s, ContentType=%s", Long.valueOf(this.contentLength()), this.getContentType()); } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/UploadContext.java100644 0 0 2675 12274737401 27145 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; /** * Enhanced access to the request information needed for file uploads, * which fixes the Content Length data access in {@link RequestContext}. * * The reason of introducing this new interface is just for backward compatibility * and it might vanish for a refactored 2.x version moving the new method into * RequestContext again. * * @since 1.3 */ public interface UploadContext extends RequestContext { /** * Retrieve the content length of the request. * * @return The content length of the request. * @since 1.3 */ long contentLength(); } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/Closeable.java100644 0 0 2663 12274737401 27217 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util; import java.io.IOException; /** * Interface of an object, which may be closed. * * @version $Id: Closeable.java 1454691 2013-03-09 12:15:54Z simonetripodi $ */ public interface Closeable { /** * Closes the object. * * @throws IOException An I/O error occurred. */ void close() throws IOException; /** * Returns, whether the object is already closed. * * @return True, if the object is closed, otherwise false. * @throws IOException An I/O error occurred. */ boolean isClosed() throws IOException; } ././@LongLink100644 0 0 147 12274740161 10261 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/FileItemHeadersImpl.ja100644 0 0 6361 12274737401 30612 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.fileupload.FileItemHeaders; /** * Default implementation of the {@link FileItemHeaders} interface. * * @since 1.2.1 * * @version $Id: FileItemHeadersImpl.java 1458379 2013-03-19 16:16:47Z britter $ */ public class FileItemHeadersImpl implements FileItemHeaders, Serializable { /** * Serial version UID, being used, if serialized. */ private static final long serialVersionUID = -4455695752627032559L; /** * Map of String keys to a List of * String instances. */ private final Map> headerNameToValueListMap = new LinkedHashMap>(); /** * {@inheritDoc} */ public String getHeader(String name) { String nameLower = name.toLowerCase(Locale.ENGLISH); List headerValueList = headerNameToValueListMap.get(nameLower); if (null == headerValueList) { return null; } return headerValueList.get(0); } /** * {@inheritDoc} */ public Iterator getHeaderNames() { return headerNameToValueListMap.keySet().iterator(); } /** * {@inheritDoc} */ public Iterator getHeaders(String name) { String nameLower = name.toLowerCase(Locale.ENGLISH); List headerValueList = headerNameToValueListMap.get(nameLower); if (null == headerValueList) { headerValueList = Collections.emptyList(); } return headerValueList.iterator(); } /** * Method to add header values to this instance. * * @param name name of this header * @param value value of this header */ public synchronized void addHeader(String name, String value) { String nameLower = name.toLowerCase(Locale.ENGLISH); List headerValueList = headerNameToValueListMap.get(nameLower); if (null == headerValueList) { headerValueList = new ArrayList(); headerNameToValueListMap.put(nameLower, headerValueList); } headerValueList.add(value); } } ././@LongLink100644 0 0 146 12274740161 10260 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/LimitedInputStream.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/LimitedInputStream.jav100644 0 0 13256 12274737401 30770 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /** * An input stream, which limits its data size. This stream is * used, if the content length is unknown. * * @version $Id: LimitedInputStream.java 1565292 2014-02-06 14:51:59Z ggregory $ */ public abstract class LimitedInputStream extends FilterInputStream implements Closeable { /** * The maximum size of an item, in bytes. */ private final long sizeMax; /** * The current number of bytes. */ private long count; /** * Whether this stream is already closed. */ private boolean closed; /** * Creates a new instance. * * @param inputStream The input stream, which shall be limited. * @param pSizeMax The limit; no more than this number of bytes * shall be returned by the source stream. */ public LimitedInputStream(InputStream inputStream, long pSizeMax) { super(inputStream); sizeMax = pSizeMax; } /** * Called to indicate, that the input streams limit has * been exceeded. * * @param pSizeMax The input streams limit, in bytes. * @param pCount The actual number of bytes. * @throws IOException The called method is expected * to raise an IOException. */ protected abstract void raiseError(long pSizeMax, long pCount) throws IOException; /** * Called to check, whether the input streams * limit is reached. * * @throws IOException The given limit is exceeded. */ private void checkLimit() throws IOException { if (count > sizeMax) { raiseError(sizeMax, count); } } /** * Reads the next byte of data from this input stream. The value * byte is returned as an int in the range * 0 to 255. If no byte is available * because the end of the stream has been reached, the value * -1 is returned. This method blocks until input data * is available, the end of the stream is detected, or an exception * is thrown. *

* This method * simply performs in.read() and returns the result. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. * @see java.io.FilterInputStream#in */ @Override public int read() throws IOException { int res = super.read(); if (res != -1) { count++; checkLimit(); } return res; } /** * Reads up to len bytes of data from this input stream * into an array of bytes. If len is not zero, the method * blocks until some input is available; otherwise, no * bytes are read and 0 is returned. *

* This method simply performs in.read(b, off, len) * and returns the result. * * @param b the buffer into which the data is read. * @param off The start offset in the destination array * b. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the stream has been reached. * @exception NullPointerException If b is null. * @exception IndexOutOfBoundsException If off is negative, * len is negative, or len is greater than * b.length - off * @exception IOException if an I/O error occurs. * @see java.io.FilterInputStream#in */ @Override public int read(byte[] b, int off, int len) throws IOException { int res = super.read(b, off, len); if (res > 0) { count += res; checkLimit(); } return res; } /** * Returns, whether this stream is already closed. * * @return True, if the stream is closed, otherwise false. * @throws IOException An I/O error occurred. */ public boolean isClosed() throws IOException { return closed; } /** * Closes this input stream and releases any system resources * associated with the stream. * This * method simply performs in.close(). * * @exception IOException if an I/O error occurs. * @see java.io.FilterInputStream#in */ @Override public void close() throws IOException { closed = true; super.close(); } } ././@LongLink100644 0 0 146 12274740161 10260 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/Base64Decoder.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/Base64Decoder.jav100644 0 0 14177 12274737401 30451 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import java.io.IOException; import java.io.OutputStream; /** * @since 1.3 */ final class Base64Decoder { /** * Decoding table value for invalid bytes. */ private static final int INVALID_BYTE = -1; // must be outside range 0-63 /** * Decoding table value for padding bytes, so can detect PAD afer conversion. */ private static final int PAD_BYTE = -2; // must be outside range 0-63 /** * Mask to treat byte as unsigned integer. */ private static final int MASK_BYTE_UNSIGNED = 0xFF; /** * Number of bytes per encoded chunk - 4 6bit bytes produce 3 8bit bytes on output. */ private static final int INPUT_BYTES_PER_CHUNK = 4; /** * Set up the encoding table. */ private static final byte[] ENCODING_TABLE = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' }; /** * The padding byte. */ private static final byte PADDING = (byte) '='; /** * Set up the decoding table; this is indexed by a byte converted to an unsigned int, * so must be at least as large as the number of different byte values, * positive and negative and zero. */ private static final byte[] DECODING_TABLE = new byte[Byte.MAX_VALUE - Byte.MIN_VALUE + 1]; static { // Initialise as all invalid characters for (int i = 0; i < DECODING_TABLE.length; i++) { DECODING_TABLE[i] = INVALID_BYTE; } // set up valid characters for (int i = 0; i < ENCODING_TABLE.length; i++) { DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i; } // Allow pad byte to be easily detected after conversion DECODING_TABLE[PADDING] = PAD_BYTE; } /** * Hidden constructor, this class must not be instantiated. */ private Base64Decoder() { // do nothing } /** * Decode the base 64 encoded byte data writing it to the given output stream, * whitespace characters will be ignored. * * @param data the buffer containing the Base64-encoded data * @param out the output stream to hold the decoded bytes * * @return the number of bytes produced. * @throws IOException thrown when the padding is incorrect or the input is truncated. */ public static int decode(byte[] data, OutputStream out) throws IOException { int outLen = 0; byte [] cache = new byte[INPUT_BYTES_PER_CHUNK]; int cachedBytes = 0; for (byte b : data) { final byte d = DECODING_TABLE[MASK_BYTE_UNSIGNED & b]; if (d == INVALID_BYTE) { continue; // Ignore invalid bytes } cache[cachedBytes++] = d; if (cachedBytes == INPUT_BYTES_PER_CHUNK) { // CHECKSTYLE IGNORE MagicNumber FOR NEXT 4 LINES final byte b1 = cache[0]; final byte b2 = cache[1]; final byte b3 = cache[2]; final byte b4 = cache[3]; if (b1 == PAD_BYTE || b2 == PAD_BYTE) { throw new IOException("Invalid Base64 input: incorrect padding, first two bytes cannot be padding"); } // Convert 4 6-bit bytes to 3 8-bit bytes // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE out.write((b1 << 2) | (b2 >> 4)); // 6 bits of b1 plus 2 bits of b2 outLen++; if (b3 != PAD_BYTE) { // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE out.write((b2 << 4) | (b3 >> 2)); // 4 bits of b2 plus 4 bits of b3 outLen++; if (b4 != PAD_BYTE) { // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE out.write((b3 << 6) | b4); // 2 bits of b3 plus 6 bits of b4 outLen++; } } else if (b4 != PAD_BYTE) { // if byte 3 is pad, byte 4 must be pad too throw new // line wrap to avoid 120 char limit IOException("Invalid Base64 input: incorrect padding, 4th byte must be padding if 3rd byte is"); } cachedBytes = 0; } } // Check for anything left over if (cachedBytes != 0) { throw new IOException("Invalid Base64 input: truncated"); } return outLen; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/MimeUtility.java100644 0 0 25606 12274737401 30552 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * Utility class to decode MIME texts. * * @since 1.3 */ public final class MimeUtility { /** * The {@code US-ASCII} charset identifier constant. */ private static final String US_ASCII_CHARSET = "US-ASCII"; /** * The marker to indicate text is encoded with BASE64 algorithm. */ private static final String BASE64_ENCODING_MARKER = "B"; /** * The marker to indicate text is encoded with QuotedPrintable algorithm. */ private static final String QUOTEDPRINTABLE_ENCODING_MARKER = "Q"; /** * If the text contains any encoded tokens, those tokens will be marked with "=?". */ private static final String ENCODED_TOKEN_MARKER = "=?"; /** * If the text contains any encoded tokens, those tokens will terminate with "=?". */ private static final String ENCODED_TOKEN_FINISHER = "?="; /** * The linear whitespace chars sequence. */ private static final String LINEAR_WHITESPACE = " \t\r\n"; /** * Mappings between MIME and Java charset. */ private static final Map MIME2JAVA = new HashMap(); static { MIME2JAVA.put("iso-2022-cn", "ISO2022CN"); MIME2JAVA.put("iso-2022-kr", "ISO2022KR"); MIME2JAVA.put("utf-8", "UTF8"); MIME2JAVA.put("utf8", "UTF8"); MIME2JAVA.put("ja_jp.iso2022-7", "ISO2022JP"); MIME2JAVA.put("ja_jp.eucjp", "EUCJIS"); MIME2JAVA.put("euc-kr", "KSC5601"); MIME2JAVA.put("euckr", "KSC5601"); MIME2JAVA.put("us-ascii", "ISO-8859-1"); MIME2JAVA.put("x-us-ascii", "ISO-8859-1"); } /** * Hidden constructor, this class must not be instantiated. */ private MimeUtility() { // do nothing } /** * Decode a string of text obtained from a mail header into * its proper form. The text generally will consist of a * string of tokens, some of which may be encoded using * base64 encoding. * * @param text The text to decode. * * @return The decoded text string. * @throws UnsupportedEncodingException if the detected encoding in the input text is not supported. */ public static String decodeText(String text) throws UnsupportedEncodingException { // if the text contains any encoded tokens, those tokens will be marked with "=?". If the // source string doesn't contain that sequent, no decoding is required. if (text.indexOf(ENCODED_TOKEN_MARKER) < 0) { return text; } int offset = 0; int endOffset = text.length(); int startWhiteSpace = -1; int endWhiteSpace = -1; StringBuilder decodedText = new StringBuilder(text.length()); boolean previousTokenEncoded = false; while (offset < endOffset) { char ch = text.charAt(offset); // is this a whitespace character? if (LINEAR_WHITESPACE.indexOf(ch) != -1) { // whitespace found startWhiteSpace = offset; while (offset < endOffset) { // step over the white space characters. ch = text.charAt(offset); if (LINEAR_WHITESPACE.indexOf(ch) != -1) { // whitespace found offset++; } else { // record the location of the first non lwsp and drop down to process the // token characters. endWhiteSpace = offset; break; } } } else { // we have a word token. We need to scan over the word and then try to parse it. int wordStart = offset; while (offset < endOffset) { // step over the non white space characters. ch = text.charAt(offset); if (LINEAR_WHITESPACE.indexOf(ch) == -1) { // not white space offset++; } else { break; } //NB: Trailing whitespace on these header strings will just be discarded. } // pull out the word token. String word = text.substring(wordStart, offset); // is the token encoded? decode the word if (word.startsWith(ENCODED_TOKEN_MARKER)) { try { // if this gives a parsing failure, treat it like a non-encoded word. String decodedWord = decodeWord(word); // are any whitespace characters significant? Append 'em if we've got 'em. if (!previousTokenEncoded && startWhiteSpace != -1) { decodedText.append(text.substring(startWhiteSpace, endWhiteSpace)); startWhiteSpace = -1; } // this is definitely a decoded token. previousTokenEncoded = true; // and add this to the text. decodedText.append(decodedWord); // we continue parsing from here...we allow parsing errors to fall through // and get handled as normal text. continue; } catch (ParseException e) { // just ignore it, skip to next word } } // this is a normal token, so it doesn't matter what the previous token was. Add the white space // if we have it. if (startWhiteSpace != -1) { decodedText.append(text.substring(startWhiteSpace, endWhiteSpace)); startWhiteSpace = -1; } // this is not a decoded token. previousTokenEncoded = false; decodedText.append(word); } } return decodedText.toString(); } /** * Parse a string using the RFC 2047 rules for an "encoded-word" * type. This encoding has the syntax: * * encoded-word = "=?" charset "?" encoding "?" encoded-text "?=" * * @param word The possibly encoded word value. * * @return The decoded word. * @throws ParseException * @throws UnsupportedEncodingException */ private static String decodeWord(String word) throws ParseException, UnsupportedEncodingException { // encoded words start with the characters "=?". If this not an encoded word, we throw a // ParseException for the caller. if (!word.startsWith(ENCODED_TOKEN_MARKER)) { throw new ParseException("Invalid RFC 2047 encoded-word: " + word); } int charsetPos = word.indexOf('?', 2); if (charsetPos == -1) { throw new ParseException("Missing charset in RFC 2047 encoded-word: " + word); } // pull out the character set information (this is the MIME name at this point). String charset = word.substring(2, charsetPos).toLowerCase(); // now pull out the encoding token the same way. int encodingPos = word.indexOf('?', charsetPos + 1); if (encodingPos == -1) { throw new ParseException("Missing encoding in RFC 2047 encoded-word: " + word); } String encoding = word.substring(charsetPos + 1, encodingPos); // and finally the encoded text. int encodedTextPos = word.indexOf(ENCODED_TOKEN_FINISHER, encodingPos + 1); if (encodedTextPos == -1) { throw new ParseException("Missing encoded text in RFC 2047 encoded-word: " + word); } String encodedText = word.substring(encodingPos + 1, encodedTextPos); // seems a bit silly to encode a null string, but easy to deal with. if (encodedText.length() == 0) { return ""; } try { // the decoder writes directly to an output stream. ByteArrayOutputStream out = new ByteArrayOutputStream(encodedText.length()); byte[] encodedData = encodedText.getBytes(US_ASCII_CHARSET); // Base64 encoded? if (encoding.equals(BASE64_ENCODING_MARKER)) { Base64Decoder.decode(encodedData, out); } else if (encoding.equals(QUOTEDPRINTABLE_ENCODING_MARKER)) { // maybe quoted printable. QuotedPrintableDecoder.decode(encodedData, out); } else { throw new UnsupportedEncodingException("Unknown RFC 2047 encoding: " + encoding); } // get the decoded byte data and convert into a string. byte[] decodedData = out.toByteArray(); return new String(decodedData, javaCharset(charset)); } catch (IOException e) { throw new UnsupportedEncodingException("Invalid RFC 2047 encoding"); } } /** * Translate a MIME standard character set name into the Java * equivalent. * * @param charset The MIME standard name. * * @return The Java equivalent for this name. */ private static String javaCharset(String charset) { // nothing in, nothing out. if (charset == null) { return null; } String mappedCharset = MIME2JAVA.get(charset.toLowerCase(Locale.ENGLISH)); // if there is no mapping, then the original name is used. Many of the MIME character set // names map directly back into Java. The reverse isn't necessarily true. if (mappedCharset == null) { return charset; } return mappedCharset; } } ././@LongLink100644 0 0 145 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/package-info.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/package-info.java100644 0 0 2044 12274737401 30572 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * MIME decoder implementation, imported and retailed from * Apache Geronimo. */ package org.apache.commons.fileupload.util.mime; ././@LongLink100644 0 0 147 12274740161 10261 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/ParseException.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/ParseException.ja100644 0 0 2442 12274737401 30652 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; /** * @since 1.3 */ final class ParseException extends Exception { /** * The UID to use when serializing this instance. */ private static final long serialVersionUID = 5355281266579392077L; /** * Constructs a new exception with the specified detail message. * * @param message the detail message. */ public ParseException(String message) { super(message); } } ././@LongLink100644 0 0 157 12274740161 10262 Lustar 0 0 commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.javacommons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/mime/QuotedPrintableDe100644 0 0 10213 12274737401 30716 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import java.io.IOException; import java.io.OutputStream; /** * @since 1.3 */ final class QuotedPrintableDecoder { /** * The shift value required to create the upper nibble * from the first of 2 byte values converted from ascii hex. */ private static final int UPPER_NIBBLE_SHIFT = Byte.SIZE / 2; /** * Hidden constructor, this class must not be instantiated. */ private QuotedPrintableDecoder() { // do nothing } /** * Decode the encoded byte data writing it to the given output stream. * * @param data The array of byte data to decode. * @param out The output stream used to return the decoded data. * * @return the number of bytes produced. * @exception IOException */ public static int decode(byte[] data, OutputStream out) throws IOException { int off = 0; int length = data.length; int endOffset = off + length; int bytesWritten = 0; while (off < endOffset) { byte ch = data[off++]; // space characters were translated to '_' on encode, so we need to translate them back. if (ch == '_') { out.write(' '); } else if (ch == '=') { // we found an encoded character. Reduce the 3 char sequence to one. // but first, make sure we have two characters to work with. if (off + 1 >= endOffset) { throw new IOException("Invalid quoted printable encoding; truncated escape sequence"); } byte b1 = data[off++]; byte b2 = data[off++]; // we've found an encoded carriage return. The next char needs to be a newline if (b1 == '\r') { if (b2 != '\n') { throw new IOException("Invalid quoted printable encoding; CR must be followed by LF"); } // this was a soft linebreak inserted by the encoding. We just toss this away // on decode. } else { // this is a hex pair we need to convert back to a single byte. int c1 = hexToBinary(b1); int c2 = hexToBinary(b2); out.write((c1 << UPPER_NIBBLE_SHIFT) | c2); // 3 bytes in, one byte out bytesWritten++; } } else { // simple character, just write it out. out.write(ch); bytesWritten++; } } return bytesWritten; } /** * Convert a hex digit to the binary value it represents. * * @param b the ascii hex byte to convert (0-0, A-F, a-f) * @return the int value of the hex byte, 0-15 * @throws IOException if the byte is not a valid hex digit. */ private static int hexToBinary(final byte b) throws IOException { // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE final int i = Character.digit((char) b, 16); if (i == -1) { throw new IOException("Invalid quoted printable encoding: not a valid hex digit: " + b); } return i; } } commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/package-info.java100644 0 0 2030 12274737401 27636 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This package contains various IO related utility classes * or methods, which are basically reusable and not necessarily * restricted to the scope of a file upload. */ package org.apache.commons.fileupload.util; commons-fileupload-1.3.1-src/src/main/java/org/apache/commons/fileupload/util/Streams.java100644 0 0 16402 12274737401 26760 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.fileupload.InvalidFileNameException; import org.apache.commons.io.IOUtils; /** * Utility class for working with streams. * * @version $Id: Streams.java 1565332 2014-02-06 16:42:19Z ggregory $ */ public final class Streams { /** * Private constructor, to prevent instantiation. * This class has only static methods. */ private Streams() { // Does nothing } /** * Default buffer size for use in * {@link #copy(InputStream, OutputStream, boolean)}. */ private static final int DEFAULT_BUFFER_SIZE = 8192; /** * Copies the contents of the given {@link InputStream} * to the given {@link OutputStream}. Shortcut for *

     *   copy(pInputStream, pOutputStream, new byte[8192]);
     * 
* * @param inputStream The input stream, which is being read. * It is guaranteed, that {@link InputStream#close()} is called * on the stream. * @param outputStream The output stream, to which data should * be written. May be null, in which case the input streams * contents are simply discarded. * @param closeOutputStream True guarantees, that {@link OutputStream#close()} * is called on the stream. False indicates, that only * {@link OutputStream#flush()} should be called finally. * * @return Number of bytes, which have been copied. * @throws IOException An I/O error occurred. */ public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream) throws IOException { return copy(inputStream, outputStream, closeOutputStream, new byte[DEFAULT_BUFFER_SIZE]); } /** * Copies the contents of the given {@link InputStream} * to the given {@link OutputStream}. * * @param inputStream The input stream, which is being read. * It is guaranteed, that {@link InputStream#close()} is called * on the stream. * @param outputStream The output stream, to which data should * be written. May be null, in which case the input streams * contents are simply discarded. * @param closeOutputStream True guarantees, that {@link OutputStream#close()} * is called on the stream. False indicates, that only * {@link OutputStream#flush()} should be called finally. * @param buffer Temporary buffer, which is to be used for * copying data. * @return Number of bytes, which have been copied. * @throws IOException An I/O error occurred. */ public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream, byte[] buffer) throws IOException { OutputStream out = outputStream; InputStream in = inputStream; try { long total = 0; for (;;) { int res = in.read(buffer); if (res == -1) { break; } if (res > 0) { total += res; if (out != null) { out.write(buffer, 0, res); } } } if (out != null) { if (closeOutputStream) { out.close(); } else { out.flush(); } out = null; } in.close(); in = null; return total; } finally { IOUtils.closeQuietly(in); if (closeOutputStream) { IOUtils.closeQuietly(out); } } } /** * This convenience method allows to read a * {@link org.apache.commons.fileupload.FileItemStream}'s * content into a string. The platform's default character encoding * is used for converting bytes into characters. * * @param inputStream The input stream to read. * @see #asString(InputStream, String) * @return The streams contents, as a string. * @throws IOException An I/O error occurred. */ public static String asString(InputStream inputStream) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); copy(inputStream, baos, true); return baos.toString(); } /** * This convenience method allows to read a * {@link org.apache.commons.fileupload.FileItemStream}'s * content into a string, using the given character encoding. * * @param inputStream The input stream to read. * @param encoding The character encoding, typically "UTF-8". * @see #asString(InputStream) * @return The streams contents, as a string. * @throws IOException An I/O error occurred. */ public static String asString(InputStream inputStream, String encoding) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); copy(inputStream, baos, true); return baos.toString(encoding); } /** * Checks, whether the given file name is valid in the sense, * that it doesn't contain any NUL characters. If the file name * is valid, it will be returned without any modifications. Otherwise, * an {@link InvalidFileNameException} is raised. * * @param fileName The file name to check * @return Unmodified file name, if valid. * @throws InvalidFileNameException The file name was found to be invalid. */ public static String checkFileName(String fileName) { if (fileName != null && fileName.indexOf('\u0000') != -1) { // pFileName.replace("\u0000", "\\0") final StringBuilder sb = new StringBuilder(); for (int i = 0; i < fileName.length(); i++) { char c = fileName.charAt(i); switch (c) { case 0: sb.append("\\0"); break; default: sb.append(c); break; } } throw new InvalidFileNameException(fileName, "Invalid file name: " + sb); } return fileName; } } commons-fileupload-1.3.1-src/src/media/logo.xcf100644 0 0 61533 12274737400 16573 0ustar 0 0 gimp xcf file,dBB/ gimp-commentCreated with The GIMP74Ca, Text Layer#2     S0W,s+,f    UU8 U!q8U8U88qU88UqU88888U UUU8 U8 q 88qUUUUUU q U8U U UqUU U UU UU U U U UU q U  UqqU UUU UqqƪqqqUqƍUUU8qq888 UU U8UU8U8   ? UU UU88 8UU88 8UUUUUU UU8 UUUUU8UUUUq8UUUUqUUUUUUUUUUUUUUUUqU 8UU 8Uq UUq qqqq8q UUƪ Uq8 UU 8UU8U8UU8UU$U9U9U9U9U9U9U86UqU82 q   8;U;U;U;U;U;U;U;U;U;U;U UUU8UU qq  8UUUqUUU8qUUqUUqU8Uq88UqU 88U qUƪqUU U qU  8U qq8U 8UU qUUq qUUUU 8888U Uq8UqUqU8UU8UU8ƪƪ8U8qUƍUq88qqU U8 8UUUUUU8qUUUUUUUU8UUqUUUUUUUUUUUU8UqU88UU}f3 <Drop-Shadow#2h     O,<44<o&0 /        !!  !     $).1332001342,$ #(+)$   '-28=BFGFDCEGHE=1$ *5=@>6*  %.5;?DJPUWWVUVYYUJ<,+:HSWTI9(&2=CFHKOV\`aa`acc]RB1"$4FXflhZG1 $3AKOOLKNSZ_aab\QA0!'9Ndt|xhQ9# /APYZUMGFIOTWWXWRG9*&9Qi|qY>'  ':N^ecYLA;BEE .D^y}eO=/'#$)3@LTUOC3#+D`zzaE,$,27;?DJQVY ,B\w{bK9-%#'/=N]hjcS?++D`zzaE-(2:?ACEJQZci(=Wsu\E3'! &2CWjwzr`I2,DazzaF/! *6AHJIHGKR]jt #7QmoU=*#0D[q}iP7",DazzaG1%#*7EPUUPKGIP\ky2LhiN5#,AZrnT9$,DazzbH4)*5DT^a]UMGGMYiy.Hd}}eI0(=WqqV;%,DazzcI6.2?QakleZOHFKVdt ,Fb{{bF- $9SnqW<%,Daz{cK939I\lusj]PHEHP\i +DazzaE+ !6PkqW<&,Daz{dL<7?Qeu|xl]ND@AGOY *D`zz`D*  4OjqW<&,Daz{dM>;DWl{ykYJ>87:@F *D`zz`D* 3NiqW<&,Daz{eN?=H[pyhTB5-*+.2 *D`zz`D* 3MiqW<&,Daz{eN@>J]szgQ<-$! *D`zz`D* 3MiqW<&,Daz{eN@>J^t|hQ:) +DazzaD+ 3NiqW<&,Daz{eN?>I^tmU>* +DazzaD+ 3NiqW<&,Eaz{dM>;F[rv_G2# +Ea{{bE,  4OjrX='-Eaz{dM=9BVnkU@/$ -Gc||dG.  6PksY?)/Gc||eM<6=Og}zfSB6.++/Ie}}eJ0 #8Rlt[@+!1Id||eM;37F\swfWKB=;2Ke|}fL3 %:Smt\B- $4Ke{{fM:01>;3*!",4;=<7/&!)29==91($-5;>?>:4- "&))'" #'('$!&((%!  %')(%!                         &*-/.+&    $'(&#  &/9@EGE@90&  %.5:;93+"  $1?MX`c`YM@1$  $0BCB@ACHMRUTOG;."WOD5&-HggG, +:FIC7)$0?LV\\YVTUZ`fklh`SC2#jeXG5%.HhgG, +:FIC7* !,=Oantsngbadjqx}|vjXD2ywkYD0! /HhgG, +:FIC7*!$2F\q|riddiq{}lWAygP:( "0IhgG, +:FIC7*!%4Jcztf]Z]fs}hPoX@-#$1IhgG, +:FIC7* $3Jd}p]PJLUctu]~oYB/$%2IhgG, +:FIC7)!0Gb|~gRA99AQezgtxtfS>-#$1IhgG, +:EHB6(-C_yw_G4*)0?UmoaeaWG6( #1IggG, +:EHB6'*@[vqW>*#1GaztLNKC8+  /HfhH, +:EHB5&(>YsmR8$'=Wrv5750) .FeiI- ,:EGA4%'=XrjO5 !6Pkv#%$",DbjK/ -,;EG?2$&0"&ED;. &CB:.!%1(#!"$)/6=BB=4' %6,!*>Uk{zl\NB941136;?BB?7,  %2.1:EPWWPC4OG>4( /CXiuywoeZPHC@??ACDC?8.#  %7.$  %JTZ\[XTPMJHEC?:4,#  $ZtpV=(   (@[uoU<' +C]vpW>((.E^upX@+).D[o}{kV@- ( -?SdptnbP>, ('6FT\_[RD6( ( +6@FHE?5+  ( %,01/+% *  *  ,/40 /  . !'**& . &1:??9." -%4COVUM>. - -?Rbjj_M8% -  1F\ozynYA+ - 2IavwaG/-/Gax|fK1 ,D_whL2 )A\uiM3     &>YsiM3     %<JQROJGGKRXZUJ:*).#"+>XriO6%'4BMSRLC<76;DP\fkh^O>0''.;JV\ZSKEELV`fdZI6&*7:+&.@YriO8("'4DS]_YM@5-,0;IZitvpbP?307CR]`\RGAAIVeopgUA/%#+7FE3+0AYrjP:,)1ASbjg\K:,# $/?Rgw~r`M>847DYmz|q]E.*?YrxcN@;>EKLH@86:GZnnYG>AM^k[D77E[skS@8GXm~ucUR[lS?46DZrkTB;ATllP5  )@[tp_USX`ed\PC;;DUj}vdVR[lK903CZrkTA8=Nf~rW<& +B[rzk^Y\eouqfUF<:CUj}xfWRZkC3,2BZskS?58F]uw^E./E\ozzqd[Zbp|}p]K@>FXm{iYSXg{:-)0B[tlT>22>Ri}zfN8&$4H\kroeZUXevzgUIFM]rm\SVcu0'&0C\tmT>0-5F[o}zjVB1&!$,:KZdgaWNKRbvraUQVdvq_TS\l~'!#/C\tlT=.(,9K_nvuk\K<1,-4?KU[YQG@@I[q{l`[^hwsaTOS`q "/C[q|jS=,#$,;L\gjg]QE;66;BINNI@713=Oezrf``fq~q_QHIRa .AVivzrcN:)!,9HSZ\XPH@<;<@CC@90'#&0@Uixxnd\Y]eowysgXI?JRTPF9,#,39;;97420.+'""/=IQTRMF?::=CILJC9.% !' $.7<=;4+! "'*,+*)&$!  )28;:61+(')-143/' $(('"    #%%"             `        !"   &.462+!  (5BJLG<.  #3DT_b[M;( (;Pcptl[E/*?Vl{xfM5 )?XplS8")?XqpU:#  *?XqqW;$  !.BZsrW;$  !)6H_vsW<$ "%(-4@Qg|tX<$ !',0247>IZnuY<$ &/59;;=CO_tvY<$ 4=CDB?<=CO`uwZ=$ CKMJD=87=I\rwZ=$ QVTLA7/-3@TkvY<$ ]_XK<.%#(5Jc|uY<$ heYH5&,B\utX<$ piYD0&;UpsX<$ wmYA+"7QlrW<$ |oY@) 4OjrW<$ r[@) 4NiqW;$ v^C* 3NiqW;$ {cG. 4OjrX<$ 玁jO5""6PlsY=% 瑇rY?+';Uov[?' 璌|eM8*#%/B[ty^B* r]I:22;Lbz|bF-拐~l[LDCIWk}dI1怉xk^VSWaqzcI2 p}}tjb^_fp|r\E0 [isxxsmfa`bhpuvobP<*ES^ehgd_ZWVY]_^XM?0! 0;EMRTRNJFDDFFE@7-" '/5:<<9630//-)$ !%''%#      bn7 Text Layer      5M5iCC59=B/8qU8Uq8q8q q UU88UU8qUqUUUqUUUqUUq8U8 UU 8q8U8 q   8U 8U UU UU UU 8UU U 8 88 U q 8888 q8 q8qUUUUUqU UUUU U 8qUq q8UqUU8qU 8q8U8 8UqU8qqq88qqUUqUUUqƪUqUUUU8Uqq q8UUU 88UUqq UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU qUq qUqU8qU88qU8UƍUUUU8q qq q8  8qUU88qU 88 8UU UUUU8U8UUUUUUUUU8q 8UqUUU UUUUU 8UUUU UUUUU UUUU UUUU UUUUUU UUUUUU UUUUU UUUUUU UUUUU8 UUUU qUUUUq UUUUq8UUUUUUUUqUqU88UUqqU8q8qUU 8Uq8 q 8VVV UU ⪪88888Uqqq88  q 8 qU  qU qq8qƪq888UUk 5$ Drop-ShadowD       Dy$Daa$DLU]`   L          &.49<=<80% &-38<>=:4," & +7BJOTX\_^WI7%   -:CJOSWZ]]ZQE5% #1@L &8HTZ\\]bkwu_D*  )beD( ;eQ*=e]9 &BhoD$*Ky0V}zT0 )LtrI'.TwK'*Mzȳ\3 >m BmoD"  3QlxoV7 >ji<  8dŢrC  6f+Sd8 0BJE5"'M~_2)QϴR) 3c5b\0  $" /[ȷX, CuԿ^1 2b ?oX,   6e̸V*8iƝh8 2b !GxW+ ;lѺW+1_ʣn<2b $L¶Z- >pԾZ-,Yʤp>2b%NǼa3 >o×a2*UȢn<2b %Mßl<  ;kɠj:)TÝh8 2b "I|ʬ}K& 6cΪvD +Vʼ_1 2b Bsѻa7  0YҴP(.[ıS) 2b8gɨ{O-  !,/*)K|Ӿ`35cuE! 2b-WӾpJ. )7@?2" =iŢrC!  @n`6 2b !EtϷpQ;-%#%,7EPQF2-SȰX1 *NzuJ&3c3[ͷgVLHJQZabXC+ m*Krƻs[@' -Lo|aI:35>Ocu|t]@% )Jw .MpĽw^C*  -IgveWPPV_hleT<% !8X~ -Gd~oX?)  )?Vjvyume`]][SF4!  )A\z &:Napz~|uiYG4"   1AOY]][WSNH@5( (<82+# +7AIM !##      !$&     ?   @         !! )   ! )&(4>DE@6(  ,8AFFA6) !(*% ,8AFD=2# PI:+%*8HYgqtoaM6#,=N^ksuoaM5  (6EOOE4'%-mѽ`4  #5YʰW2 3Yʹ]6ĶnI, 6V~ƺuO1 6U}ĶpL2%$.Deb?&&AdıhEmO5!(>ZysU:&)>ZxnR<0/9LgcF-.GeiLzm[F1!'9Nbs~|q_K7&'9Nbs}zm[I90/7EWiw~vgT?,,@ViwykXDNLF<1$)5@HMOMG?4')5@HMNLF=3*%$)1;DJNNJC9-  -:DJNNKE;0&%# !$&&$  !$&&%# #%&&%" "%&&%#         >   A      "       "$0;CGE>2#  #+17;=><7/&  $+.+"%1$ .Hfmceo|acgn{a6 %A`y}kTA516CXra?$1MpʸnfejtOHEHTlwG"  <`yZ='&9Uw^9)DiãfTJHN_z6)$&1JpdzU+ 1WjD' 7Z~R.4ZuR:,'+;Y 3Zȼa3 #FrY1 !@kɽk? (M~Һb<#"@l&Lžj:1ZyJ$,T˰Q*"ExͱR+  1^  Fxţp??mo?  Bsҿb5 CuɫzH" +W  CvƦsA &K}i85cɣp? CuȨvD )T  BuƦtB",UÜf6,WέzG$!CuǧuB (R  BuǧtC#0[ƞg6&NвL'!CuǧuB (R  BuǧtC#2^ʢl: "H|гN("CuǧuB (R  BuǧuC#1^ͨs@  ExαL'!CuǧuB (R  BuǧuC#/YѰ}I"  DwʬzH$!CuǧuB (R  BuǧuC"*RԸS) FyĢp@ CuǧuB (R  BuǧuC!$Hza3 $K~ûc6 BuǧuB (R  BuǧuB 43:H\p|yfJ-  1X˰X3 "@k*'@cb@& &@]x{j[QOS\eki[E- "=b­c@'/Nu3!/GddG. "7Odsywpha^]]\WK:(  (CcdG/#7Sr0!-@Uhw~~vhU@-+=94.& *7CJNNJC:.!%2>G "%&&%"    "%&&%"  $      ?       -  &-13321/,)! U>' )8BGHHJKNNI<) eE( 1FUZWRNMRZeljX< ĩf?  0LdmgXI@?GVj{~kI'W/&Fh}|hL6)'0B\upN*ɾm> 4[d@%+EaqhK)ȭ~K$ ?kf=  /I[XB%̷U* !EtsI( 3CE5 ̽\. Etc@'".0& `0 >leH1!a12\sXA.!b2%GrµlS=+ b2 0S{fL5" ̶b2 5UxȽx[?' b24PnŸeD(b2 .D^zf@"b2 %7MgĬ[3b2 )-$$,=XupM+ƾ}U4$@b|yeQB;;BPbquiP3 xX;$3Mcli_TLHINV^`YH2|}sbL5""3AHIGDCCEHJJD9*MOMH@4&"&()+-/121.' &$!     )p8 ,d Background     bk,dbc7cCcO,dbbbbbbcccc+               0002K% commons-fileupload-1.3.1-src/src/site/fml/faq.fml100644 0 0 15775 12274737402 17054 0ustar 0 0 General Why is parseRequest() returning no items? This most commonly happens when the request has already been parsed, or processed in some other way. Since the input stream has aleady been consumed by that earlier process, it is no longer available for parsing by Commons FileUpload. Why am I getting "Read timed out" exceptions while parsing? The most common cause of these exceptions is when FileUpload is being used on a site that is using the Tomcat ISAPI redirector. There was a bug in earlier versions of that component that caused problems with multipart requests. The bug was fixed some time ago, so you probably just need to pick up a newer version. See the Tomcat bug report for full details. Why is NoClassDefFoundError being thrown?

There are two common causes for this error.

Firstly, it might simply mean that you do not have the Commons IO jar in your classpath. FileUpload depends on IO (see dependencies) - you can tell if this is the case if the missing class is within the org.apache.commons.io package.

Secondly this happens when attempting to rely on a shared copy of the Commons FileUpload jar file provided by your web container. The solution is to include the FileUpload jar file as part of your own web application, instead of relying on the container. The same may hold for FileUpload's IO dependency.

Why does FileItem.getName() return the whole path, and not just the file name? Internet Explorer provides the entire path to the uploaded file and not just the base file name. Since FileUpload provides exactly what was supplied by the client (browser), you may want to remove this path information in your application. You can do that using the following method from Commons IO (which you already have, since it is used by FileUpload).
    String fileName = item.getName();
    if (fileName != null) {
        filename = FilenameUtils.getName(filename);
    }
        
FileUpload and Struts 1 I'm using FileUpload in an Action, but it's not working. Why? Struts 1 recognises multipart requests, and parses them automatically, presenting the request parameters to your code in the same manner as if they were regular request parameters. Since Struts has already processed the request, and made it available in your form bean, the input stream is no longer available for parsing, so attempting to do so with FileUpload will fail. But I need to parse the request myself. How can I do that? Struts 1 parses multipart a request as a part of the process of populating your form bean from that request. If, for some reason, you need to have full control over the multipart parsing, you can do so by configuring your action mapping without an associated form bean. (A better way of doing this, however, is to replace the default multipart handler with your own. See the Struts 1 documentation for details.) FileUpload and Flash I'm using FileUpload to receive an upload from flash, but FileUpload will always throw an Exception "Stream ended unexpectedly". What can I do?

At least as of version 8, Flash contains a known bug: The multipart stream it produces is broken, because the final boundary doesn't contain the suffix "--", which ought to indicate, that no more items are following. Consequently, FileUpload waits for the next item (which it doesn't get) and throws an exception.

The problems details and a possible workaround are outlined in Bug 143 . The workaround suggests to use the streaming API and catch the exception. The resulting code could look like this:

 items = new ArrayList();

HttpServletRequest servletRequest = [...];
RequestContext ctx = new ServletRequestContext(servletRequest);

FileItemFactory fileItemFactory = new DiskFileItemFactory();

ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(ctx);
try {
    while (iter.hasNext()) {
        FileItemStream item = iter.next();
        FileItem fileItem = fileItemFactory.createItem(item.getFieldName(),
                                                       item.getContentType(),
                                                       item.isFormField(),
                                                       item.getName());
        Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
        items.add(fileItem);
    }
} catch (MalformedStreamException e) {
    // Ignore this
}]]>
commons-fileupload-1.3.1-src/src/site/resources/images/logo.gif100644 0 0 11360 12274737402 21717 0ustar 0 0 GIF89agw1!Software: Microsoft Office!,d0467=DFJLNh)j*3445677:<==>?@@ACCDFGHHIJKNNOPQQRST>_][YWUSQOMKIGECA}{ywusqomgcaejH*\ȰÇ#J"E 3jȱǏ-V#ȓ(S\iK &YʜIfA@8sӦϟ@33ѣH )S=J*UPj1W^ÊٳJŪ]K,ڷZ KwݺrU߿m떯Ꮒ ^,p>LY㍓3W~cPf-x4zf.zNCp| NAS{_0e_@'>ׯf{O?B /=_x$ Lx1I`@v<`-p dР=A֯ @ LhA  O03 mҐ0>Aȇ:< 9h%"QD"qȀs8-*`cx2h$#L6Qg4c[HG3$h"=c(H>RR/:f@ԣ _2$6Nr&n =I ) Sѕ\+]JZ2JV/0I/Lf1y"JQ*SPy&2@ \&LiLd 07qn0& řM<`,'2S` O }SP'@B-;Pk7an;~y~H 7Uzj;sH~=$Κ$&N +{py2oW>׶l :HéjU RBЇD ї;}H ԃΓ Jzէ *V: R|ͽa M& 2۽aΓW끗O,;'_jێϞ] BDOћ 09aR֧=Y*T8|d?z>M=T']`g@fJ^XB@[0}+}" I!'@5w W0Q8< 8~8~؀w(&hw|7v&hvjY0024XY8؃ⷃ:D'$2ym$|&|jHqXZ0Z؅^<b[HGcGn'ѷMC6gFa[0XX[؈0xȈqEXv8NHyzhgvs,\؊0[K kk!u++>> ;>нY@;? ۾ @0e?0 3ڼͫ\0phI[am!|dQX%\%9fѼ|b8 F.0vXøqR:|!\XYD̹2|HJ<>;P|!;commons-fileupload-1.3.1-src/src/site/resources/images/logo.png100644 0 0 32732 12274737402 21744 0ustar 0 0 PNG  IHDR,dcbKGD pHYs  ~tIME$6v IDATx=ixSױ^ɒmxR d}-lՀ7@@m&iY 1۔MZ,c; !!%ٲ0Ie;{4?Y;wΜ9s9G$ u j# @n100C[ # @n100C[ # @n100C[ 'FNj>_xo7O7V/$׶6#G4 A'ڒdȑF2@fXF5rH& SEEE'OvyGVmNqqoI9rdff'YY,2"/er7effr/Id2PQbԁLOlF BO=ԛoA&DGG{_vtt8r\.'RoRxbgggWWwj{1cГ`ʲylggW_}OvYAAA{{;2U`ތ . L&'x?niiijj:|jj*]v{Ҙ"$SRjTTڪ?ٜҲl2/xʕ/^c,** )&);;[͟9*Xի:nTŋRGf9rdAAAkkkssիWwܙH A7qΥhƌJ755}G0,{;w655uvv>p? իǎKJJB:MMM3_#,**®/˗/_tn7441ۿsrrwmjjHlSRjӧOr rg̘!ӧO e˖ܹsK/dwfdd.Z(22R|ʕVQF͘1Civ}۶mMF믿d9)1N:u崴4&]v1m4U䦦v^R/|ʕoeJ0**>ˌ3Tu֭[SK,۵kŋ9AEFFloCt| jQ#tvomnnVI N^zDDDD]]˗9 ")X~~~k)2eJpԩW^t:ʕ+)ɓcwuWiiicc#hfX,&crÆ ӧ?Accc}}}mmmYYYDDEꫯl6w}ֆtvvvr#_}(CK_}U@&V믿^n\[[kۛ84hW\VsZg3Oc@gggzz:'.hZUUntRCCj@1׭[gXx7W^m6[CCnZlپ<j8QByyĉsee^Ȑ1&Fh47oƧ8tPADQEQJ*))饗^G LRXX ~w  ÇW.\?~֭[#""$I;q:]]]MMMOF&>Qk:Eav:';v,L@6((4a{o[[l6 V$I999hӧO۠P`z+BcÇ8qq80(e h4AAAIII4j _%I"N8{0BڻSLgÀ7ׯnL& >mmm(!88x̘1TWl6ۦMwQWwr`tcƌ;;;]TeCBBGŔ|.#*jz=VPсPE5k ɓ9 rSsW^yL6Q[r|nCCdΪVM A[AAAZ~|aII ~,PӁ@~s*++o„ @PE>|8sH bT.S6:N:p2AM#KErȌ1008L4W`M 2NJQ2bbb m͡ J믿0lL( +O* IMʊ+vbO o&?=((7#48v1 p?"(t?D ݻ)19?{.Gw̙UuG{b)p0SP_,Jh( 8i$Ncvx|:j1cpKA~)(D* io1k֬JhLv[Ga}zV[__O)xS5%)$8zhjrg!#FuAکq2i8tO,l(wx~~ nܸXz5NUhFӧi“9!Gѣ T JO޿vxA?NGI]`W+Vؿxx8k]]s=䫯!ml6lTl|k㰰0.-=<\` #3@}Qʞ}Y%j}ك+7|ȑ#n 2T"?~Ӵ#}n|+.CYxͳCò… ??/.!:ݻwc>"Hp4| {p\F#eXVZ`yy̙3{= ;wЋƍ'{\ III\7箘lǏ &ɶYqi߾}?#==GAdƴ >jCCʕ+kkk~R`FJLLVIIIb1!)'NAϟp%=`1A,YB裏Bbƈy Z@uAbL! -TOJ}oF(?7;vlE5l6/-ϧ Paidd$dҰl vD444j'2`"jYύիWc$WMaСC366֠ay1BnkO6-###>>gٳgϞ={   @PHyPԳ>}a!VWh(yyytɚ5kV+:An0A͛!%ҍPb0֭ݪ._$s >FBQ333wءwyΝ;gΜ5kրM2wz+:pDٳg|IZ nL`0:t$)(oW 4443 2444p߀l R;|f3 Ff3n͝4il^?cȑ1f3g巿-ԩR C1updwލ49ǏFIWˀ}iРA4i6{M&˗8l6 ]vM<Bn ]Fq۩On~<;N>}ƍX,޳>tmmm_|ł l~_>psrFGZKK;SsN<8)!!76^XXXXllԩS;SWUU"3ƍ2dȐc{A {㎡CVWWWVVp*7f ڷoɓ' dǏ mV{Qj hznQAXVTCCC C1 \.F n[[[)2PN\.)X\p7 @ɀ& 3ɂARF6`[f\`@{S X^ | ;m4+`(z*htBsP4|̝j4ԥ]uw\ APQj]K' zդ(@c81V U 6 eDƑ>dWQE{}<c%5 &JׇP=A(X|P<AU>髁Oj4&{+c0cOJlB.Uv\œ/< dCP(h7z ـKx5:3/ڀ)rVz(enDh4.y3)(Q;8@ 6((mF`)5J 8ZDsz^Ѝ a;2_uar4:@gq`2@AC#LDs#)Hc#6 %KTq/wj`l9 Qv4Wv|5sz*"?Hݻ IΧH(*wI$Վ]L%vKQBjw)`ȂD|Jdn1L2gE8NLhSTZUDHPr_9z\hT^JԘZOJN0] _UEQ"+ 7a", OVGS'MxiTσk@fIg+T'/xzwfh靔'Gdw%z!\`gfddP)Yֵkך'|pAܮUG`|z^(/"d0>IOeh,((aСX'$&& d)`$yaK0wr>(p GoŧnHBQaa!n4:_/hT—N pXtt':;;Kn2CW^zF3337lh>&IO?tYYY~U(A(ܼ{=/d743222A~v_넽Fm6|#F8ΰG778q].eR>CȊx(/3_.9rϞ=$&''s2HA4\?({& J:+V N5\9barj]+XX|9wk$u*K ,_}Pa k/gwuעE:ܷo_DD@v9"ɓ'ǎ$&UnqNrL{z,aWQ:u}w,5NJlwJ\77B& p֬Yxӷn*&ms#!cIﰰ0}M8'N\v'M$IRGG g%;f춶6 kc[$?[ZZRHIIN/AQ%|CwY%%%Bi./bjJOOG#t:ע\dz^s?Ɇۀ1!..nذa06@-5~bR#)](m'S#IRjjrZE`ME-eߌ1D1Vښs;d.p\`\y-w|K,@<ɔ[@qlNoCӏ$r8N`S PM%s=oҭ\.h4\٠Hs?owZ`4 w\Y侃DC E0"q%4WH0N,/k@ӻsf}RJ~Z>Jo7Bíw$I1 iΈ /MP+ ,oD| FQT(rm+.- ~o7B7r!LR|MF+|,)g*+S;ӴmA=xnS"o Q؆ .y.?i#,IRtt*Jb$+JFL3+%JVQn@ِ$h4FEEyaXzΜ9Slj۷bJKKc%U/˚L&XǗ.] J@U_UdU:`pl`޽O?4QC믿N_MGQU$^Z-|;## w5k֨rJU ǑQ?sSBݭ\Y&NPUUUVVvĉ'O9s… WTT__ٔ@:U-d2f̘ѣGGEE޽/<[vСCكVcwjrrجxg<{lu\csu,o}w~Wx,͸x+Ʌp$IPv…_`0X,gy{)**rȠ+**8p`NNNTTݻ8[IDAT?|ҥ{2{NP%I9sѣM&ӪU.^DV}?Aɼ?{GB̔p(( cLzEQX-pTj;v,2cL:u_+55U޻CX]]]=cp}UUEZƍ>i|OP\\S\]]][[cQ\\\nnƍ###_|EZwF!(nڴ NPU ˈ)hfxN_Ir'L[Ϟ= +tg>C8.QHUUU~0 2eJJJ 0ՈLm۶Еa$b*N8ߢJFHcN=5BMHqFm֭'NhM$G2r=^5/ 9 hvFNE$UUU. KyDHd>p@Jȑ#?#뺢|^8r{̙;w:thԩY4QFՅ^2""Xɽ7PY)wsBy ei=<)3n'wmLS8LaVغ:,j)iӦGn{ッ빑:8 qA")nֻޑA5Hã@{pldPw?}jl%14κ:HKAӊV3;4͛7o޼9""bƍÇW qteO.Bܢ}&(j#<ԗq8LaBẁ6ou4{yDyc z{wA!S$1&u̘.n`v7qbP)oٲ_fM:w^/̫2ԍz"\'>| At J]C.tꋼā P殈10yJK1 Sq 6%KN6m֭RCͧ(/dfB7j>np1 ^d>/g8ťOJcW/w+f$1jjjdFVZÿ ,\OD$IkӧOw-OL  zW^9ug `7g}ƩUré_ 4d>~Ɉpܹ @.{ۈvȑgR7% KܶԆn2('DAX`Aee%Džqqqu`'\NDQܾ}Ip{Æ G Y{Aᣏ>M:dURR30RSS{챶6x\#d[ ].עE˅ n۶`0@[z)b0m* Z6>>@f͛7/666,,ܹs6-""jڴi 16G;w$瞫sM6mܸqSLtpj+6И<Ձr]1ry˹sfee1t:]hhh߾}CCC6ywMÏ~6l"Zvv6\aUG=|>Oc)b<&Wx]xqÆ (Pܪ*;鯽Zxx8{cU؜9s0nbbb̙zʕ;v^{S}R^766"cÆ ۲e$I&$$~;ɔSs禤 <8$$>x-h{VHo"0a„^x!::nJ3gNvv6./YY ۷og= *=-^#G.ظ8xw^|O?,//~=#F2v=##Ǻe˖͚5+((\۷ڵgBB~#F:th… ;v,j4^ j,ЫFB?`K(h4IIIhNEjz~okllD@u`EEE%&&k:.t 0cLHHI3ܾ\5c ΝtVc =b:5•+W}]]]ϟozAF''PnV}嚚,_Plu:FAt:= 8pȑ#AnL𮮮'O~'?ɀ4 Kt!ӟ?c m8%[,AHHH0 jCC$I70B |k vZp@N <(Pb h$3eO4BEC}@1p7jfp`~u&`q,@eV:";6(:ï::: pT 'tloA?DP t7t0 $f CF .1!ᯈ 7i-Y<.RlIQ>r_"9A#GS_!ťT(@˅ڌ>Sƶ ?>L)K_D?3{i4m(z>!] 7a5`4$Ix{]i pf)٠ 3Q 4 .dIEH0m㿸0Mm*@l!L&s8F(KC ѡSd)Aqk<6S* s9{F#;HًTgT9id w[UEEE%%%}Fw_xx8ӇnWn䩙އeO?g_,`3gK)V b 5^ # 7=B]`eVpp0T@%`C'`G8Ls 0nA(Q^įV5݂`D81yѨ%Oa<fq 1,e ]+5WuYA Rd#u')% UV Jo9ݳrIENDB`commons-fileupload-1.3.1-src/src/site/site.xml100644 0 0 3757 12274737402 16472 0ustar 0 0 Commons FileUpload /images/logo.png /index.html commons-fileupload-1.3.1-src/src/site/xdoc/customizing.xml100644 0 0 2503 12274737402 21022 0ustar 0 0 Customizing FileUpload Martin Cooper

TODO: Document usage of factories and subclassing for customization.

commons-fileupload-1.3.1-src/src/site/xdoc/download_fileupload.xml100644 0 0 16070 12274737402 22506 0ustar 0 0 Download Apache Commons FileUpload Commons Documentation Team

We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

You are currently using [preferred]. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

[if-any logo][end]

Other mirrors:

The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

commons-fileupload-1.3.1-bin.tar.gz md5 pgp
commons-fileupload-1.3.1-bin.zip md5 pgp
commons-fileupload-1.3.1-src.tar.gz md5 pgp
commons-fileupload-1.3.1-src.zip md5 pgp

Older releases can be obtained from the archives.

commons-fileupload-1.3.1-src/src/site/xdoc/index.xml100644 0 0 13257 12274737402 17606 0ustar 0 0 Home Martin Cooper

The Commons FileUpload package makes it easy to add robust, high-performance, file upload capability to your servlets and web applications.

FileUpload parses HTTP requests which conform to RFC 1867, "Form-based File Upload in HTML". That is, if an HTTP request is submitted using the POST method, and with a content type of "multipart/form-data", then FileUpload can parse that request, and make the results available in a manner easily used by the caller.

Starting with version 1.3, FileUpload handles RFC 2047 encoded header values.

The simplest way to send a multipart/form-data request to a server is via a web form, i.e.

File to upload:
Notes about the file:

to upload the file! ]]>

The following documentation is available:

You can also browse the Subversion repository.

FileUpload 1.3 - 27 March 2013

  • Download the binary and source distributions from a mirror site here

FileUpload 1.2.2 - 29 July 2010

  • Download the binary and source distributions from a mirror site here

FileUpload 1.2.1 - 18 January 2008

  • Download the binary and source distributions from the archive site here

FileUpload 1.2 - 13 February 2007

  • Download the binary and source distributions from the archive site here

FileUpload 1.1.1 - 08 June 2006

  • Download the binary and source distributions from the archive site here

FileUpload 1.1 - 22 Dec 2005

  • Download the binary and source distributions from the archive site here

FileUpload 1.0 - 24 Jun 2003

  • Download the binary and source distributions from the archive site here

None available.

The Apache Commons mailing lists act as the main support forum. The user list is suitable for most library usage queries. The dev list is intended for development discussion. Please remember that the lists are shared between all commons components, so prefix your e-mail subject line with [fileupload].

Issues may be reported via ASF JIRA.

commons-fileupload-1.3.1-src/src/site/xdoc/issue-tracking.xml100644 0 0 13463 12274737402 21426 0ustar 0 0 Commons FileUpload Issue tracking Commons Documentation Team

Commons FileUpload uses ASF JIRA for tracking issues. See the Commons FileUpload JIRA project page.

To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

If you would like to report a bug, or raise an enhancement request with Commons FileUpload please do the following:

  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
  3. Decide if your issue is a bug or an enhancement.
  4. Submit either a bug report or enhancement request.

Please also remember these points:

  • the more information you provide, the better we can help you
  • test cases are vital, particularly for any proposed enhancements
  • the developers of Commons FileUpload are all unpaid volunteers

For more information on subversion and creating patches see the Apache Contributors Guide.

You may also find these links useful:

commons-fileupload-1.3.1-src/src/site/xdoc/mail-lists.xml100644 0 0 22646 12274737402 20557 0ustar 0 0 Commons FileUpload Mailing Lists Commons Documentation Team

Commons FileUpload shares mailing lists with all the other Commons Components. To make it easier for people to only read messages related to components they are interested in, the convention in Commons is to prefix the subject line of messages with the component's name, for example:

  • [fileupload] Problem with the ...

Questions related to the usage of Commons FileUpload should be posted to the User List.
The Developer List is for questions and discussion related to the development of Commons FileUpload.
Please do not cross-post; developers are also subscribed to the user list.

Note: please don't send patches or attachments to any of the mailing lists. Patches are best handled via the Issue Tracking system. Otherwise, please upload the file to a public server and include the URL in the mail.

Please prefix the subject line of any messages for Commons FileUpload with [fileupload] - thanks!

Name Subscribe Unsubscribe Post Archive Other Archives
Commons User List

Questions on using Commons FileUpload.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Developer List

Discussion of development of Commons FileUpload.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Issues List

Only for e-mails automatically generated by the issue tracking system.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com
Commons Commits List

Only for e-mails automatically generated by the source control sytem.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com

Other mailing lists which you may find useful include:

Name Subscribe Unsubscribe Post Archive Other Archives
Apache Announce List

General announcements of Apache project releases.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
old.nabble.com
www.mail-archive.com
news.gmane.org
commons-fileupload-1.3.1-src/src/site/xdoc/overview.xml100644 0 0 4424 12274737402 20321 0ustar 0 0 Fileupload Overview Robert Burrell Donkin

Your application should detect whether or not FileUpload should be invoked, based on the HTTP method and the content type of the request.

Assuming that you have decided that FileUpload should be invoked, you might write the following code to handle a file upload request: items = upload.parseRequest(request); // Process the uploaded fields Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); if (item.isFormField()) { processTextParameter(request, item); } else { processFileParameter(request, item); } } ]]>

commons-fileupload-1.3.1-src/src/site/xdoc/streaming.xml100644 0 0 6634 12274737402 20451 0ustar 0 0 The Streaming API

The traditional API, which is described in the User Guide, assumes, that file items must be stored somewhere, before they are actually accessable by the user. This approach is convenient, because it allows easy access to an items contents. On the other hand, it is memory and time consuming.

The streaming API allows you to trade a little bit of convenience for optimal performance and and a low memory profile. Additionally, the API is more lightweight, thus easier to understand.

Again, the FileUpload class is used for accessing the form fields and fields in the order, in which they have been sent by the client. However, the FileItemFactory is completely ignored.

First of all, do not forget to ensure, that a request actually is a a file upload request. This is typically done using the same static method, which you already know from the traditional API.

Now we are ready to parse the request into its constituent items. Here's how we do it:

That's all that's needed. Really!

commons-fileupload-1.3.1-src/src/site/xdoc/using.xml100644 0 0 46674 12274737402 17635 0ustar 0 0 Using FileUpload Martin Cooper

FileUpload can be used in a number of different ways, depending upon the requirements of your application. In the simplest case, you will call a single method to parse the servlet request, and then process the list of items as they apply to your application. At the other end of the scale, you might decide to customize FileUpload to take full control of the way in which individual items are stored; for example, you might decide to stream the content into a database.

Here, we will describe the basic principles of FileUpload, and illustrate some of the simpler - and most common - usage patterns. Customization of FileUpload is described elsewhere.

FileUpload depends on Commons IO, so make sure you have the version mentioned on the dependencies page in your classpath before continuing.

A file upload request comprises an ordered list of items that are encoded according to RFC 1867, "Form-based File Upload in HTML". FileUpload can parse such a request and provide your application with a list of the individual uploaded items. Each such item implements the FileItem interface, regardless of its underlying implementation.

This page describes the traditional API of the commons fileupload library. The traditional API is a convenient approach. However, for ultimate performance, you might prefer the faster Streaming API.

Each file item has a number of properties that might be of interest for your application. For example, every item has a name and a content type, and can provide an InputStream to access its data. On the other hand, you may need to process items differently, depending upon whether the item is a regular form field - that is, the data came from an ordinary text box or similar HTML field - or an uploaded file. The FileItem interface provides the methods to make such a determination, and to access the data in the most appropriate manner.

FileUpload creates new file items using a FileItemFactory. This is what gives FileUpload most of its flexibility. The factory has ultimate control over how each item is created. The factory implementation that currently ships with FileUpload stores the item's data in memory or on disk, depending on the size of the item (i.e. bytes of data). However, this behavior can be customized to suit your application.

Starting with version 1.1, FileUpload supports file upload requests in both servlet and portlet environments. The usage is almost identical in the two environments, so the remainder of this document refers only to the servlet environment.

If you are building a portlet application, the following are the two distinctions you should make as you read this document:

  • Where you see references to the ServletFileUpload class, substitute the PortletFileUpload class.
  • Where you see references to the HttpServletRequest class, substitute the ActionRequest class.

Before you can work with the uploaded items, of course, you need to parse the request itself. Ensuring that the request is actually a file upload request is straightforward, but FileUpload makes it simplicity itself, by providing a static method to do just that.

Now we are ready to parse the request into its constituent items.

The simplest usage scenario is the following:

  • Uploaded items should be retained in memory as long as they are reasonably small.
  • Larger items should be written to a temporary file on disk.
  • Very large upload requests should not be permitted.
  • The built-in defaults for the maximum size of an item to be retained in memory, the maximum permitted size of an upload request, and the location of temporary files are acceptable.

Handling a request in this scenario couldn't be much simpler:

items = upload.parseRequest(request);]]>

That's all that's needed. Really!

The result of the parse is a List of file items, each of which implements the FileItem interface. Processing these items is discussed below.

If your usage scenario is close to the simplest case, described above, but you need a little more control, you can easily customize the behavior of the upload handler or the file item factory or both. The following example shows several configuration options:

items = upload.parseRequest(request);]]>

Of course, each of the configuration methods is independent of the others, but if you want to configure the factory all at once, you can do that with an alternative constructor, like this:

Should you need further control over the parsing of the request, such as storing the items elsewhere - for example, in a database - you will need to look into customizing FileUpload.

Once the parse has completed, you will have a List of file items that you need to process. In most cases, you will want to handle file uploads differently from regular form fields, so you might process the list like this:

iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); if (item.isFormField()) { processFormField(item); } else { processUploadedFile(item); } }]]>

For a regular form field, you will most likely be interested only in the name of the item, and its String value. As you might expect, accessing these is very simple.

For a file upload, there are several different things you might want to know before you process the content. Here is an example of some of the methods you might be interested in.

With uploaded files, you generally will not want to access them via memory, unless they are small, or unless you have no other alternative. Rather, you will want to process the content as a stream, or write the entire file to its ultimate location. FileUpload provides simple means of accomplishing both of these.

Note that, in the default implementation of FileUpload, write() will attempt to rename the file to the specified destination, if the data is already in a temporary file. Actually copying the data is only done if the the rename fails, for some reason, or if the data was in memory.

If you do need to access the uploaded data in memory, you need simply call the get() method to obtain the data as an array of bytes.

This section applies only, if you are using the DiskFileItem. In other words, it applies, if your uploaded files are written to temporary files before processing them.

Such temporary files are deleted automatically, if they are no longer used (more precisely, if the corresponding instance of java.io.File is garbage collected. This is done silently by the org.apache.commons.io.FileCleaner class, which starts a reaper thread.

This reaper thread should be stopped, if it is no longer needed. In a servlet environment, this is done by using a special servlet context listener, called FileCleanerCleanup. To do so, add a section like the following to your web.xml:

... org.apache.commons.fileupload.servlet.FileCleanerCleanup ... ]]>

The FileCleanerCleanup provides an instance of org.apache.commons.io.FileCleaningTracker. This instance must be used when creating a org.apache.commons.fileupload.disk.DiskFileItemFactory. This should be done by calling a method like the following:

To disable tracking of temporary files, you may set the FileCleaningTracker to null. Consequently, created files will no longer be tracked. In particular, they will no longer be deleted automatically.

Virus scanners running on the same system as the web container can cause some unexpected behaviours for applications using FileUpload. This section describes some of the behaviours that you might encounter, and provides some ideas for how to handle them.

The default implementation of FileUpload will cause uploaded items above a certain size threshold to be written to disk. As soon as such a file is closed, any virus scanner on the system will wake up and inspect it, and potentially quarantine the file - that is, move it to a special location where it will not cause problems. This, of course, will be a surprise to the application developer, since the uploaded file item will no longer be available for processing. On the other hand, uploaded items below that same threshold will be held in memory, and therefore will not be seen by virus scanners. This allows for the possibility of a virus being retained in some form (although if it is ever written to disk, the virus scanner would locate and inspect it).

One commonly used solution is to set aside one directory on the system into which all uploaded files will be placed, and to configure the virus scanner to ignore that directory. This ensures that files will not be ripped out from under the application, but then leaves responsibility for virus scanning up to the application developer. Scanning the uploaded files for viruses can then be performed by an external process, which might move clean or cleaned files to an "approved" location, or by integrating a virus scanner within the application itself. The details of configuring an external process or integrating virus scanning into an application are outside the scope of this document.

If you expect really large file uploads, then it would be nice to report to your users, how much is already received. Even HTML pages allow to implement a progress bar by returning a multipart/replace response, or something like that.

Watching the upload progress may be done by supplying a progress listener:

Do yourself a favour and implement your first progress listener just like the above, because it shows you a pitfall: The progress listener is called quite frequently. Depending on the servlet engine and other environment factory, it may be called for any network packet! In other words, your progress listener may become a performance problem! A typical solution might be, to reduce the progress listeners activity. For example, you might emit a message only, if the number of megabytes has changed:

Hopefully this page has provided you with a good idea of how to use FileUpload in your own applications. For more detail on the methods introduced here, as well as other available methods, you should refer to the JavaDocs.

The usage described here should satisfy a large majority of file upload needs. However, should you have more complex requirements, FileUpload should still be able to help you, with it's flexible customization capabilities.

commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/DefaultFileItemTest.java100644 0 0 26502 12274737401 30265 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import org.junit.Test; /** * Unit tests for {@link org.apache.commons.fileupload.DefaultFileItem}. * * @version $Id: DefaultFileItemTest.java 1565246 2014-02-06 13:40:52Z ggregory $ */ @SuppressWarnings({"deprecation", "javadoc"}) // unit tests for deprecated class public class DefaultFileItemTest { /** * Content type for regular form items. */ private static final String textContentType = "text/plain"; /** * Content type for file uploads. */ private static final String fileContentType = "application/octet-stream"; /** * Very low threshold for testing memory versus disk options. */ private static final int threshold = 16; /** * Test construction of a regular text field. */ @Test public void testTextFieldConstruction() { FileItemFactory factory = createFactory(null); String textFieldName = "textField"; FileItem item = factory.createItem( textFieldName, textContentType, true, null ); assertNotNull(item); assertEquals(item.getFieldName(), textFieldName); assertEquals(item.getContentType(), textContentType); assertTrue(item.isFormField()); assertNull(item.getName()); } /** * Test construction of a file field. */ @Test public void testFileFieldConstruction() { FileItemFactory factory = createFactory(null); String fileFieldName = "fileField"; String fileName = "originalFileName"; FileItem item = factory.createItem( fileFieldName, fileContentType, false, fileName ); assertNotNull(item); assertEquals(item.getFieldName(), fileFieldName); assertEquals(item.getContentType(), fileContentType); assertFalse(item.isFormField()); assertEquals(item.getName(), fileName); } /** * Test creation of a field for which the amount of data falls below the * configured threshold. */ @Test public void testBelowThreshold() { FileItemFactory factory = createFactory(null); String textFieldName = "textField"; String textFieldValue = "0123456789"; byte[] testFieldValueBytes = textFieldValue.getBytes(); FileItem item = factory.createItem( textFieldName, textContentType, true, null ); assertNotNull(item); try { OutputStream os = item.getOutputStream(); os.write(testFieldValueBytes); os.close(); } catch(IOException e) { fail("Unexpected IOException"); } assertTrue(item.isInMemory()); assertEquals(item.getSize(), testFieldValueBytes.length); assertTrue(Arrays.equals(item.get(), testFieldValueBytes)); assertEquals(item.getString(), textFieldValue); } /** * Test creation of a field for which the amount of data falls above the * configured threshold, where no specific repository is configured. */ @Test public void testAboveThresholdDefaultRepository() { doTestAboveThreshold(null); } /** * Test creation of a field for which the amount of data falls above the * configured threshold, where a specific repository is configured. */ @Test public void testAboveThresholdSpecifiedRepository() { String tempPath = System.getProperty("java.io.tmpdir"); String tempDirName = "testAboveThresholdSpecifiedRepository"; File tempDir = new File(tempPath, tempDirName); tempDir.mkdir(); doTestAboveThreshold(tempDir); assertTrue(tempDir.delete()); } /** * Common code for cases where the amount of data is above the configured * threshold, but the ultimate destination of the data has not yet been * determined. * * @param repository The directory within which temporary files will be * created. */ public void doTestAboveThreshold(File repository) { FileItemFactory factory = createFactory(repository); String textFieldName = "textField"; String textFieldValue = "01234567890123456789"; byte[] testFieldValueBytes = textFieldValue.getBytes(); FileItem item = factory.createItem( textFieldName, textContentType, true, null ); assertNotNull(item); try { OutputStream os = item.getOutputStream(); os.write(testFieldValueBytes); os.close(); } catch(IOException e) { fail("Unexpected IOException"); } assertFalse(item.isInMemory()); assertEquals(item.getSize(), testFieldValueBytes.length); assertTrue(Arrays.equals(item.get(), testFieldValueBytes)); assertEquals(item.getString(), textFieldValue); assertTrue(item instanceof DefaultFileItem); DefaultFileItem dfi = (DefaultFileItem) item; File storeLocation = dfi.getStoreLocation(); assertNotNull(storeLocation); assertTrue(storeLocation.exists()); assertEquals(storeLocation.length(), testFieldValueBytes.length); if (repository != null) { assertEquals(storeLocation.getParentFile(), repository); } item.delete(); } /** * Creates a new FileItemFactory and returns it, obscuring * from the caller the underlying implementation of this interface. * * @param repository The directory within which temporary files will be * created. * @return the new FileItemFactory instance. */ protected FileItemFactory createFactory(File repository) { return new DefaultFileItemFactory(threshold, repository); } static final String CHARSET_ISO88591 = "ISO-8859-1"; static final String CHARSET_ASCII = "US-ASCII"; static final String CHARSET_UTF8 = "UTF-8"; static final String CHARSET_KOI8_R = "KOI8_R"; static final String CHARSET_WIN1251 = "Cp1251"; static final int SWISS_GERMAN_STUFF_UNICODE [] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 }; static final int SWISS_GERMAN_STUFF_ISO8859_1 [] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 }; static final int SWISS_GERMAN_STUFF_UTF8 [] = { 0x47, 0x72, 0xC3, 0xBC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xC3, 0xA4, 0x6D, 0xC3, 0xA4 }; static final int RUSSIAN_STUFF_UNICODE [] = { 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 }; static final int RUSSIAN_STUFF_UTF8 [] = { 0xD0, 0x92, 0xD1, 0x81, 0xD0, 0xB5, 0xD0, 0xBC, 0x5F, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82 }; static final int RUSSIAN_STUFF_KOI8R [] = { 0xF7, 0xD3, 0xC5, 0xCD, 0x5F, 0xD0, 0xD2, 0xC9, 0xD7, 0xC5, 0xD4 }; static final int RUSSIAN_STUFF_WIN1251 [] = { 0xC2, 0xF1, 0xE5, 0xEC, 0x5F, 0xEF, 0xF0, 0xE8, 0xE2, 0xE5, 0xF2 }; private static String constructString(int[] unicodeChars) { StringBuilder buffer = new StringBuilder(); if (unicodeChars != null) { for (int unicodeChar : unicodeChars) { buffer.append((char) unicodeChar); } } return buffer.toString(); } /** * Test construction of content charset. */ public void testContentCharSet() throws Exception { FileItemFactory factory = createFactory(null); String teststr = constructString(SWISS_GERMAN_STUFF_UNICODE); FileItem item = factory.createItem( "doesnotmatter", "text/plain; charset=" + CHARSET_ISO88591, true, null); OutputStream outstream = item.getOutputStream(); for (int element : SWISS_GERMAN_STUFF_ISO8859_1) { outstream.write(element); } outstream.close(); assertEquals(teststr, teststr, item.getString()); item = factory.createItem( "doesnotmatter", "text/plain; charset=" + CHARSET_UTF8, true, null); outstream = item.getOutputStream(); for (int element : SWISS_GERMAN_STUFF_UTF8) { outstream.write(element); } outstream.close(); assertEquals(teststr, teststr, item.getString()); teststr = constructString(RUSSIAN_STUFF_UNICODE); item = factory.createItem( "doesnotmatter", "text/plain; charset=" + CHARSET_KOI8_R, true, null); outstream = item.getOutputStream(); for (int element : RUSSIAN_STUFF_KOI8R) { outstream.write(element); } outstream.close(); assertEquals(teststr, teststr, item.getString()); item = factory.createItem( "doesnotmatter", "text/plain; charset=" + CHARSET_WIN1251, true, null); outstream = item.getOutputStream(); for (int element : RUSSIAN_STUFF_WIN1251) { outstream.write(element); } outstream.close(); assertEquals(teststr, teststr, item.getString()); item = factory.createItem( "doesnotmatter", "text/plain; charset=" + CHARSET_UTF8, true, null); outstream = item.getOutputStream(); for (int element : RUSSIAN_STUFF_UTF8) { outstream.write(element); } outstream.close(); assertEquals(teststr, teststr, item.getString()); } } ././@LongLink100644 0 0 150 12274740161 10253 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.j100644 0 0 23562 12274737401 30756 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.junit.Test; /** * Serialization Unit tests for * {@link org.apache.commons.fileupload.disk.DiskFileItem}. * * @version $Id: DiskFileItemSerializeTest.java 1507048 2013-07-25 16:16:15Z markt $ */ public class DiskFileItemSerializeTest { /** * Content type for regular form items. */ private static final String textContentType = "text/plain"; /** * Very low threshold for testing memory versus disk options. */ private static final int threshold = 16; /** * Helper method to test creation of a field when a repository is used. */ public void testInMemoryObject(byte[] testFieldValueBytes, File repository) { FileItem item = createFileItem(testFieldValueBytes, repository); // Check state is as expected assertTrue("Initial: in memory", item.isInMemory()); assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length); compareBytes("Initial", item.get(), testFieldValueBytes); // Serialize & Deserialize FileItem newItem = (FileItem)serializeDeserialize(item); // Test deserialized content is as expected assertTrue("Check in memory", newItem.isInMemory()); compareBytes("Check", testFieldValueBytes, newItem.get()); // Compare FileItem's (except byte[]) compareFileItems(item, newItem); } /** * Helper method to test creation of a field. */ private void testInMemoryObject(byte[] testFieldValueBytes) { testInMemoryObject(testFieldValueBytes, null); } /** * Test creation of a field for which the amount of data falls below the * configured threshold. */ @Test public void testBelowThreshold() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold - 1); testInMemoryObject(testFieldValueBytes); } /** * Test creation of a field for which the amount of data equals the * configured threshold. */ @Test public void testThreshold() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold); testInMemoryObject(testFieldValueBytes); } /** * Test creation of a field for which the amount of data falls above the * configured threshold. */ @Test public void testAboveThreshold() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold + 1); FileItem item = createFileItem(testFieldValueBytes); // Check state is as expected assertFalse("Initial: in memory", item.isInMemory()); assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length); compareBytes("Initial", item.get(), testFieldValueBytes); // Serialize & Deserialize FileItem newItem = (FileItem)serializeDeserialize(item); // Test deserialized content is as expected assertFalse("Check in memory", newItem.isInMemory()); compareBytes("Check", testFieldValueBytes, newItem.get()); // Compare FileItem's (except byte[]) compareFileItems(item, newItem); } /** * Test serialization and deserialization when repository is not null. */ @Test public void testValidRepository() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold); File repository = new File(System.getProperty("java.io.tmpdir")); testInMemoryObject(testFieldValueBytes, repository); } /** * Test deserialization fails when repository is not valid. */ @Test(expected=IOException.class) public void testInvalidRepository() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold); File repository = new File(System.getProperty("java.io.tmpdir") + "file"); FileItem item = createFileItem(testFieldValueBytes, repository); deserialize(serialize(item)); } /** * Test deserialization fails when repository contains a null character. */ @Test(expected=IOException.class) public void testInvalidRepositoryWithNullChar() throws Exception { // Create the FileItem byte[] testFieldValueBytes = createContentBytes(threshold); File repository = new File(System.getProperty("java.io.tmpdir") + "\0"); FileItem item = createFileItem(testFieldValueBytes, repository); deserialize(serialize(item)); } /** * Compare FileItem's (except the byte[] content) */ private void compareFileItems(FileItem origItem, FileItem newItem) { assertTrue("Compare: is in Memory", origItem.isInMemory() == newItem.isInMemory()); assertTrue("Compare: is Form Field", origItem.isFormField() == newItem.isFormField()); assertEquals("Compare: Field Name", origItem.getFieldName(), newItem.getFieldName()); assertEquals("Compare: Content Type", origItem.getContentType(), newItem.getContentType()); assertEquals("Compare: File Name", origItem.getName(), newItem.getName()); } /** * Compare content bytes. */ private void compareBytes(String text, byte[] origBytes, byte[] newBytes) { assertNotNull("origBytes must not be null", origBytes); assertNotNull("newBytes must not be null", newBytes); assertEquals(text + " byte[] length", origBytes.length, newBytes.length); for (int i = 0; i < origBytes.length; i++) { assertEquals(text + " byte[" + i + "]", origBytes[i], newBytes[i]); } } /** * Create content bytes of a specified size. */ private byte[] createContentBytes(int size) { StringBuilder buffer = new StringBuilder(size); byte count = 0; for (int i = 0; i < size; i++) { buffer.append(count+""); count++; if (count > 9) { count = 0; } } return buffer.toString().getBytes(); } /** * Create a FileItem with the specfied content bytes and repository. */ private FileItem createFileItem(byte[] contentBytes, File repository) { FileItemFactory factory = new DiskFileItemFactory(threshold, repository); String textFieldName = "textField"; FileItem item = factory.createItem( textFieldName, textContentType, true, "My File Name" ); try { OutputStream os = item.getOutputStream(); os.write(contentBytes); os.close(); } catch(IOException e) { fail("Unexpected IOException" + e); } return item; } /** * Create a FileItem with the specfied content bytes. */ private FileItem createFileItem(byte[] contentBytes) { return createFileItem(contentBytes, null); } /** * Do serialization */ private ByteArrayOutputStream serialize(Object target) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(target); oos.flush(); oos.close(); return baos; } /** * Do deserialization */ private Object deserialize(ByteArrayOutputStream baos) throws Exception { Object result = null; ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); result = ois.readObject(); bais.close(); return result; } /** * Do serialization and deserialization. */ private Object serializeDeserialize(Object target) { // Serialize the test object ByteArrayOutputStream baos = null; try { baos = serialize(target); } catch (Exception e) { fail("Exception during serialization: " + e); } // Deserialize the test object Object result = null; try { result = deserialize(baos); } catch (Exception e) { fail("Exception during deserialization: " + e); } return result; } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/FileItemHeadersTest.java100644 0 0 10170 12274737401 30246 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Iterator; import org.apache.commons.fileupload.util.FileItemHeadersImpl; import org.junit.Test; /** * Unit tests {@link FileItemHeaders} and * {@link FileItemHeadersImpl}. * * @version $Id$ */ public class FileItemHeadersTest { /** * @throws Exception */ @Test public void testFileItemHeaders() throws Exception { FileItemHeadersImpl aMutableFileItemHeaders = new FileItemHeadersImpl(); aMutableFileItemHeaders.addHeader("Content-Disposition", "form-data; name=\"FileItem\"; filename=\"file1.txt\""); aMutableFileItemHeaders.addHeader("Content-Type", "text/plain"); aMutableFileItemHeaders.addHeader("TestHeader", "headerValue1"); aMutableFileItemHeaders.addHeader("TestHeader", "headerValue2"); aMutableFileItemHeaders.addHeader("TestHeader", "headerValue3"); aMutableFileItemHeaders.addHeader("testheader", "headerValue4"); Iterator headerNameEnumeration = aMutableFileItemHeaders.getHeaderNames(); assertEquals("content-disposition", headerNameEnumeration.next()); assertEquals("content-type", headerNameEnumeration.next()); assertEquals("testheader", headerNameEnumeration.next()); assertFalse(headerNameEnumeration.hasNext()); assertEquals(aMutableFileItemHeaders.getHeader("Content-Disposition"), "form-data; name=\"FileItem\"; filename=\"file1.txt\""); assertEquals(aMutableFileItemHeaders.getHeader("Content-Type"), "text/plain"); assertEquals(aMutableFileItemHeaders.getHeader("content-type"), "text/plain"); assertEquals(aMutableFileItemHeaders.getHeader("TestHeader"), "headerValue1"); assertNull(aMutableFileItemHeaders.getHeader("DummyHeader")); Iterator headerValueEnumeration; headerValueEnumeration = aMutableFileItemHeaders.getHeaders("Content-Type"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "text/plain"); assertFalse(headerValueEnumeration.hasNext()); headerValueEnumeration = aMutableFileItemHeaders.getHeaders("content-type"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "text/plain"); assertFalse(headerValueEnumeration.hasNext()); headerValueEnumeration = aMutableFileItemHeaders.getHeaders("TestHeader"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "headerValue1"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "headerValue2"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "headerValue3"); assertTrue(headerValueEnumeration.hasNext()); assertEquals(headerValueEnumeration.next(), "headerValue4"); assertFalse(headerValueEnumeration.hasNext()); headerValueEnumeration = aMutableFileItemHeaders.getHeaders("DummyHeader"); assertFalse(headerValueEnumeration.hasNext()); } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/FileUploadTestCase.java100644 0 0 4160 12274737401 30056 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.UnsupportedEncodingException; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Base class for deriving test cases. * * @version $Id: FileUploadTestCase.java 1454693 2013-03-09 12:30:27Z simonetripodi $ */ public abstract class FileUploadTestCase { protected static final String CONTENT_TYPE = "multipart/form-data; boundary=---1234"; protected List parseUpload(byte[] bytes) throws FileUploadException { return parseUpload(bytes, CONTENT_TYPE); } protected List parseUpload(byte[] bytes, String contentType) throws FileUploadException { ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); HttpServletRequest request = new MockHttpServletRequest(bytes, contentType); List fileItems = upload.parseRequest(request); return fileItems; } protected List parseUpload(String content) throws UnsupportedEncodingException, FileUploadException { byte[] bytes = content.getBytes("US-ASCII"); return parseUpload(bytes, CONTENT_TYPE); } } ././@LongLink100644 0 0 150 12274740161 10253 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/HttpServletRequestFactory.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/HttpServletRequestFactory.j100644 0 0 4236 12274737401 31077 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import javax.servlet.http.HttpServletRequest; /** * @version $Id: HttpServletRequestFactory.java 1565246 2014-02-06 13:40:52Z ggregory $ */ final class HttpServletRequestFactory { static public HttpServletRequest createHttpServletRequestWithNullContentType() { byte[] requestData = "foobar".getBytes(); return new MockHttpServletRequest( requestData, null); } static public HttpServletRequest createValidHttpServletRequest( final String[] strFileNames) { // todo - provide a real implementation StringBuilder sbRequestData = new StringBuilder(); for (String strFileName : strFileNames) { sbRequestData.append(strFileName); } byte[] requestData = null; requestData = sbRequestData.toString().getBytes(); return new MockHttpServletRequest( requestData, FileUploadBase.MULTIPART_FORM_DATA); } static public HttpServletRequest createInvalidHttpServletRequest() { byte[] requestData = "foobar".getBytes(); return new MockHttpServletRequest( requestData, FileUploadBase.MULTIPART_FORM_DATA); } } ././@LongLink100644 0 0 145 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/MockHttpServletRequest.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/MockHttpServletRequest.java100644 0 0 31564 12274737401 31075 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.Principal; import java.util.Enumeration; import java.util.Locale; import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletInputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * @version $Id: MockHttpServletRequest.java 1565255 2014-02-06 13:49:17Z ggregory $ */ class MockHttpServletRequest implements HttpServletRequest { private final InputStream m_requestData; private long length; private String m_strContentType; private int readLimit = -1; private final Map m_headers = new java.util.HashMap(); /** * Creates a new instance with the given request data * and content type. */ public MockHttpServletRequest( final byte[] requestData, final String strContentType) { this(new ByteArrayInputStream(requestData), requestData.length, strContentType); } /** * Creates a new instance with the given request data * and content type. */ public MockHttpServletRequest( final InputStream requestData, final long requestLength, final String strContentType) { m_requestData = requestData; length = requestLength; m_strContentType = strContentType; m_headers.put(FileUploadBase.CONTENT_TYPE, strContentType); } /** * @see javax.servlet.http.HttpServletRequest#getAuthType() */ public String getAuthType() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getCookies() */ public Cookie[] getCookies() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getDateHeader(String) */ public long getDateHeader(String arg0) { return 0; } /** * @see javax.servlet.http.HttpServletRequest#getHeader(String) */ public String getHeader(String headerName) { return m_headers.get(headerName); } /** * @see javax.servlet.http.HttpServletRequest#getHeaders(String) */ public Enumeration getHeaders(String arg0) { // todo - implement return null; } /** * @see javax.servlet.http.HttpServletRequest#getHeaderNames() */ public Enumeration getHeaderNames() { // todo - implement return null; } /** * @see javax.servlet.http.HttpServletRequest#getIntHeader(String) */ public int getIntHeader(String arg0) { return 0; } /** * @see javax.servlet.http.HttpServletRequest#getMethod() */ public String getMethod() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getPathInfo() */ public String getPathInfo() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getPathTranslated() */ public String getPathTranslated() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getContextPath() */ public String getContextPath() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getQueryString() */ public String getQueryString() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getRemoteUser() */ public String getRemoteUser() { return null; } /** * @see javax.servlet.http.HttpServletRequest#isUserInRole(String) */ public boolean isUserInRole(String arg0) { return false; } /** * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() */ public Principal getUserPrincipal() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() */ public String getRequestedSessionId() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getRequestURI() */ public String getRequestURI() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getRequestURL() */ public StringBuffer getRequestURL() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getServletPath() */ public String getServletPath() { return null; } /** * @see javax.servlet.http.HttpServletRequest#getSession(boolean) */ public HttpSession getSession(boolean arg0) { return null; } /** * @see javax.servlet.http.HttpServletRequest#getSession() */ public HttpSession getSession() { return null; } /** * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() */ public boolean isRequestedSessionIdValid() { return false; } /** * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() */ public boolean isRequestedSessionIdFromCookie() { return false; } /** * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() */ public boolean isRequestedSessionIdFromURL() { return false; } /** * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() * @deprecated */ @Deprecated public boolean isRequestedSessionIdFromUrl() { return false; } /** * @see javax.servlet.ServletRequest#getAttribute(String) */ public Object getAttribute(String arg0) { return null; } /** * @see javax.servlet.ServletRequest#getAttributeNames() */ public Enumeration getAttributeNames() { return null; } /** * @see javax.servlet.ServletRequest#getCharacterEncoding() */ public String getCharacterEncoding() { return null; } /** * @see javax.servlet.ServletRequest#setCharacterEncoding(String) */ public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException { } /** * @see javax.servlet.ServletRequest#getContentLength() */ public int getContentLength() { int iLength = 0; if (null == m_requestData) { iLength = -1; } else { if (length > Integer.MAX_VALUE) { throw new RuntimeException("Value '" + length + "' is too large to be converted to int"); } iLength = (int) length; } return iLength; } /** * For testing attack scenarios in SizesTest. */ public void setContentLength(long length) { this.length = length; } /** * @see javax.servlet.ServletRequest#getContentType() */ public String getContentType() { return m_strContentType; } /** * @see javax.servlet.ServletRequest#getInputStream() */ public ServletInputStream getInputStream() throws IOException { ServletInputStream sis = new MyServletInputStream(m_requestData, readLimit); return sis; } /** * Sets the read limit. This can be used to limit the number of bytes to read ahead. * * @param readLimit the read limit to use */ public void setReadLimit(int readLimit) { this.readLimit = readLimit; } /** * @see javax.servlet.ServletRequest#getParameter(String) */ public String getParameter(String arg0) { return null; } /** * @see javax.servlet.ServletRequest#getParameterNames() */ public Enumeration getParameterNames() { return null; } /** * @see javax.servlet.ServletRequest#getParameterValues(String) */ public String[] getParameterValues(String arg0) { return null; } /** * @see javax.servlet.ServletRequest#getParameterMap() */ public Map getParameterMap() { return null; } /** * @see javax.servlet.ServletRequest#getProtocol() */ public String getProtocol() { return null; } /** * @see javax.servlet.ServletRequest#getScheme() */ public String getScheme() { return null; } /** * @see javax.servlet.ServletRequest#getServerName() */ public String getServerName() { return null; } /** * @see javax.servlet.ServletRequest#getLocalName() */ @SuppressWarnings("javadoc") // This is a Servlet 2.4 method public String getLocalName() { return null; } /** * @see javax.servlet.ServletRequest#getServerPort() */ public int getServerPort() { return 0; } /** * @see javax.servlet.ServletRequest#getLocalPort() */ @SuppressWarnings("javadoc") // This is a Servlet 2.4 method public int getLocalPort() { return 0; } /** * @see javax.servlet.ServletRequest#getRemotePort() */ @SuppressWarnings("javadoc") // This is a Servlet 2.4 method public int getRemotePort() { return 0; } /** * @see javax.servlet.ServletRequest#getReader() */ public BufferedReader getReader() throws IOException { return null; } /** * @see javax.servlet.ServletRequest#getRemoteAddr() */ public String getRemoteAddr() { return null; } /** * @see javax.servlet.ServletRequest#getLocalAddr() */ @SuppressWarnings("javadoc") // This is a Servlet 2.4 method public String getLocalAddr() { return null; } /** * @see javax.servlet.ServletRequest#getRemoteHost() */ public String getRemoteHost() { return null; } /** * @see javax.servlet.ServletRequest#setAttribute(String, Object) */ public void setAttribute(String arg0, Object arg1) { } /** * @see javax.servlet.ServletRequest#removeAttribute(String) */ public void removeAttribute(String arg0) { } /** * @see javax.servlet.ServletRequest#getLocale() */ public Locale getLocale() { return null; } /** * @see javax.servlet.ServletRequest#getLocales() */ public Enumeration getLocales() { return null; } /** * @see javax.servlet.ServletRequest#isSecure() */ public boolean isSecure() { return false; } /** * @see javax.servlet.ServletRequest#getRequestDispatcher(String) */ public RequestDispatcher getRequestDispatcher(String arg0) { return null; } /** * @see javax.servlet.ServletRequest#getRealPath(String) * @deprecated */ @Deprecated public String getRealPath(String arg0) { return null; } private static class MyServletInputStream extends javax.servlet.ServletInputStream { private final InputStream in; private final int readLimit; /** * Creates a new instance, which returns the given * streams data. */ public MyServletInputStream(InputStream pStream, int readLimit) { in = pStream; this.readLimit = readLimit; } @Override public int read() throws IOException { return in.read(); } @Override public int read(byte b[], int off, int len) throws IOException { if (readLimit > 0) { return in.read(b, off, Math.min(readLimit, len)); } return in.read(b, off, len); } } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/MultipartStreamTest.java100644 0 0 5656 12274737401 30406 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertNotNull; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.junit.Test; /** * Unit tests {@link org.apache.commons.fileupload.MultipartStream}. * * @version $Id: MultipartStreamTest.java 1565190 2014-02-06 12:01:48Z markt $ */ public class MultipartStreamTest { static private final String BOUNDARY_TEXT = "myboundary"; @Test public void testThreeParamConstructor() throws Exception { final String strData = "foobar"; final byte[] contents = strData.getBytes(); InputStream input = new ByteArrayInputStream(contents); byte[] boundary = BOUNDARY_TEXT.getBytes(); int iBufSize = boundary.length + MultipartStream.BOUNDARY_PREFIX.length + 1; MultipartStream ms = new MultipartStream( input, boundary, iBufSize, new MultipartStream.ProgressNotifier(null, contents.length)); assertNotNull(ms); } @SuppressWarnings("unused") @Test(expected=IllegalArgumentException.class) public void testSmallBuffer() throws Exception { final String strData = "foobar"; final byte[] contents = strData.getBytes(); InputStream input = new ByteArrayInputStream(contents); byte[] boundary = BOUNDARY_TEXT.getBytes(); int iBufSize = 1; new MultipartStream( input, boundary, iBufSize, new MultipartStream.ProgressNotifier(null, contents.length)); } @Test public void testTwoParamConstructor() throws Exception { final String strData = "foobar"; final byte[] contents = strData.getBytes(); InputStream input = new ByteArrayInputStream(contents); byte[] boundary = BOUNDARY_TEXT.getBytes(); MultipartStream ms = new MultipartStream( input, boundary, new MultipartStream.ProgressNotifier(null, contents.length)); assertNotNull(ms); } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/ParameterParserTest.java100644 0 0 11400 12274737401 30346 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.util.Map; import org.junit.Test; /** * Unit tests for {@link ParameterParser}. * * @version $Id: ParameterParserTest.java 1455521 2013-03-12 13:18:01Z simonetripodi $ */ public class ParameterParserTest { @Test public void testParsing() { String s = "test; test1 = stuff ; test2 = \"stuff; stuff\"; test3=\"stuff"; ParameterParser parser = new ParameterParser(); Map params = parser.parse(s, ';'); assertEquals(null, params.get("test")); assertEquals("stuff", params.get("test1")); assertEquals("stuff; stuff", params.get("test2")); assertEquals("\"stuff", params.get("test3")); params = parser.parse(s, new char[] { ',', ';' }); assertEquals(null, params.get("test")); assertEquals("stuff", params.get("test1")); assertEquals("stuff; stuff", params.get("test2")); assertEquals("\"stuff", params.get("test3")); s = " test , test1=stuff , , test2=, test3, "; params = parser.parse(s, ','); assertEquals(null, params.get("test")); assertEquals("stuff", params.get("test1")); assertEquals(null, params.get("test2")); assertEquals(null, params.get("test3")); s = " test"; params = parser.parse(s, ';'); assertEquals(null, params.get("test")); s = " "; params = parser.parse(s, ';'); assertEquals(0, params.size()); s = " = stuff "; params = parser.parse(s, ';'); assertEquals(0, params.size()); } @Test public void testContentTypeParsing() { String s = "text/plain; Charset=UTF-8"; ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); Map params = parser.parse(s, ';'); assertEquals("UTF-8", params.get("charset")); } @Test public void testParsingEscapedChars() { String s = "param = \"stuff\\\"; more stuff\""; ParameterParser parser = new ParameterParser(); Map params = parser.parse(s, ';'); assertEquals(1, params.size()); assertEquals("stuff\\\"; more stuff", params.get("param")); s = "param = \"stuff\\\\\"; anotherparam"; params = parser.parse(s, ';'); assertEquals(2, params.size()); assertEquals("stuff\\\\", params.get("param")); assertNull(params.get("anotherparam")); } // See: http://issues.apache.org/jira/browse/FILEUPLOAD-139 @Test public void testFileUpload139() { ParameterParser parser = new ParameterParser(); String s = "Content-type: multipart/form-data , boundary=AaB03x"; Map params = parser.parse(s, new char[] { ',', ';' }); assertEquals("AaB03x", params.get("boundary")); s = "Content-type: multipart/form-data, boundary=AaB03x"; params = parser.parse(s, new char[] { ';', ',' }); assertEquals("AaB03x", params.get("boundary")); s = "Content-type: multipart/mixed, boundary=BbC04y"; params = parser.parse(s, new char[] { ',', ';' }); assertEquals("BbC04y", params.get("boundary")); } /** * Test for FILEUPLOAD-199 */ @Test public void fileUpload199() { ParameterParser parser = new ParameterParser(); String s = "Content-Disposition: form-data; name=\"file\"; filename=\"=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n"; Map params = parser.parse(s, new char[] { ',', ';' }); assertEquals("If you can read this you understand the example.", params.get("filename")); } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/ProgressListenerTest.java100644 0 0 11703 12274737401 30571 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.junit.Test; /** * Tests the progress listener. * * @version $Id: ProgressListenerTest.java 1454693 2013-03-09 12:30:27Z simonetripodi $ */ public class ProgressListenerTest extends FileUploadTestCase { private class ProgressListenerImpl implements ProgressListener { private final long expectedContentLength; private final int expectedItems; private Long bytesRead; private Integer items; ProgressListenerImpl(long pContentLength, int pItems) { expectedContentLength = pContentLength; expectedItems = pItems; } public void update(long pBytesRead, long pContentLength, int pItems) { assertTrue(pBytesRead >= 0 && pBytesRead <= expectedContentLength); assertTrue(pContentLength == -1 || pContentLength == expectedContentLength); assertTrue(pItems >= 0 && pItems <= expectedItems); assertTrue(bytesRead == null || pBytesRead >= bytesRead.longValue()); bytesRead = new Long(pBytesRead); assertTrue(items == null || pItems >= items.intValue()); items = new Integer(pItems); } void checkFinished(){ assertEquals(expectedContentLength, bytesRead.longValue()); assertEquals(expectedItems, items.intValue()); } } /** * Parse a very long file upload by using a progress listener. */ @Test public void testProgressListener() throws Exception { final int NUM_ITEMS = 512; ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (int i = 0; i < NUM_ITEMS; i++) { String header = "-----1234\r\n" + "Content-Disposition: form-data; name=\"field" + (i+1) + "\"\r\n" + "\r\n"; baos.write(header.getBytes("US-ASCII")); for (int j = 0; j < 16384+i; j++) { baos.write((byte) j); } baos.write("\r\n".getBytes("US-ASCII")); } baos.write("-----1234--\r\n".getBytes("US-ASCII")); byte[] contents = baos.toByteArray(); MockHttpServletRequest request = new MockHttpServletRequest(contents, "multipart/form-data; boundary=---1234"); runTest(NUM_ITEMS, contents.length, request); request = new MockHttpServletRequest(contents, "multipart/form-data; boundary=---1234"){ @Override public int getContentLength() { return -1; } }; runTest(NUM_ITEMS, contents.length, request); } private void runTest(final int NUM_ITEMS, long pContentLength, MockHttpServletRequest request) throws FileUploadException, IOException { ServletFileUpload upload = new ServletFileUpload(); ProgressListenerImpl listener = new ProgressListenerImpl(pContentLength, NUM_ITEMS); upload.setProgressListener(listener); FileItemIterator iter = upload.getItemIterator(request); for (int i = 0; i < NUM_ITEMS; i++) { FileItemStream stream = iter.next(); InputStream istream = stream.openStream(); for (int j = 0; j < 16384+i; j++) { /** * This used to be * assertEquals((byte) j, (byte) istream.read()); * but this seems to trigger a bug in JRockit, so * we express the same like this: */ byte b1 = (byte) j; byte b2 = (byte) istream.read(); if (b1 != b2) { fail("Expected " + b1 + ", got " + b2); } } assertEquals(-1, istream.read()); } assertTrue(!iter.hasNext()); listener.checkFinished(); } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/ServletFileUploadTest.java100644 0 0 44442 12274737401 30656 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.junit.Test; /** * Unit tests {@link org.apache.commons.fileupload.DiskFileUpload}. * * @version $Id: ServletFileUploadTest.java 1564788 2014-02-05 14:36:41Z markt $ */ @SuppressWarnings({"deprecation", "javadoc"}) // unit tests for deprecated class public class ServletFileUploadTest extends FileUploadTestCase { @Test public void testWithInvalidRequest() { FileUploadBase fu = null; fu = new DiskFileUpload(); HttpServletRequest req = HttpServletRequestFactory.createInvalidHttpServletRequest(); try { fu.parseRequest(req); fail("testWithInvalidRequest: expected exception was not thrown"); } catch (FileUploadException expected) { // this exception is expected } } @Test public void testWithNullContentType() { FileUploadBase fu = new DiskFileUpload(); HttpServletRequest req = HttpServletRequestFactory.createHttpServletRequestWithNullContentType(); try { fu.parseRequest(req); fail("testWithNullContentType: expected exception was not thrown"); } catch (DiskFileUpload.InvalidContentTypeException expected) { // this exception is expected } catch (FileUploadException unexpected) { fail("testWithNullContentType: unexpected exception was thrown"); } } @Test public void testFileUpload() throws IOException, FileUploadException { List fileItems = parseUpload("-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"field\"\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value1\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value2\r\n" + "-----1234--\r\n"); assertEquals(4, fileItems.size()); FileItem file = fileItems.get(0); assertEquals("file", file.getFieldName()); assertFalse(file.isFormField()); assertEquals("This is the content of the file\n", file.getString()); assertEquals("text/whatever", file.getContentType()); assertEquals("foo.tab", file.getName()); FileItem field = fileItems.get(1); assertEquals("field", field.getFieldName()); assertTrue(field.isFormField()); assertEquals("fieldValue", field.getString()); FileItem multi0 = fileItems.get(2); assertEquals("multi", multi0.getFieldName()); assertTrue(multi0.isFormField()); assertEquals("value1", multi0.getString()); FileItem multi1 = fileItems.get(3); assertEquals("multi", multi1.getFieldName()); assertTrue(multi1.isFormField()); assertEquals("value2", multi1.getString()); } @Test public void testFilenameCaseSensitivity() throws IOException, FileUploadException { List fileItems = parseUpload("-----1234\r\n" + "Content-Disposition: form-data; name=\"FiLe\"; filename=\"FOO.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"); assertEquals(1, fileItems.size()); FileItem file = fileItems.get(0); assertEquals("FiLe", file.getFieldName()); assertEquals("FOO.tab", file.getName()); } /** * This is what the browser does if you submit the form without choosing a file. */ @Test public void testEmptyFile() throws UnsupportedEncodingException, FileUploadException { List fileItems = parseUpload ("-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n" + "\r\n" + "\r\n" + "-----1234--\r\n"); assertEquals(1, fileItems.size()); FileItem file = fileItems.get(0); assertFalse(file.isFormField()); assertEquals("", file.getString()); assertEquals("", file.getName()); } /** * Internet Explorer 5 for the Mac has a bug where the carriage * return is missing on any boundary line immediately preceding * an input with type=image. (type=submit does not have the bug.) */ @Test public void testIE5MacBug() throws UnsupportedEncodingException, FileUploadException { List fileItems = parseUpload("-----1234\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\n" + // NOTE \r missing "Content-Disposition: form-data; name=\"submitName.x\"\r\n" + "\r\n" + "42\r\n" + "-----1234\n" + // NOTE \r missing "Content-Disposition: form-data; name=\"submitName.y\"\r\n" + "\r\n" + "21\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"field2\"\r\n" + "\r\n" + "fieldValue2\r\n" + "-----1234--\r\n"); assertEquals(4, fileItems.size()); FileItem field1 = fileItems.get(0); assertEquals("field1", field1.getFieldName()); assertTrue(field1.isFormField()); assertEquals("fieldValue", field1.getString()); FileItem submitX = fileItems.get(1); assertEquals("submitName.x", submitX.getFieldName()); assertTrue(submitX.isFormField()); assertEquals("42", submitX.getString()); FileItem submitY = fileItems.get(2); assertEquals("submitName.y", submitY.getFieldName()); assertTrue(submitY.isFormField()); assertEquals("21", submitY.getString()); FileItem field2 = fileItems.get(3); assertEquals("field2", field2.getFieldName()); assertTrue(field2.isFormField()); assertEquals("fieldValue2", field2.getString()); } /** * Test for FILEUPLOAD-62 */ @Test public void testFILEUPLOAD62() throws Exception { final String contentType = "multipart/form-data; boundary=AaB03x"; final String request = "--AaB03x\r\n" + "content-disposition: form-data; name=\"field1\"\r\n" + "\r\n" + "Joe Blow\r\n" + "--AaB03x\r\n" + "content-disposition: form-data; name=\"pics\"\r\n" + "Content-type: multipart/mixed; boundary=BbC04y\r\n" + "\r\n" + "--BbC04y\r\n" + "Content-disposition: attachment; filename=\"file1.txt\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "... contents of file1.txt ...\r\n" + "--BbC04y\r\n" + "Content-disposition: attachment; filename=\"file2.gif\"\r\n" + "Content-type: image/gif\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "...contents of file2.gif...\r\n" + "--BbC04y--\r\n" + "--AaB03x--"; List fileItems = parseUpload(request.getBytes("US-ASCII"), contentType); assertEquals(3, fileItems.size()); FileItem item0 = fileItems.get(0); assertEquals("field1", item0.getFieldName()); assertNull(item0.getName()); assertEquals("Joe Blow", new String(item0.get())); FileItem item1 = fileItems.get(1); assertEquals("pics", item1.getFieldName()); assertEquals("file1.txt", item1.getName()); assertEquals("... contents of file1.txt ...", new String(item1.get())); FileItem item2 = fileItems.get(2); assertEquals("pics", item2.getFieldName()); assertEquals("file2.gif", item2.getName()); assertEquals("...contents of file2.gif...", new String(item2.get())); } /** * Test for FILEUPLOAD-111 */ @Test public void testFoldedHeaders() throws IOException, FileUploadException { List fileItems = parseUpload("-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; \r\n" + "\tname=\"field\"\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\r\n" + "Content-Disposition: form-data;\r\n" + " name=\"multi\"\r\n" + "\r\n" + "value1\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value2\r\n" + "-----1234--\r\n"); assertEquals(4, fileItems.size()); FileItem file = fileItems.get(0); assertEquals("file", file.getFieldName()); assertFalse(file.isFormField()); assertEquals("This is the content of the file\n", file.getString()); assertEquals("text/whatever", file.getContentType()); assertEquals("foo.tab", file.getName()); FileItem field = fileItems.get(1); assertEquals("field", field.getFieldName()); assertTrue(field.isFormField()); assertEquals("fieldValue", field.getString()); FileItem multi0 = fileItems.get(2); assertEquals("multi", multi0.getFieldName()); assertTrue(multi0.isFormField()); assertEquals("value1", multi0.getString()); FileItem multi1 = fileItems.get(3); assertEquals("multi", multi1.getFieldName()); assertTrue(multi1.isFormField()); assertEquals("value2", multi1.getString()); } /** * Test case for */ @Test public void testFileUpload130() throws Exception { final String[] headerNames = new String[] { "SomeHeader", "OtherHeader", "YetAnotherHeader", "WhatAHeader" }; final String[] headerValues = new String[] { "present", "Is there", "Here", "Is That" }; List fileItems = parseUpload("-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + headerNames[0] + ": " + headerValues[0] + "\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; \r\n" + "\tname=\"field\"\r\n" + headerNames[1] + ": " + headerValues[1] + "\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\r\n" + "Content-Disposition: form-data;\r\n" + " name=\"multi\"\r\n" + headerNames[2] + ": " + headerValues[2] + "\r\n" + "\r\n" + "value1\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + headerNames[3] + ": " + headerValues[3] + "\r\n" + "\r\n" + "value2\r\n" + "-----1234--\r\n"); assertEquals(4, fileItems.size()); FileItem file = fileItems.get(0); assertHeaders(headerNames, headerValues, file, 0); FileItem field = fileItems.get(1); assertHeaders(headerNames, headerValues, field, 1); FileItem multi0 = fileItems.get(2); assertHeaders(headerNames, headerValues, multi0, 2); FileItem multi1 = fileItems.get(3); assertHeaders(headerNames, headerValues, multi1, 3); } /** * Test case for */ @Test public void parseParameterMap() throws Exception { String text = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"field\"\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value1\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value2\r\n" + "-----1234--\r\n"; byte[] bytes = text.getBytes("US-ASCII"); ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); HttpServletRequest request = new MockHttpServletRequest(bytes, CONTENT_TYPE); Map> mappedParameters = upload.parseParameterMap(request); assertTrue(mappedParameters.containsKey("file")); assertEquals(1, mappedParameters.get("file").size()); assertTrue(mappedParameters.containsKey("field")); assertEquals(1, mappedParameters.get("field").size()); assertTrue(mappedParameters.containsKey("multi")); assertEquals(2, mappedParameters.get("multi").size()); } private void assertHeaders(String[] pHeaderNames, String[] pHeaderValues, FileItem pItem, int pIndex) { for (int i = 0; i < pHeaderNames.length; i++) { final String value = pItem.getHeaders().getHeader(pHeaderNames[i]); if (i == pIndex) { assertEquals(pHeaderValues[i], value); } else { assertNull(value); } } } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/SizesTest.java100644 0 0 26050 12274737401 26355 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileUploadBase.FileUploadIOException; import org.apache.commons.fileupload.FileUploadBase.SizeException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.util.Streams; import org.junit.Test; /** * Unit test for items with varying sizes. * * @version $Id: SizesTest.java 1458684 2013-03-20 08:31:53Z simonetripodi $ */ public class SizesTest extends FileUploadTestCase { /** * Runs a test with varying file sizes. */ @Test public void testFileUpload() throws IOException, FileUploadException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int add = 16; int num = 0; for (int i = 0; i < 16384; i += add) { if (++add == 32) { add = 16; } String header = "-----1234\r\n" + "Content-Disposition: form-data; name=\"field" + (num++) + "\"\r\n" + "\r\n"; baos.write(header.getBytes("US-ASCII")); for (int j = 0; j < i; j++) { baos.write((byte) j); } baos.write("\r\n".getBytes("US-ASCII")); } baos.write("-----1234--\r\n".getBytes("US-ASCII")); List fileItems = parseUpload(baos.toByteArray()); Iterator fileIter = fileItems.iterator(); add = 16; num = 0; for (int i = 0; i < 16384; i += add) { if (++add == 32) { add = 16; } FileItem item = fileIter.next(); assertEquals("field" + (num++), item.getFieldName()); byte[] bytes = item.get(); assertEquals(i, bytes.length); for (int j = 0; j < i; j++) { assertEquals((byte) j, bytes[j]); } } assertTrue(!fileIter.hasNext()); } /** Checks, whether limiting the file size works. */ @Test public void testFileSizeLimit() throws IOException, FileUploadException { final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"; ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(-1); HttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); List fileItems = upload.parseRequest(req); assertEquals(1, fileItems.size()); FileItem item = fileItems.get(0); assertEquals("This is the content of the file\n", new String(item.get())); upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(40); req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); fileItems = upload.parseRequest(req); assertEquals(1, fileItems.size()); item = fileItems.get(0); assertEquals("This is the content of the file\n", new String(item.get())); upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(30); req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); try { upload.parseRequest(req); fail("Expected exception."); } catch (FileUploadBase.FileSizeLimitExceededException e) { assertEquals(30, e.getPermittedSize()); } } /** Checks, whether a faked Content-Length header is detected. */ @Test public void testFileSizeLimitWithFakedContentLength() throws IOException, FileUploadException { final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "Content-Length: 10\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"; ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(-1); HttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); List fileItems = upload.parseRequest(req); assertEquals(1, fileItems.size()); FileItem item = fileItems.get(0); assertEquals("This is the content of the file\n", new String(item.get())); upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(40); req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); fileItems = upload.parseRequest(req); assertEquals(1, fileItems.size()); item = fileItems.get(0); assertEquals("This is the content of the file\n", new String(item.get())); // provided Content-Length is larger than the FileSizeMax -> handled by ctor upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(5); req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); try { upload.parseRequest(req); fail("Expected exception."); } catch (FileUploadBase.FileSizeLimitExceededException e) { assertEquals(5, e.getPermittedSize()); } // provided Content-Length is wrong, actual content is larger -> handled by LimitedInputStream upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(15); req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); try { upload.parseRequest(req); fail("Expected exception."); } catch (FileUploadBase.FileSizeLimitExceededException e) { assertEquals(15, e.getPermittedSize()); } } /** Checks, whether the maxSize works. */ @Test public void testMaxSizeLimit() throws IOException, FileUploadException { final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "Content-Length: 10\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"; ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(-1); upload.setSizeMax(200); MockHttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); try { upload.parseRequest(req); fail("Expected exception."); } catch (FileUploadBase.SizeLimitExceededException e) { assertEquals(200, e.getPermittedSize()); } } @Test public void testMaxSizeLimitUnknownContentLength() throws IOException, FileUploadException { final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "Content-Length: 10\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"; ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setFileSizeMax(-1); upload.setSizeMax(300); // the first item should be within the max size limit // set the read limit to 10 to simulate a "real" stream // otherwise the buffer would be immediately filled MockHttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE); req.setContentLength(-1); req.setReadLimit(10); FileItemIterator it = upload.getItemIterator(req); assertTrue(it.hasNext()); FileItemStream item = it.next(); assertFalse(item.isFormField()); assertEquals("file1", item.getFieldName()); assertEquals("foo1.tab", item.getName()); try { InputStream stream = item.openStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Streams.copy(stream, baos, true); } catch (FileUploadIOException e) { fail(e.getMessage()); } // the second item is over the size max, thus we expect an error try { // the header is still within size max -> this shall still succeed assertTrue(it.hasNext()); } catch (SizeException e) { fail(); } item = it.next(); try { InputStream stream = item.openStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Streams.copy(stream, baos, true); fail(); } catch (FileUploadIOException e) { // expected } } } commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/StreamingTest.java100644 0 0 24044 12274737401 27212 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileUploadBase.IOFileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletRequestContext; import junit.framework.TestCase; /** * Unit test for items with varying sizes. * * @version $Id: StreamingTest.java 1454693 2013-03-09 12:30:27Z simonetripodi $ */ public class StreamingTest extends TestCase { /** * Tests a file upload with varying file sizes. */ public void testFileUpload() throws IOException, FileUploadException { byte[] request = newRequest(); List fileItems = parseUpload(request); Iterator fileIter = fileItems.iterator(); int add = 16; int num = 0; for (int i = 0; i < 16384; i += add) { if (++add == 32) { add = 16; } FileItem item = fileIter.next(); assertEquals("field" + (num++), item.getFieldName()); byte[] bytes = item.get(); assertEquals(i, bytes.length); for (int j = 0; j < i; j++) { assertEquals((byte) j, bytes[j]); } } assertTrue(!fileIter.hasNext()); } /** * Tests, whether an invalid request throws a proper * exception. */ public void testFileUploadException() throws IOException, FileUploadException { byte[] request = newRequest(); byte[] invalidRequest = new byte[request.length-11]; System.arraycopy(request, 0, invalidRequest, 0, request.length-11); try { parseUpload(invalidRequest); fail("Expected EndOfStreamException"); } catch (IOFileUploadException e) { assertTrue(e.getCause() instanceof MultipartStream.MalformedStreamException); } } /** * Tests, whether an IOException is properly delegated. */ public void testIOException() throws IOException { byte[] request = newRequest(); InputStream stream = new FilterInputStream(new ByteArrayInputStream(request)){ private int num; @Override public int read() throws IOException { if (++num > 123) { throw new IOException("123"); } return super.read(); } @Override public int read(byte[] pB, int pOff, int pLen) throws IOException { for (int i = 0; i < pLen; i++) { int res = read(); if (res == -1) { return i == 0 ? -1 : i; } pB[pOff+i] = (byte) res; } return pLen; } }; try { parseUpload(stream, request.length); fail("Expected IOException"); } catch (FileUploadException e) { assertTrue(e.getCause() instanceof IOException); assertEquals("123", e.getCause().getMessage()); } } /** * Test for FILEUPLOAD-135 */ public void testFILEUPLOAD135() throws IOException, FileUploadException { byte[] request = newShortRequest(); final ByteArrayInputStream bais = new ByteArrayInputStream(request); List fileItems = parseUpload(new InputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public int read(byte b[], int off, int len) throws IOException { return bais.read(b, off, Math.min(len, 3)); } }, request.length); Iterator fileIter = fileItems.iterator(); assertTrue(fileIter.hasNext()); FileItem item = fileIter.next(); assertEquals("field", item.getFieldName()); byte[] bytes = item.get(); assertEquals(3, bytes.length); assertEquals((byte)'1', bytes[0]); assertEquals((byte)'2', bytes[1]); assertEquals((byte)'3', bytes[2]); assertTrue(!fileIter.hasNext()); } private List parseUpload(byte[] bytes) throws FileUploadException { return parseUpload(new ByteArrayInputStream(bytes), bytes.length); } private FileItemIterator parseUpload(int pLength, InputStream pStream) throws FileUploadException, IOException { String contentType = "multipart/form-data; boundary=---1234"; FileUploadBase upload = new ServletFileUpload(); upload.setFileItemFactory(new DiskFileItemFactory()); HttpServletRequest request = new MockHttpServletRequest(pStream, pLength, contentType); return upload.getItemIterator(new ServletRequestContext(request)); } private List parseUpload(InputStream pStream, int pLength) throws FileUploadException { String contentType = "multipart/form-data; boundary=---1234"; FileUploadBase upload = new ServletFileUpload(); upload.setFileItemFactory(new DiskFileItemFactory()); HttpServletRequest request = new MockHttpServletRequest(pStream, pLength, contentType); List fileItems = upload.parseRequest(new ServletRequestContext(request)); return fileItems; } private String getHeader(String pField) { return "-----1234\r\n" + "Content-Disposition: form-data; name=\"" + pField + "\"\r\n" + "\r\n"; } private String getFooter() { return "-----1234--\r\n"; } private byte[] newShortRequest() throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final OutputStreamWriter osw = new OutputStreamWriter(baos, "US-ASCII"); osw.write(getHeader("field")); osw.write("123"); osw.write("\r\n"); osw.write(getFooter()); osw.close(); return baos.toByteArray(); } private byte[] newRequest() throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final OutputStreamWriter osw = new OutputStreamWriter(baos, "US-ASCII"); int add = 16; int num = 0; for (int i = 0; i < 16384; i += add) { if (++add == 32) { add = 16; } osw.write(getHeader("field" + (num++))); osw.flush(); for (int j = 0; j < i; j++) { baos.write((byte) j); } osw.write("\r\n"); } osw.write(getFooter()); osw.close(); return baos.toByteArray(); } /** * Tests, whether an {@link InvalidFileNameException} is thrown. */ public void testInvalidFileNameException() throws Exception { final String fileName = "foo.exe\u0000.png"; final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"field\"\r\n" + "\r\n" + "fieldValue\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value1\r\n" + "-----1234\r\n" + "Content-Disposition: form-data; name=\"multi\"\r\n" + "\r\n" + "value2\r\n" + "-----1234--\r\n"; final byte[] reqBytes = request.getBytes("US-ASCII"); FileItemIterator fileItemIter = parseUpload(reqBytes.length, new ByteArrayInputStream(reqBytes)); final FileItemStream fileItemStream = fileItemIter.next(); try { fileItemStream.getName(); fail("Expected exception"); } catch (InvalidFileNameException e) { assertEquals(fileName, e.getName()); assertTrue(e.getMessage().indexOf(fileName) == -1); assertTrue(e.getMessage().indexOf("foo.exe\\0.png") != -1); } List fileItems = parseUpload(reqBytes); final FileItem fileItem = fileItems.get(0); try { fileItem.getName(); fail("Expected exception"); } catch (InvalidFileNameException e) { assertEquals(fileName, e.getName()); assertTrue(e.getMessage().indexOf(fileName) == -1); assertTrue(e.getMessage().indexOf("foo.exe\\0.png") != -1); } } } ././@LongLink100644 0 0 156 12274740161 10261 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/Base64DecoderTestCase.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/Base64DecoderTest100644 0 0 13251 12274737401 30555 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.junit.Test; /** * @since 1.3 */ public final class Base64DecoderTestCase { private static final String US_ASCII_CHARSET = "US-ASCII"; /** * Tests RFC 4648 section 10 test vectors. *
    *
  • BASE64("") = ""
  • *
  • BASE64("f") = "Zg=="
  • *
  • BASE64("fo") = "Zm8="
  • *
  • BASE64("foo") = "Zm9v"
  • *
  • BASE64("foob") = "Zm9vYg=="
  • *
  • BASE64("fooba") = "Zm9vYmE="
  • *
  • BASE64("foobar") = "Zm9vYmFy"
  • *
* * @see
http://tools.ietf.org/html/rfc4648 */ @Test public void rfc4648Section10Decode() throws Exception { assertEncoded("", ""); assertEncoded("f", "Zg=="); assertEncoded("fo", "Zm8="); assertEncoded("foo", "Zm9v"); assertEncoded("foob", "Zm9vYg=="); assertEncoded("fooba", "Zm9vYmE="); assertEncoded("foobar", "Zm9vYmFy"); } /** * Test our decode with pad character in the middle. * Continues provided that the padding is in the correct place, * i.e. concatenated valid strings decode OK. */ @Test public void decodeWithInnerPad() throws Exception { assertEncoded("Hello WorldHello World", "SGVsbG8gV29ybGQ=SGVsbG8gV29ybGQ="); } /** * Ignores non-BASE64 bytes. */ @Test public void nonBase64Bytes() throws Exception { assertEncoded("Hello World", "S?G!V%sbG 8g\rV\t\n29ybGQ*="); } @Test(expected = IOException.class) public void truncatedString() throws Exception { final byte[] x = new byte[]{'n'}; Base64Decoder.decode(x, new ByteArrayOutputStream()); } @Test public void decodeTrailingJunk() throws Exception { assertEncoded("foobar", "Zm9vYmFy!!!"); } // If there are valid trailing Base64 chars, complain @Test public void decodeTrailing1() throws Exception { assertIOException("truncated", "Zm9vYmFy1"); } // If there are valid trailing Base64 chars, complain @Test public void decodeTrailing2() throws Exception { assertIOException("truncated", "Zm9vYmFy12"); } // If there are valid trailing Base64 chars, complain @Test public void decodeTrailing3() throws Exception { assertIOException("truncated", "Zm9vYmFy123"); } @Test public void badPadding() throws Exception { assertIOException("incorrect padding, 4th byte", "Zg=a"); } @Test public void badPaddingLeading1() throws Exception { assertIOException("incorrect padding, first two bytes cannot be padding", "=A=="); } @Test public void badPaddingLeading2() throws Exception { assertIOException("incorrect padding, first two bytes cannot be padding", "===="); } // This input causes java.lang.ArrayIndexOutOfBoundsException: 1 // in the Java 6 method DatatypeConverter.parseBase64Binary(String) // currently reported as truncated (the last chunk consists just of '=') @Test public void badLength() throws Exception { assertIOException("truncated", "Zm8=="); } // These inputs cause java.lang.ArrayIndexOutOfBoundsException // in the Java 6 method DatatypeConverter.parseBase64Binary(String) // The non-ASCII characters should just be ignored @Test public void nonASCIIcharacter() throws Exception { assertEncoded("f","Zg=="); // A-grave assertEncoded("f","Zg=\u0100="); } private static void assertEncoded(String clearText, String encoded) throws Exception { byte[] expected = clearText.getBytes(US_ASCII_CHARSET); ByteArrayOutputStream out = new ByteArrayOutputStream(encoded.length()); byte[] encodedData = encoded.getBytes(US_ASCII_CHARSET); Base64Decoder.decode(encodedData, out); byte[] actual = out.toByteArray(); assertArrayEquals(expected, actual); } private static void assertIOException(String messageText, String encoded) throws UnsupportedEncodingException { ByteArrayOutputStream out = new ByteArrayOutputStream(encoded.length()); byte[] encodedData = encoded.getBytes(US_ASCII_CHARSET); try { Base64Decoder.decode(encodedData, out); fail("Expected IOException"); } catch (IOException e) { String em = e.getMessage(); assertTrue("Expected to find " + messageText + " in '" + em + "'",em.contains(messageText)); } } } ././@LongLink100644 0 0 154 12274740161 10257 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/MimeUtilityTestCase.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/MimeUtilityTestCa100644 0 0 5154 12274737401 30745 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import static org.junit.Assert.assertEquals; import java.io.UnsupportedEncodingException; import org.apache.commons.fileupload.util.mime.MimeUtility; import org.junit.Test; /** * Use the online MimeHeadersDecoder * to validate expected values. * * @since 1.3 */ public final class MimeUtilityTestCase { @Test public void noNeedToDecode() throws Exception { assertEncoded("abc", "abc"); } @Test public void decodeUtf8QuotedPrintableEncoded() throws Exception { assertEncoded(" h! u !!!", "=?UTF-8?Q?_h=C3=A9!_=C3=A0=C3=A8=C3=B4u_!!!?="); } @Test public void decodeUtf8Base64Encoded() throws Exception { assertEncoded(" h! u !!!", "=?UTF-8?B?IGjDqSEgw6DDqMO0dSAhISE=?="); } @Test public void decodeIso88591Base64Encoded() throws Exception { assertEncoded("If you can read this you understand the example.", "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n"); } @Test public void decodeIso88591Base64EncodedWithWhiteSpace() throws Exception { assertEncoded("If you can read this you understand the example.", "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\t \r\n =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n"); } private static void assertEncoded(String expected, String encoded) throws Exception { assertEquals(expected, MimeUtility.decodeText(encoded)); } @Test(expected=UnsupportedEncodingException.class) public void decodeInvalidEncoding() throws Exception { MimeUtility.decodeText("=?invalid?B?xyz-?="); } } ././@LongLink100644 0 0 167 12274740161 10263 Lustar 0 0 commons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoderTestCase.javacommons-fileupload-1.3.1-src/src/test/java/org/apache/commons/fileupload/util/mime/QuotedPrintableDe100644 0 0 10574 12274737401 30763 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.fileupload.util.mime; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.fail; import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.junit.Test; /** * @since 1.3 */ public final class QuotedPrintableDecoderTestCase { private static final String US_ASCII_CHARSET = "US-ASCII"; @Test public void emptyDecode() throws Exception { assertEncoded("", ""); } @Test public void plainDecode() throws Exception { // spaces are allowed in encoded data // There are special rules for trailing spaces; these are not currently implemented. assertEncoded("The quick brown fox jumps over the lazy dog.", "The quick brown fox jumps over the lazy dog."); } @Test public void basicEncodeDecode() throws Exception { assertEncoded("= Hello there =\r\n", "=3D Hello there =3D=0D=0A"); } @Test public void invalidQuotedPrintableEncoding() throws Exception { assertIOException("truncated escape sequence", "YWJjMTIzXy0uKn4hQCMkJV4mKCkre31cIlxcOzpgLC9bXQ=="); } @Test public void unsafeDecode() throws Exception { assertEncoded("=\r\n", "=3D=0D=0A"); } @Test public void unsafeDecodeLowerCase() throws Exception { assertEncoded("=\r\n", "=3d=0d=0a"); } @Test(expected = IOException.class) public void invalidCharDecode() throws Exception { assertEncoded("=\r\n", "=3D=XD=XA"); } /** * This is NOT supported by Commons-Codec, see CODEC-121. * * @throws Exception * @see CODEC-121 */ @Test public void softLineBreakDecode() throws Exception { assertEncoded("If you believe that truth=beauty, then surely mathematics is the most beautiful branch of philosophy.", "If you believe that truth=3Dbeauty, then surely=20=\r\nmathematics is the most beautiful branch of philosophy."); } @Test public void invalidSoftBreak1() throws Exception { assertIOException("CR must be followed by LF", "=\r\r"); } @Test public void invalidSoftBreak2() throws Exception { assertIOException("CR must be followed by LF", "=\rn"); } @Test public void truncatedEscape() throws Exception { assertIOException("truncated", "=1"); } private static void assertEncoded(String clearText, String encoded) throws Exception { byte[] expected = clearText.getBytes(US_ASCII_CHARSET); ByteArrayOutputStream out = new ByteArrayOutputStream(encoded.length()); byte[] encodedData = encoded.getBytes(US_ASCII_CHARSET); QuotedPrintableDecoder.decode(encodedData, out); byte[] actual = out.toByteArray(); assertArrayEquals(expected, actual); } private static void assertIOException(String messageText, String encoded) throws UnsupportedEncodingException { ByteArrayOutputStream out = new ByteArrayOutputStream(encoded.length()); byte[] encodedData = encoded.getBytes(US_ASCII_CHARSET); try { QuotedPrintableDecoder.decode(encodedData, out); fail("Expected IOException"); } catch (IOException e) { String em = e.getMessage(); assertTrue("Expected to find " + messageText + " in '" + em + "'",em.contains(messageText)); } } }