├── src ├── media │ └── logo.xcf ├── site │ ├── resources │ │ ├── images │ │ │ └── logo.png │ │ ├── profile.jacoco │ │ └── download_fileupload.cgi │ ├── xdoc │ │ ├── customizing.xml │ │ ├── overview.xml │ │ ├── streaming.xml │ │ └── index.xml │ └── site.xml ├── checkstyle │ ├── license-header.txt │ └── checkstyle-suppressions.xml ├── main │ └── assembly │ │ ├── src.xml │ │ └── bin.xml ├── changes │ └── release-notes.vm └── conf │ └── pmd-ruleset.xml ├── .mvn └── .gitignore ├── NOTICE.txt ├── .gitignore ├── .gitattributes ├── SECURITY.md ├── CODE_OF_CONDUCT.md ├── .github ├── GH-ROBOTS.txt ├── dependabot.yml ├── workflows │ ├── dependency-review.yml │ ├── maven.yml │ ├── scorecards-analysis.yml │ └── codeql-analysis.yml └── pull_request_template.md ├── commons-fileupload2-core └── src │ ├── site │ └── resources │ │ └── profile.jacoco │ ├── test │ └── java │ │ └── org │ │ └── apache │ │ └── commons │ │ └── fileupload2 │ │ └── core │ │ ├── Constants.java │ │ ├── DiskFileItemFactoryTest.java │ │ ├── AbstractTest.java │ │ ├── AbstractFileUploadWrapper.java │ │ ├── MimeUtilityTestCase.java │ │ ├── RFC2231UtilityTestCase.java │ │ ├── FileItemHeadersTest.java │ │ ├── QuotedPrintableDecoderTestCase.java │ │ └── MultipartStreamTest.java │ └── main │ └── java │ └── org │ └── apache │ └── commons │ └── fileupload2 │ └── core │ ├── FileUploadFileCountLimitException.java │ ├── ProgressListener.java │ ├── FileItemHeadersProvider.java │ ├── FileUploadException.java │ ├── FileUploadContentTypeException.java │ ├── FileUploadSizeException.java │ ├── FileUploadByteCountLimitException.java │ ├── RequestContext.java │ ├── FileItemHeaders.java │ ├── FileItemHeadersImpl.java │ ├── package-info.java │ ├── AbstractRequestContext.java │ ├── FileItemInput.java │ ├── QuotedPrintableDecoder.java │ └── FileItemInputIterator.java ├── commons-fileupload2-javax └── src │ ├── site │ └── resources │ │ └── profile.jacoco │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── commons │ │ └── fileupload2 │ │ └── javax │ │ ├── JavaxServletDiskFileUpload.java │ │ ├── package-info.java │ │ ├── JavaxServletRequestContext.java │ │ └── JavaxFileCleaner.java │ └── test │ └── java │ └── org │ └── apache │ └── commons │ └── fileupload2 │ └── javax │ ├── JavaxSizesDiskTest.java │ ├── JavaxProgressListenerDiskTest.java │ ├── JavaxSizesTest.java │ ├── JavaxProgressListenerTest.java │ ├── JavaxHttpServletRequestFactory.java │ ├── JavaxStreamingDiskTest.java │ └── JavaxStreamingTest.java ├── commons-fileupload2-portlet └── src │ ├── site │ └── resources │ │ └── profile.jacoco │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── commons │ │ └── fileupload2 │ │ └── portlet │ │ ├── package-info.java │ │ └── JavaxPortletRequestContext.java │ └── test │ └── java │ └── org │ └── apache │ └── commons │ └── fileupload2 │ └── portlet │ └── JavaxPortletFileUploadTest.java ├── commons-fileupload2-jakarta-servlet5 └── src │ ├── site │ └── resources │ │ └── profile.jacoco │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── commons │ │ └── fileupload2 │ │ └── jakarta │ │ └── servlet5 │ │ ├── package-info.java │ │ ├── JakartaServletDiskFileUpload.java │ │ ├── JakartaServletRequestContext.java │ │ └── JakartaFileCleaner.java │ └── test │ └── java │ └── org │ └── apache │ └── commons │ └── fileupload2 │ └── jakarta │ └── servlet5 │ ├── JakartaSizesDiskTest.java │ ├── JakartaSizesTest.java │ ├── JakartaProgressListenerDiskTest.java │ ├── JakartaProgressListenerTest.java │ ├── JakartaStreamingDiskTest.java │ └── JakartaStreamingTest.java ├── commons-fileupload2-jakarta-servlet6 └── src │ ├── site │ └── resources │ │ └── profile.jacoco │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── commons │ │ └── fileupload2 │ │ └── jakarta │ │ └── servlet6 │ │ ├── package-info.java │ │ ├── JakartaServletDiskFileUpload.java │ │ ├── JakartaServletRequestContext.java │ │ └── JakartaFileCleaner.java │ └── test │ └── java │ └── org │ └── apache │ └── commons │ └── fileupload2 │ └── jakarta │ └── servlet6 │ ├── JakartaSizesDiskTest.java │ ├── JakartaSizesTest.java │ ├── JakartaProgressListenerDiskTest.java │ ├── JakartaProgressListenerTest.java │ ├── JakartaStreamingDiskTest.java │ └── JakartaStreamingTest.java ├── .checkstyle ├── .asf.yaml ├── commons-fileupload2-distribution └── src │ └── assembly │ ├── src.xml │ └── bin.xml └── spotbugs-exclude-filter.xml /src/media/logo.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/commons-fileupload/HEAD/src/media/logo.xcf -------------------------------------------------------------------------------- /src/site/resources/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/commons-fileupload/HEAD/src/site/resources/images/logo.png -------------------------------------------------------------------------------- /.mvn/.gitignore: -------------------------------------------------------------------------------- 1 | # Nothing to ignore here. 2 | # This file is only here, to make Git create the directory, thereby making Maven 4 happy. 3 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Apache Commons FileUpload 2 | Copyright 2002-2025 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (https://www.apache.org/). 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.code-workspace 2 | *.iml 3 | *.iws 4 | .checkstyle 5 | .classpath 6 | .DS_Store 7 | .externalToolBuilders/ 8 | .history/ 9 | .idea/ 10 | .project 11 | .settings/ 12 | .svn/ 13 | .vscode/ 14 | /derby.log 15 | /jackrabbit.log_IS_UNDEFINED 16 | /jetty.log_IS_UNDEFINED 17 | **/bin/ 18 | maven-eclipse.xml 19 | target/ 20 | site-content/ 21 | 22 | # NetBeans files 23 | nb-configuration.xml 24 | nbactions.xml 25 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | * text=auto 17 | *.patch -text 18 | -------------------------------------------------------------------------------- /src/checkstyle/license-header.txt: -------------------------------------------------------------------------------- 1 | /\*\s* 2 | \*\s*Licensed to the Apache Software Foundation \(ASF\) under one or more 3 | \*\s*contributor license agreements. See the NOTICE file distributed with 4 | \*\s*this work for additional information regarding copyright ownership\. 5 | \*\s*The ASF licenses this file to You under the Apache License, Version 2\.0 6 | \*\s*\(the "License"\); you may not use this file except in compliance with 7 | \*\s*the License\. You may obtain a copy of the License at 8 | \*\s* 9 | \*\s*http://www\.apache\.org/licenses/LICENSE\-2\.0 10 | \*\s* 11 | \*\s*Unless required by applicable law or agreed to in writing, software 12 | \*\s*distributed under the License is distributed on an "AS IS" BASIS, 13 | \*\s*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. 14 | \*\s*See the License for the specific language governing permissions and 15 | \*\s*limitations under the License\. 16 | \*/\s* 17 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 17 | The Apache Commons security page is [https://commons.apache.org/security.html](https://commons.apache.org/security.html). 18 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 17 | The Apache code of conduct page is [https://www.apache.org/foundation/policies/conduct.html](https://www.apache.org/foundation/policies/conduct.html). 18 | -------------------------------------------------------------------------------- /.github/GH-ROBOTS.txt: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Keeps on creating FUD PRs in test code 17 | # Does not follow Apache disclosure policies 18 | User-agent: JLLeitschuh/security-research 19 | Disallow: * 20 | -------------------------------------------------------------------------------- /src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /commons-fileupload2-portlet/src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /src/site/resources/download_fileupload.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | 19 | # Just call the standard mirrors.cgi script. It will use download.html 20 | # as the input template. 21 | exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $* 22 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/site/resources/profile.jacoco: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ----------------------------------------------------------------------------- 16 | # 17 | # Empty file used to automatically trigger JaCoCo profile from commons parent pom 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | version: 2 17 | updates: 18 | - package-ecosystem: "maven" 19 | directory: "/" 20 | schedule: 21 | interval: "weekly" 22 | day: "friday" 23 | - package-ecosystem: "github-actions" 24 | directory: "/" 25 | schedule: 26 | interval: "weekly" 27 | day: "friday" 28 | -------------------------------------------------------------------------------- /src/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Constants used for testing. 21 | */ 22 | public final class Constants { 23 | 24 | /** 25 | * The content type used in several tests. 26 | */ 27 | public static final String CONTENT_TYPE = "multipart/form-data; boundary=---1234"; 28 | 29 | private Constants() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: 'Dependency Review' 19 | on: [pull_request] 20 | 21 | permissions: 22 | contents: read 23 | 24 | jobs: 25 | dependency-review: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: 'Checkout Repository' 29 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 30 | - name: 'Dependency Review PR' 31 | uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 32 | -------------------------------------------------------------------------------- /src/site/xdoc/customizing.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | 22 | 23 | Customizing FileUpload 24 | Martin Cooper 25 | 26 | 27 | 28 |
29 |

TODO: Document usage of factories and subclassing for customization.

30 |
31 | 32 | 33 |
34 | -------------------------------------------------------------------------------- /.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.asf.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | github: 17 | description: "Apache Commons FileUpload is a robust, high-performance, file upload capability to your servlets and web applications" 18 | homepage: https://commons.apache.org/fileupload/ 19 | labels: 20 | - java 21 | - fileupload 22 | - upload 23 | - apache 24 | 25 | notifications: 26 | commits: commits@commons.apache.org 27 | issues: issues@commons.apache.org 28 | pullrequests: issues@commons.apache.org 29 | jira_options: link label 30 | jobs: notifications@commons.apache.org 31 | # commits_bot_dependabot: dependabot@commons.apache.org 32 | issues_bot_dependabot: dependabot@commons.apache.org 33 | pullrequests_bot_dependabot: dependabot@commons.apache.org 34 | issues_bot_codecov-commenter: notifications@commons.apache.org 35 | pullrequests_bot_codecov-commenter: notifications@commons.apache.org 36 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileUploadFileCountLimitException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Signals that a request contains more files than the specified limit. 21 | */ 22 | public class FileUploadFileCountLimitException extends FileUploadSizeException { 23 | 24 | private static final long serialVersionUID = 2; 25 | 26 | /** 27 | * Constructs an instance. 28 | * 29 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 30 | * @param limit The limit that was exceeded. 31 | * @param actual The actual value. 32 | */ 33 | public FileUploadFileCountLimitException(final String message, final long limit, final long actual) { 34 | super(message, limit, actual); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/ProgressListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Receives progress information. May be used to display a progress bar. 21 | */ 22 | @FunctionalInterface 23 | public interface ProgressListener { 24 | 25 | /** 26 | * Nop implementation. 27 | */ 28 | ProgressListener NOP = (bytesRead, contentLength, items) -> { 29 | // nop 30 | }; 31 | 32 | /** 33 | * Updates the listeners status information. 34 | * 35 | * @param bytesRead The total number of bytes, which have been read so far. 36 | * @param contentLength The total number of bytes, which are being read. May be -1, if this number is unknown. 37 | * @param items The number of the field, which is currently being read. (0 = no item so far, 1 = first item is being read, ...) 38 | */ 39 | void update(long bytesRead, long contentLength, int items); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletDiskFileUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.commons.fileupload2.javax; 19 | 20 | import org.apache.commons.fileupload2.core.DiskFileItem; 21 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 22 | 23 | /** 24 | * A JavaxServletFileUpload for {@link DiskFileItem} and {@link DiskFileItemFactory}. 25 | */ 26 | public class JavaxServletDiskFileUpload extends JavaxServletFileUpload { 27 | 28 | /** 29 | * Constructs a new instance. 30 | */ 31 | public JavaxServletDiskFileUpload() { 32 | super(DiskFileItemFactory.builder().get()); 33 | } 34 | 35 | /** 36 | * Constructs a new instance. 37 | * 38 | * @param fileItemFactory The factory to use for creating file items. 39 | */ 40 | public JavaxServletDiskFileUpload(final DiskFileItemFactory fileItemFactory) { 41 | super(fileItemFactory); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | *

20 | * An implementation of {@link org.apache.commons.fileupload2.core.AbstractFileUpload} for use in servlets conforming to the namespace {@code jakarta.servlet}. 21 | * 22 | *

23 | *

24 | * The following code fragment demonstrates typical usage. 25 | *

26 | * 27 | *
{@code
28 |  * DiskFileItemFactory factory = DiskFileItemFactory().builder().get();
29 |  * // Configure the factory here, if desired.
30 |  * JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);
31 |  * // Configure the uploader here, if desired.
32 |  * List fileItems = upload.parseRequest(request);
33 |  * }
34 | *

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

38 | */ 39 | package org.apache.commons.fileupload2.jakarta.servlet5; 40 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | *

20 | * An implementation of {@link org.apache.commons.fileupload2.core.AbstractFileUpload} for use in servlets conforming to the namespace {@code jakarta.servlet}. 21 | * 22 | *

23 | *

24 | * The following code fragment demonstrates typical usage. 25 | *

26 | * 27 | *
{@code
28 |  * DiskFileItemFactory factory = DiskFileItemFactory().builder().get();
29 |  * // Configure the factory here, if desired.
30 |  * JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);
31 |  * // Configure the uploader here, if desired.
32 |  * List fileItems = upload.parseRequest(request);
33 |  * }
34 | *

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

38 | */ 39 | package org.apache.commons.fileupload2.jakarta.servlet6; 40 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletDiskFileUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.commons.fileupload2.jakarta.servlet5; 19 | 20 | import org.apache.commons.fileupload2.core.DiskFileItem; 21 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 22 | 23 | /** 24 | * A JakartaServletFileUpload for {@link DiskFileItem} and {@link DiskFileItemFactory}. 25 | */ 26 | public class JakartaServletDiskFileUpload extends JakartaServletFileUpload { 27 | 28 | /** 29 | * Constructs a new instance. 30 | */ 31 | public JakartaServletDiskFileUpload() { 32 | super(DiskFileItemFactory.builder().get()); 33 | } 34 | 35 | /** 36 | * Constructs a new instance. 37 | * 38 | * @param fileItemFactory The factory to use for creating file items. 39 | */ 40 | public JakartaServletDiskFileUpload(final DiskFileItemFactory fileItemFactory) { 41 | super(fileItemFactory); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletDiskFileUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.commons.fileupload2.jakarta.servlet6; 19 | 20 | import org.apache.commons.fileupload2.core.DiskFileItem; 21 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 22 | 23 | /** 24 | * A JakartaServletFileUpload for {@link DiskFileItem} and {@link DiskFileItemFactory}. 25 | */ 26 | public class JakartaServletDiskFileUpload extends JakartaServletFileUpload { 27 | 28 | /** 29 | * Constructs a new instance. 30 | */ 31 | public JakartaServletDiskFileUpload() { 32 | super(DiskFileItemFactory.builder().get()); 33 | } 34 | 35 | /** 36 | * Constructs a new instance. 37 | * 38 | * @param fileItemFactory The factory to use for creating file items. 39 | */ 40 | public JakartaServletDiskFileUpload(final DiskFileItemFactory fileItemFactory) { 41 | super(fileItemFactory); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/assembly/src.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | src 22 | 23 | tar.gz 24 | zip 25 | 26 | ${project.build.finalName}-src 27 | 28 | 29 | ${basedir} 30 | 31 | **/.classpath 32 | **/.project 33 | **/.settings/ 34 | **/.checkstyle/ 35 | **/doap_*.rdf 36 | **/bin/ 37 | **/.externalToolBuilders/ 38 | **/${project.build.directory}/ 39 | **/download*.cgi 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemHeadersProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Provides access to headers. 21 | * 22 | * @param The FileItemHeadersProvider type. 23 | * @see FileItem 24 | * @see FileItemInput 25 | */ 26 | public interface FileItemHeadersProvider> { 27 | 28 | /** 29 | * Gets the collection of headers defined locally within this item. 30 | * 31 | * @return the {@link FileItemHeaders} present for this item. 32 | */ 33 | FileItemHeaders getHeaders(); 34 | 35 | /** 36 | * Sets the headers read from within an item. Implementations of {@link FileItem} or {@link FileItemInput} should implement this interface to be able to get 37 | * the raw headers found within the item header block. 38 | * 39 | * @param headers the instance that holds onto the headers for this instance. 40 | * @return {@code this} instance. 41 | */ 42 | T setHeaders(FileItemHeaders headers); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-distribution/src/assembly/src.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | src 22 | 23 | tar.gz 24 | zip 25 | 26 | 27 | 28 | ${basedir}/.. 29 | 30 | **/.classpath 31 | **/.project 32 | **/.settings/ 33 | **/.checkstyle/ 34 | **/doap_*.rdf 35 | **/bin/ 36 | **/.externalToolBuilders/ 37 | **/${project.build.directory}/ 38 | **/download*.cgi 39 | **/site-content/ 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxSizesDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JavaxSizesDiskTest extends AbstractSizesTest { 31 | 32 | @Override 33 | protected JavaxServletDiskFileUpload newFileUpload() { 34 | return new JavaxServletDiskFileUpload(); 35 | } 36 | 37 | @Override 38 | protected JavaxMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 39 | final int readLimit) { 40 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | bin 22 | 23 | tar.gz 24 | zip 25 | 26 | ${project.build.finalName}-bin 27 | true 28 | 29 | 30 | 31 | LICENSE.txt 32 | NOTICE.txt 33 | RELEASE-NOTES.txt 34 | 35 | 36 | 37 | target 38 | 39 | 40 | *.jar 41 | 42 | 43 | 44 | target/site/apidocs 45 | apidocs 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaSizesDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaSizesDiskTest extends AbstractSizesTest { 31 | 32 | @Override 33 | protected JakartaServletDiskFileUpload newFileUpload() { 34 | return new JakartaServletDiskFileUpload(); 35 | } 36 | 37 | @Override 38 | protected JakartaMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 39 | final int readLimit) { 40 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaSizesDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaSizesDiskTest extends AbstractSizesTest { 31 | 32 | @Override 33 | protected JakartaServletDiskFileUpload newFileUpload() { 34 | return new JakartaServletDiskFileUpload(); 35 | } 36 | 37 | @Override 38 | protected JakartaMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 39 | final int readLimit) { 40 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | Thanks for your contribution to [Apache Commons](https://commons.apache.org/)! Your help is appreciated! 21 | 22 | Before you push a pull request, review this list: 23 | 24 | - [ ] Read the [contribution guidelines](CONTRIBUTING.md) for this project. 25 | - [ ] Read the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) if you use Artificial Intelligence (AI). 26 | - [ ] I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute? 27 | - [ ] Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself. 28 | - [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice. 29 | - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. 30 | - [ ] Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process. 31 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxProgressListenerDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | import org.apache.commons.fileupload2.core.ProgressListener; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JavaxProgressListenerDiskTest 32 | extends AbstractProgressListenerTest { 33 | 34 | @Override 35 | protected JavaxServletDiskFileUpload newFileUpload() { 36 | return new JavaxServletDiskFileUpload(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | *

20 | * An implementation of {@link org.apache.commons.fileupload2.core.AbstractFileUpload} for use in servlets conforming to JSR 53. This implementation requires 21 | * only access to the servlet's current {@code HttpServletRequest} instance, and a suitable {@link org.apache.commons.fileupload2.core.FileItemFactory} 22 | * implementation, such as {@link org.apache.commons.fileupload2.core.DiskFileItemFactory}. 23 | *

24 | *

25 | * The following code fragment demonstrates typical usage. 26 | *

27 | * 28 | *
{@code
29 |  * DiskFileItemFactory factory = DiskFileItemFactory().builder().get();
30 |  * // Configure the factory here, if desired.
31 |  * ServletFileUpload upload = new ServletFileUpload(factory);
32 |  * // Configure the uploader here, if desired.
33 |  * List fileItems = upload.parseRequest(request);
34 |  * }
35 | *

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

39 | */ 40 | package org.apache.commons.fileupload2.javax; 41 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxSizesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JavaxSizesTest 31 | extends AbstractSizesTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected JavaxServletFileUpload newFileUpload() { 35 | return new JavaxServletFileUpload<>(DiskFileItemFactory.builder().get()); 36 | } 37 | 38 | @Override 39 | protected JavaxMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 40 | final int readLimit) { 41 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | *

20 | * An implementation of {@link org.apache.commons.fileupload2.core.AbstractFileUpload} for use in portlets conforming to JSR 168. This implementation requires 21 | * only access to the portlet's current {@code ActionRequest} instance, and a suitable {@link org.apache.commons.fileupload2.core.FileItemFactory} 22 | * implementation, such as {@link org.apache.commons.fileupload2.core.DiskFileItemFactory}. 23 | *

24 | *

25 | * The following code fragment demonstrates typical usage. 26 | *

27 | * 28 | *
{@code
29 |  * DiskFileItemFactory factory = DiskFileItemFactory().builder().get();
30 |  * // Configure the factory here, if desired.
31 |  * PortletFileUpload upload = new PortletFileUpload(factory);
32 |  * // Configure the uploader here, if desired.
33 |  * List fileItems = upload.parseRequest(request);
34 |  * }
35 | *

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

39 | */ 40 | package org.apache.commons.fileupload2.portlet; 41 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | name: Java CI 17 | 18 | on: 19 | push: 20 | branches: [ master ] 21 | pull_request: 22 | branches: [ master ] 23 | 24 | permissions: 25 | contents: read 26 | 27 | jobs: 28 | build: 29 | 30 | runs-on: ubuntu-latest 31 | continue-on-error: ${{ matrix.experimental }} 32 | strategy: 33 | matrix: 34 | java: [ 11, 17, 21, 25 ] 35 | experimental: [false] 36 | include: 37 | - java: 26-ea 38 | experimental: true 39 | 40 | steps: 41 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 42 | with: 43 | persist-credentials: false 44 | - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 45 | with: 46 | path: ~/.m2/repository 47 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 48 | restore-keys: | 49 | ${{ runner.os }}-maven- 50 | - name: Set up JDK ${{ matrix.java }} 51 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 52 | with: 53 | distribution: 'temurin' 54 | java-version: ${{ matrix.java }} 55 | - name: Build with Maven 56 | run: mvn --errors --show-version --batch-mode --no-transfer-progress 57 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxProgressListenerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | import org.apache.commons.fileupload2.core.ProgressListener; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JavaxProgressListenerTest 32 | extends AbstractProgressListenerTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 33 | 34 | @Override 35 | protected JavaxServletFileUpload newFileUpload() { 36 | return new JavaxServletFileUpload<>(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaSizesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaSizesTest 31 | extends AbstractSizesTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected JakartaServletFileUpload newFileUpload() { 35 | return new JakartaServletFileUpload<>(DiskFileItemFactory.builder().get()); 36 | } 37 | 38 | @Override 39 | protected JakartaMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 40 | final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaSizesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractSizesTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaSizesTest 31 | extends AbstractSizesTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected JakartaServletFileUpload newFileUpload() { 35 | return new JakartaServletFileUpload<>(DiskFileItemFactory.builder().get()); 36 | } 37 | 38 | @Override 39 | protected JakartaMockHttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, 40 | final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaProgressListenerDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | import org.apache.commons.fileupload2.core.ProgressListener; 25 | 26 | import jakarta.servlet.http.HttpServletRequest; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JakartaProgressListenerDiskTest extends 32 | AbstractProgressListenerTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 33 | 34 | @Override 35 | protected JakartaServletDiskFileUpload newFileUpload() { 36 | return new JakartaServletDiskFileUpload(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaProgressListenerDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | import org.apache.commons.fileupload2.core.ProgressListener; 25 | 26 | import jakarta.servlet.http.HttpServletRequest; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JakartaProgressListenerDiskTest extends 32 | AbstractProgressListenerTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 33 | 34 | @Override 35 | protected JakartaServletDiskFileUpload newFileUpload() { 36 | return new JakartaServletDiskFileUpload(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/DiskFileItemFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertFalse; 20 | import static org.junit.jupiter.api.Assertions.assertNotNull; 21 | import static org.junit.jupiter.api.Assertions.assertSame; 22 | 23 | import org.apache.commons.fileupload2.core.FileItemFactory.AbstractFileItemBuilder; 24 | import org.junit.jupiter.api.Test; 25 | 26 | /** 27 | * Tests for {@link DiskFileItem}. 28 | */ 29 | class DiskFileItemFactoryTest { 30 | 31 | @Test 32 | void testHeaders() { 33 | final var factory = DiskFileItemFactory.builder().get(); 34 | final var fileItemBuilder = factory.fileItemBuilder(); 35 | assertNotNull(fileItemBuilder.getFileItemHeaders()); 36 | final var fileItem = fileItemBuilder.get(); 37 | assertNotNull(fileItem.getHeaders(), "Missing default headers (empty)"); 38 | assertFalse(fileItem.getHeaders().getHeaderNames().hasNext()); 39 | final var fileItemHeaders = AbstractFileItemBuilder.newFileItemHeaders(); 40 | assertNotNull(fileItemHeaders); 41 | fileItem.setHeaders(fileItemHeaders); 42 | assertSame(fileItemHeaders, fileItem.getHeaders()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaProgressListenerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | import org.apache.commons.fileupload2.core.ProgressListener; 25 | 26 | import jakarta.servlet.http.HttpServletRequest; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JakartaProgressListenerTest extends 32 | AbstractProgressListenerTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 33 | 34 | @Override 35 | protected JakartaServletFileUpload newFileUpload() { 36 | return new JakartaServletFileUpload<>(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaProgressListenerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractProgressListenerTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | import org.apache.commons.fileupload2.core.ProgressListener; 25 | 26 | import jakarta.servlet.http.HttpServletRequest; 27 | 28 | /** 29 | * Tests the {@link ProgressListener}. 30 | */ 31 | class JakartaProgressListenerTest extends 32 | AbstractProgressListenerTest, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 33 | 34 | @Override 35 | protected JakartaServletFileUpload newFileUpload() { 36 | return new JakartaServletFileUpload<>(); 37 | } 38 | 39 | @Override 40 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 41 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /commons-fileupload2-distribution/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 17 | 20 | bin 21 | 22 | tar.gz 23 | zip 24 | 25 | false 26 | 27 | 28 | 29 | org.apache.commons:commons-fileupload2-core 30 | org.apache.commons:commons-fileupload2-jakarta-servlet5 31 | org.apache.commons:commons-fileupload2-jakarta-servlet6 32 | org.apache.commons:commons-fileupload2-javax 33 | org.apache.commons:commons-fileupload2-portlet 34 | 35 | false 36 | 37 | 38 | 39 | 40 | .. 41 | 42 | LICENSE.txt 43 | NOTICE.txt 44 | RELEASE-NOTES.txt 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxHttpServletRequestFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import javax.servlet.http.HttpServletRequest; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractFileUpload; 22 | 23 | final class JavaxHttpServletRequestFactory { 24 | 25 | public static HttpServletRequest createHttpServletRequestWithNullContentType() { 26 | final var requestData = "foobar".getBytes(); 27 | return new JavaxMockHttpServletRequest(requestData, null); 28 | } 29 | 30 | static public HttpServletRequest createInvalidHttpServletRequest() { 31 | final var requestData = "foobar".getBytes(); 32 | return new JavaxMockHttpServletRequest(requestData, AbstractFileUpload.MULTIPART_FORM_DATA); 33 | } 34 | 35 | public static HttpServletRequest createValidHttpServletRequest(final String[] strFileNames) { 36 | // TODO Provide a real implementation. 37 | 38 | final var sbRequestData = new StringBuilder(); 39 | 40 | for (final String strFileName : strFileNames) { 41 | sbRequestData.append(strFileName); 42 | } 43 | 44 | final var requestData = sbRequestData.toString().getBytes(); 45 | 46 | return new JavaxMockHttpServletRequest(requestData, AbstractFileUpload.MULTIPART_FORM_DATA); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileUploadException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Signals errors encountered while processing the request. 23 | */ 24 | public class FileUploadException extends IOException { 25 | 26 | /** 27 | * Serial version UID, being used, if the exception is serialized. 28 | */ 29 | private static final long serialVersionUID = 2; 30 | 31 | /** 32 | * Constructs an instance with a given detail message. 33 | * 34 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 35 | */ 36 | public FileUploadException(final String message) { 37 | super(message); 38 | } 39 | 40 | /** 41 | * Constructs an instance with the given detail message and cause. 42 | * 43 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 44 | * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the cause 45 | * is nonexistent or unknown.) 46 | */ 47 | public FileUploadException(final String message, final Throwable cause) { 48 | super(message, cause); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxStreamingDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JavaxStreamingDiskTest 31 | extends AbstractStreamingTest { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JavaxServletDiskFileUpload newFileUpload() { 40 | return new JavaxServletDiskFileUpload(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JavaxServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JavaxServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.ByteArrayInputStream; 20 | import java.io.InputStream; 21 | import java.nio.charset.StandardCharsets; 22 | 23 | /** 24 | * Abstract test. 25 | * 26 | * @param The AbstractFileUpload type. 27 | * @param The FileUpload request type. 28 | * @param The FileItem type. 29 | * @param The FileItemFactory type. 30 | */ 31 | public abstract class AbstractTest, R, I extends FileItem, F extends FileItemFactory> { 32 | 33 | protected abstract AFU newFileUpload(); 34 | 35 | protected R newMockHttpServletRequest(final byte[] request, final Long overrideContenLength, final String contentType, final Integer overrideReadLimit) { 36 | return newMockHttpServletRequest(new ByteArrayInputStream(request), overrideContenLength != null ? overrideContenLength : request.length, contentType, 37 | overrideReadLimit != null ? overrideReadLimit : -1); 38 | } 39 | 40 | protected abstract R newMockHttpServletRequest(InputStream requestInputStream, long requestLength, String contentType, int readLimit); 41 | 42 | protected R newMockHttpServletRequest(final String request, final Long overrideContenLength, final Integer overrideReadLimit) { 43 | return newMockHttpServletRequest(request.getBytes(StandardCharsets.US_ASCII), overrideContenLength, Constants.CONTENT_TYPE, overrideReadLimit); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaStreamingDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaStreamingDiskTest 31 | extends AbstractStreamingTest { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JakartaServletDiskFileUpload newFileUpload() { 40 | return new JakartaServletDiskFileUpload(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JakartaServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JakartaServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaStreamingDiskTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaStreamingDiskTest 31 | extends AbstractStreamingTest { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JakartaServletDiskFileUpload newFileUpload() { 40 | return new JakartaServletDiskFileUpload(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JakartaServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JakartaServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/test/java/org/apache/commons/fileupload2/javax/JavaxStreamingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.InputStream; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | 23 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 24 | import org.apache.commons.fileupload2.core.DiskFileItem; 25 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JavaxStreamingTest extends 31 | AbstractStreamingTest, HttpServletRequest, JavaxServletRequestContext, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JavaxServletFileUpload newFileUpload() { 40 | return new JavaxServletFileUpload<>(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JavaxMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JavaxServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JavaxServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.nio.charset.StandardCharsets; 20 | import java.util.List; 21 | 22 | /** 23 | * Common tests for implementations of {@link AbstractFileUpload}. This is a parameterized test. Tests must be valid and common to all implementations of 24 | * FileUpload added as parameter in this class. 25 | * 26 | * @param The type for {@link AbstractFileUpload}. 27 | * @param The FileUpload request type. 28 | * @param The FileItem type. 29 | * @param The FileItemFactory type. 30 | */ 31 | public abstract class AbstractFileUploadWrapper, R, I extends FileItem, F extends FileItemFactory> { 32 | 33 | protected final AFU upload; 34 | 35 | protected AbstractFileUploadWrapper(final AFU fileUpload) { 36 | this.upload = fileUpload; 37 | } 38 | 39 | public List parseUpload(final AFU upload, final byte[] bytes) throws FileUploadException { 40 | return parseUpload(upload, bytes, Constants.CONTENT_TYPE); 41 | } 42 | 43 | public abstract List parseUpload(final AFU upload, final byte[] bytes, final String contentType) throws FileUploadException; 44 | 45 | public List parseUpload(final AFU upload, final String content) throws FileUploadException { 46 | final var bytes = content.getBytes(StandardCharsets.US_ASCII); 47 | return parseUpload(upload, bytes, Constants.CONTENT_TYPE); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/test/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaStreamingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaStreamingTest extends 31 | AbstractStreamingTest, HttpServletRequest, JakartaServletRequestContext, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JakartaServletFileUpload newFileUpload() { 40 | return new JakartaServletFileUpload<>(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JakartaServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JakartaServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/test/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaStreamingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.InputStream; 20 | 21 | import org.apache.commons.fileupload2.core.AbstractStreamingTest; 22 | import org.apache.commons.fileupload2.core.DiskFileItem; 23 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 24 | 25 | import jakarta.servlet.http.HttpServletRequest; 26 | 27 | /** 28 | * Unit test for items with varying sizes. 29 | */ 30 | class JakartaStreamingTest extends 31 | AbstractStreamingTest, HttpServletRequest, JakartaServletRequestContext, DiskFileItem, DiskFileItemFactory> { 32 | 33 | @Override 34 | protected DiskFileItemFactory newDiskFileItemFactory() { 35 | return DiskFileItemFactory.builder().get(); 36 | } 37 | 38 | @Override 39 | protected JakartaServletFileUpload newFileUpload() { 40 | return new JakartaServletFileUpload<>(); 41 | } 42 | 43 | @Override 44 | protected HttpServletRequest newMockHttpServletRequest(final InputStream request, final long requestLength, final String contentType, final int readLimit) { 45 | return new JakartaMockHttpServletRequest(request, requestLength, contentType, readLimit); 46 | } 47 | 48 | @Override 49 | protected JakartaServletRequestContext newServletRequestContext(final HttpServletRequest request) { 50 | return new JakartaServletRequestContext(request); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/site/xdoc/overview.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | 22 | 23 | FileUpload Overview 24 | Robert Burrell Donkin 25 | 26 | 27 | 28 |
29 |

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

33 |

34 | Assuming that you have decided that FileUpload should be invoked, you 35 | might write the following code to handle a file upload request: 36 | items = upload.parseRequest(request); 48 | 49 | // Process the uploaded fields 50 | for (DiskFileItem item :items) { 51 | if (item.isFormField()) { 52 | processTextParameter(request, item); 53 | } else { 54 | processFileParameter(request, item); 55 | } 56 | } 57 | ]]> 58 |

59 |
60 | 61 | 62 |
63 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileUploadContentTypeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Signals that a request is not a multipart request. 21 | */ 22 | public class FileUploadContentTypeException extends FileUploadException { 23 | 24 | /** 25 | * The exceptions UID, for serializing an instance. 26 | */ 27 | private static final long serialVersionUID = 2; 28 | 29 | /** 30 | * The guilty content type. 31 | */ 32 | private String contentType; 33 | 34 | /** 35 | * Constructs an instance with the specified detail message. 36 | * 37 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 38 | * @param contentType The guilty content type. 39 | */ 40 | public FileUploadContentTypeException(final String message, final String contentType) { 41 | super(message); 42 | this.contentType = contentType; 43 | } 44 | 45 | /** 46 | * Constructs an instance with the specified detail message and cause. 47 | * 48 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 49 | * @param cause the original cause 50 | */ 51 | public FileUploadContentTypeException(final String message, final Throwable cause) { 52 | super(message, cause); 53 | } 54 | 55 | /** 56 | * Gets the content type. 57 | * 58 | * @return the content type. 59 | */ 60 | public String getContentType() { 61 | return contentType; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileUploadSizeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Signals that a requests permitted size is exceeded. 21 | */ 22 | public class FileUploadSizeException extends FileUploadException { 23 | 24 | /** 25 | * Serial version UID, being used, if serialized. 26 | */ 27 | private static final long serialVersionUID = 2; 28 | 29 | /** 30 | * The actual size of the request. 31 | */ 32 | private final long actual; 33 | 34 | /** 35 | * The maximum permitted size of the request. 36 | */ 37 | private final long permitted; 38 | 39 | /** 40 | * Constructs an instance. 41 | * 42 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 43 | * @param permitted The requests size limit. 44 | * @param actual The actual values for the request. 45 | */ 46 | public FileUploadSizeException(final String message, final long permitted, final long actual) { 47 | super(message); 48 | this.permitted = permitted; 49 | this.actual = actual; 50 | } 51 | 52 | /** 53 | * Gets the actual size of the request. 54 | * 55 | * @return The actual size of the request. 56 | */ 57 | public long getActualSize() { 58 | return actual; 59 | } 60 | 61 | /** 62 | * Gets the limit size of the request. 63 | * 64 | * @return The limit size of the request. 65 | */ 66 | public long getPermitted() { 67 | return permitted; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.portlet; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import javax.portlet.ActionRequest; 23 | 24 | import org.apache.commons.fileupload2.core.AbstractRequestContext; 25 | 26 | /** 27 | * Provides access to the request information needed for a request made to a portlet. 28 | */ 29 | public class JavaxPortletRequestContext extends AbstractRequestContext { 30 | 31 | /** 32 | * Constructs a context for this request. 33 | * 34 | * @param request The request to which this context applies. 35 | */ 36 | public JavaxPortletRequestContext(final ActionRequest request) { 37 | super(request::getProperty, request::getContentLength, request); 38 | } 39 | 40 | /** 41 | * Gets the character encoding for the request. 42 | * 43 | * @return The character encoding for the request. 44 | */ 45 | @Override 46 | public String getCharacterEncoding() { 47 | return getRequest().getCharacterEncoding(); 48 | } 49 | 50 | /** 51 | * Gets the content type of the request. 52 | * 53 | * @return The content type of the request. 54 | */ 55 | @Override 56 | public String getContentType() { 57 | return getRequest().getContentType(); 58 | } 59 | 60 | /** 61 | * Gets the input stream for the request. 62 | * 63 | * @return The input stream for the request. 64 | * @throws IOException if a problem occurs. 65 | */ 66 | @Override 67 | public InputStream getInputStream() throws IOException { 68 | return getRequest().getPortletInputStream(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import org.apache.commons.fileupload2.core.AbstractRequestContext; 25 | 26 | /** 27 | * Provides access to the request information needed for a request made to an HTTP servlet. 28 | */ 29 | public class JavaxServletRequestContext extends AbstractRequestContext { 30 | 31 | /** 32 | * Constructs a context for this request. 33 | * 34 | * @param request The request to which this context applies. 35 | */ 36 | public JavaxServletRequestContext(final HttpServletRequest request) { 37 | super(request::getHeader, request::getContentLength, request); 38 | } 39 | 40 | /** 41 | * Gets the character encoding for the request. 42 | * 43 | * @return The character encoding for the request. 44 | */ 45 | @Override 46 | public String getCharacterEncoding() { 47 | return getRequest().getCharacterEncoding(); 48 | } 49 | 50 | /** 51 | * Gets the content type of the request. 52 | * 53 | * @return The content type of the request. 54 | */ 55 | @Override 56 | public String getContentType() { 57 | return getRequest().getContentType(); 58 | } 59 | 60 | /** 61 | * Gets the input stream for the request. 62 | * 63 | * @return The input stream for the request. 64 | * @throws IOException if a problem occurs. 65 | */ 66 | @Override 67 | public InputStream getInputStream() throws IOException { 68 | return getRequest().getInputStream(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import org.apache.commons.fileupload2.core.AbstractRequestContext; 23 | 24 | import jakarta.servlet.http.HttpServletRequest; 25 | 26 | /** 27 | * Provides access to the request information needed for a request made to an HTTP servlet. 28 | */ 29 | public class JakartaServletRequestContext extends AbstractRequestContext { 30 | 31 | /** 32 | * Constructs a context for this request. 33 | * 34 | * @param request The request to which this context applies. 35 | */ 36 | public JakartaServletRequestContext(final HttpServletRequest request) { 37 | super(request::getHeader, request::getContentLength, request); 38 | } 39 | 40 | /** 41 | * Gets the character encoding for the request. 42 | * 43 | * @return The character encoding for the request. 44 | */ 45 | @Override 46 | public String getCharacterEncoding() { 47 | return getRequest().getCharacterEncoding(); 48 | } 49 | 50 | /** 51 | * Gets the content type of the request. 52 | * 53 | * @return The content type of the request. 54 | */ 55 | @Override 56 | public String getContentType() { 57 | return getRequest().getContentType(); 58 | } 59 | 60 | /** 61 | * Gets the input stream for the request. 62 | * 63 | * @return The input stream for the request. 64 | * @throws IOException if a problem occurs. 65 | */ 66 | @Override 67 | public InputStream getInputStream() throws IOException { 68 | return getRequest().getInputStream(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import org.apache.commons.fileupload2.core.AbstractRequestContext; 23 | 24 | import jakarta.servlet.http.HttpServletRequest; 25 | 26 | /** 27 | * Provides access to the request information needed for a request made to an HTTP servlet. 28 | */ 29 | public class JakartaServletRequestContext extends AbstractRequestContext { 30 | 31 | /** 32 | * Constructs a context for this request. 33 | * 34 | * @param request The request to which this context applies. 35 | */ 36 | public JakartaServletRequestContext(final HttpServletRequest request) { 37 | super(request::getHeader, request::getContentLength, request); 38 | } 39 | 40 | /** 41 | * Gets the character encoding for the request. 42 | * 43 | * @return The character encoding for the request. 44 | */ 45 | @Override 46 | public String getCharacterEncoding() { 47 | return getRequest().getCharacterEncoding(); 48 | } 49 | 50 | /** 51 | * Gets the content type of the request. 52 | * 53 | * @return The content type of the request. 54 | */ 55 | @Override 56 | public String getContentType() { 57 | return getRequest().getContentType(); 58 | } 59 | 60 | /** 61 | * Gets the input stream for the request. 62 | * 63 | * @return The input stream for the request. 64 | * @throws IOException if a problem occurs. 65 | */ 66 | @Override 67 | public InputStream getInputStream() throws IOException { 68 | return getRequest().getInputStream(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /.github/workflows/scorecards-analysis.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache license, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the license for the specific language governing permissions and 14 | # limitations under the license. 15 | 16 | name: "Scorecards supply-chain security" 17 | 18 | on: 19 | branch_protection_rule: 20 | schedule: 21 | - cron: "30 1 * * 6" # Weekly on Saturdays 22 | push: 23 | branches: [ "master" ] 24 | 25 | permissions: read-all 26 | 27 | jobs: 28 | 29 | analysis: 30 | 31 | name: "Scorecards analysis" 32 | runs-on: ubuntu-latest 33 | permissions: 34 | # Needed to upload the results to the code-scanning dashboard. 35 | security-events: write 36 | actions: read 37 | id-token: write # This is required for requesting the JWT 38 | contents: read # This is required for actions/checkout 39 | 40 | steps: 41 | 42 | - name: "Checkout code" 43 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 44 | with: 45 | persist-credentials: false 46 | 47 | - name: "Run analysis" 48 | uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # 2.4.3 49 | with: 50 | results_file: results.sarif 51 | results_format: sarif 52 | # A read-only PAT token, which is sufficient for the action to function. 53 | # The relevant discussion: https://github.com/ossf/scorecard-action/issues/188 54 | repo_token: ${{ secrets.GITHUB_TOKEN }} 55 | # Publish the results for public repositories to enable scorecard badges. 56 | # For more details: https://github.com/ossf/scorecard-action#publishing-results 57 | publish_results: true 58 | 59 | - name: "Upload artifact" 60 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # 5.0.0 61 | with: 62 | name: SARIF file 63 | path: results.sarif 64 | retention-days: 5 65 | 66 | - name: "Upload to code-scanning" 67 | uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 68 | with: 69 | sarif_file: results.sarif 70 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 22 | Commons FileUpload 23 | /images/logo.png 24 | /index.html 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileUploadByteCountLimitException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | /** 20 | * Signals that a file size exceeds the configured maximum. 21 | */ 22 | public class FileUploadByteCountLimitException extends FileUploadSizeException { 23 | 24 | /** 25 | * The exceptions UID, for serializing an instance. 26 | */ 27 | private static final long serialVersionUID = 2; 28 | 29 | /** 30 | * File name of the item, which caused the exception. 31 | */ 32 | private final String fileName; 33 | 34 | /** 35 | * Field name of the item, which caused the exception. 36 | */ 37 | private final String fieldName; 38 | 39 | /** 40 | * Constructs an instance with the specified detail message, and actual and permitted sizes. 41 | * 42 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 43 | * @param actual The actual request size. 44 | * @param permitted The maximum permitted request size. 45 | * @param fileName File name of the item, which caused the exception. 46 | * @param fieldName Field name of the item, which caused the exception. 47 | */ 48 | public FileUploadByteCountLimitException(final String message, final long actual, final long permitted, final String fileName, final String fieldName) { 49 | super(message, permitted, actual); 50 | this.fileName = fileName; 51 | this.fieldName = fieldName; 52 | } 53 | 54 | /** 55 | * Gets the field name of the item, which caused the exception. 56 | * 57 | * @return Field name, if known, or null. 58 | */ 59 | public String getFieldName() { 60 | return fieldName; 61 | } 62 | 63 | /** 64 | * Gets the file name of the item, which caused the exception. 65 | * 66 | * @return File name, if known, or null. 67 | */ 68 | public String getFileName() { 69 | return fileName; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.nio.charset.Charset; 22 | import java.nio.charset.UnsupportedCharsetException; 23 | 24 | import org.apache.commons.io.Charsets; 25 | 26 | /** 27 | * Abstracts access to the request information needed for file uploads. 28 | *

29 | * This interface should be implemented for each type of request that may be handled by FileUpload, such as servlets and portlets. 30 | *

31 | */ 32 | public interface RequestContext { 33 | 34 | /** 35 | * Gets the character encoding for the request. 36 | * 37 | * @return The character encoding for the request. 38 | */ 39 | String getCharacterEncoding(); 40 | 41 | /** 42 | * Gets the character encoding for the request or null if unspecified. 43 | * 44 | * @return The character encoding for the request or null. 45 | * @throws UnsupportedCharsetException If the named Charset is unavailable. 46 | */ 47 | default Charset getCharset() throws UnsupportedCharsetException { 48 | return Charsets.toCharset(getCharacterEncoding(), null); 49 | } 50 | 51 | /** 52 | * Gets the content length of the request. 53 | * 54 | * @return The content length of the request. 55 | */ 56 | long getContentLength(); 57 | 58 | /** 59 | * Gets the content type of the request. 60 | * 61 | * @return The content type of the request. 62 | */ 63 | String getContentType(); 64 | 65 | /** 66 | * Gets the input stream for the request. 67 | * 68 | * @return The input stream for the request. 69 | * @throws IOException if a problem occurs. 70 | */ 71 | InputStream getInputStream() throws IOException; 72 | 73 | /** 74 | * Is the Request of type {@code multipart/related}? 75 | * 76 | * @return the Request is of type {@code multipart/related} 77 | * @since 2.0.0 78 | */ 79 | boolean isMultipartRelated(); 80 | } 81 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MimeUtilityTestCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertThrows; 21 | 22 | import java.io.UnsupportedEncodingException; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | /** 27 | * Use the online MimeHeadersDecoder to validate expected values. 28 | */ 29 | public final class MimeUtilityTestCase { 30 | 31 | private static void assertEncoded(final String expected, final String encoded) throws Exception { 32 | assertEquals(expected, MimeUtils.decodeText(encoded)); 33 | } 34 | 35 | @Test 36 | void testDecodeInvalidEncoding() { 37 | assertThrows(UnsupportedEncodingException.class, () -> MimeUtils.decodeText("=?invalid?B?xyz-?=")); 38 | } 39 | 40 | @Test 41 | void testDecodeIso88591Base64Encoded() throws Exception { 42 | assertEncoded("If you can read this you understand the example.", 43 | "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= " + "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n"); 44 | } 45 | 46 | @Test 47 | void testDecodeIso88591Base64EncodedWithWhiteSpace() throws Exception { 48 | assertEncoded("If you can read this you understand the example.", 49 | "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\t \r\n =?ISO-8859-" + "2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n"); 50 | } 51 | 52 | @Test 53 | void testDecodeUtf8Base64Encoded() throws Exception { 54 | assertEncoded(" h\u00e9! \u00e0\u00e8\u00f4u !!!", "=?UTF-8?B?IGjDqSEgw6DDqMO0dSAhISE=?="); 55 | } 56 | 57 | @Test 58 | void testDecodeUtf8QuotedPrintableEncoded() throws Exception { 59 | assertEncoded(" h\u00e9! \u00e0\u00e8\u00f4u !!!", "=?UTF-8?Q?_h=C3=A9!_=C3=A0=C3=A8=C3=B4u_!!!?="); 60 | } 61 | 62 | @Test 63 | void testNoNeedToDecode() throws Exception { 64 | assertEncoded("abc", "abc"); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /spotbugs-exclude-filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemHeaders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.util.Iterator; 20 | 21 | /** 22 | * This class provides support for accessing the headers for a file or form item that was received within a {@code multipart/form-data} POST request. 23 | */ 24 | public interface FileItemHeaders { 25 | 26 | /** 27 | * Adds a header. 28 | * 29 | * @param name name 30 | * @param value value. 31 | */ 32 | void addHeader(String name, String value); 33 | 34 | /** 35 | * Gets the value of the specified part header as a {@code String}. 36 | *

37 | * If the part did not include a header of the specified name, this method return {@code null}. If there are multiple headers with the same name, this 38 | * method returns the first header in the item. The header name is case insensitive. 39 | *

40 | * 41 | * @param name a {@code String} specifying the header name 42 | * @return a {@code String} containing the value of the requested header, or {@code null} if the item does not have a header of that name 43 | */ 44 | String getHeader(String name); 45 | 46 | /** 47 | * Gets an {@code Iterator} of all the header names. 48 | * 49 | * @return an {@code Iterator} containing all of the names of headers provided with this file item. If the item does not have any headers return an empty 50 | * {@code Iterator} 51 | */ 52 | Iterator getHeaderNames(); 53 | 54 | /** 55 | * Gets all the values of the specified item header as an {@code Iterator} of {@code String} objects. 56 | *

57 | * If the item did not include any headers of the specified name, this method returns an empty {@code Iterator}. The header name is case insensitive. 58 | *

59 | * 60 | * @param name a {@code String} specifying the header name 61 | * @return an {@code Iterator} containing the values of the requested header. If the item does not have any headers of that name, return an empty 62 | * {@code Iterator} 63 | */ 64 | Iterator getHeaders(String name); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemHeadersImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.Iterator; 22 | import java.util.LinkedHashMap; 23 | import java.util.List; 24 | import java.util.Locale; 25 | import java.util.Map; 26 | 27 | /** 28 | * Default implementation of the {@link FileItemHeaders} interface. 29 | */ 30 | class FileItemHeadersImpl implements FileItemHeaders { 31 | 32 | /** 33 | * Map of {@code String} keys to a {@code List} of {@code String} instances. 34 | */ 35 | private final Map> headerNameToValueListMap = new LinkedHashMap<>(); 36 | 37 | /** 38 | * Method to add header values to this instance. 39 | * 40 | * @param name name of this header 41 | * @param value value of this header 42 | */ 43 | @Override 44 | public synchronized void addHeader(final String name, final String value) { 45 | headerNameToValueListMap.computeIfAbsent(toLowerCase(name), k -> new ArrayList<>()).add(value); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | */ 51 | @Override 52 | public String getHeader(final String name) { 53 | final var headerValueList = getList(name); 54 | if (null == headerValueList) { 55 | return null; 56 | } 57 | return headerValueList.get(0); 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | @Override 64 | public Iterator getHeaderNames() { 65 | return headerNameToValueListMap.keySet().iterator(); 66 | } 67 | 68 | /** 69 | * {@inheritDoc} 70 | */ 71 | @Override 72 | public Iterator getHeaders(final String name) { 73 | var headerValueList = getList(name); 74 | if (null == headerValueList) { 75 | headerValueList = Collections.emptyList(); 76 | } 77 | return headerValueList.iterator(); 78 | } 79 | 80 | private List getList(final String name) { 81 | return headerNameToValueListMap.get(toLowerCase(name)); 82 | } 83 | 84 | private String toLowerCase(final String value) { 85 | return value.toLowerCase(Locale.ROOT); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | name: "CodeQL" 17 | 18 | on: 19 | push: 20 | branches: [ master ] 21 | pull_request: 22 | # The branches below must be a subset of the branches above 23 | branches: [ master ] 24 | schedule: 25 | - cron: '33 9 * * 4' 26 | 27 | permissions: 28 | contents: read 29 | 30 | jobs: 31 | analyze: 32 | name: Analyze 33 | runs-on: ubuntu-latest 34 | permissions: 35 | actions: read 36 | contents: read 37 | security-events: write 38 | 39 | strategy: 40 | fail-fast: false 41 | matrix: 42 | language: [ 'java' ] 43 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 44 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 45 | 46 | steps: 47 | - name: Checkout repository 48 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 49 | with: 50 | persist-credentials: false 51 | - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 52 | with: 53 | path: ~/.m2/repository 54 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 55 | restore-keys: | 56 | ${{ runner.os }}-maven- 57 | 58 | # Initializes the CodeQL tools for scanning. 59 | - name: Initialize CodeQL 60 | uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 61 | with: 62 | languages: ${{ matrix.language }} 63 | # If you wish to specify custom queries, you can do so here or in a config file. 64 | # By default, queries listed here will override any specified in a config file. 65 | # Prefix the list here with "+" to use these queries and those in the config file. 66 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 67 | 68 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 69 | # If this step fails, then you should remove it and run the build manually (see below) 70 | - name: Autobuild 71 | uses: github/codeql-action/autobuild@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 72 | 73 | # ℹ️ Command-line programs to run using the OS shell. 74 | # 📚 https://git.io/JvXDl 75 | 76 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 77 | # and modify them (or add more) to build your code if your project 78 | # uses a compiled language 79 | 80 | #- run: | 81 | # make bootstrap 82 | # make release 83 | 84 | - name: Perform CodeQL Analysis 85 | uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 86 | -------------------------------------------------------------------------------- /commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxFileCleaner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.javax; 18 | 19 | import javax.servlet.ServletContext; 20 | import javax.servlet.ServletContextEvent; 21 | import javax.servlet.ServletContextListener; 22 | 23 | import org.apache.commons.io.FileCleaningTracker; 24 | 25 | /** 26 | * A servlet context listener, which ensures that the {@link FileCleaningTracker}'s reaper thread is terminated, when the web application is destroyed. 27 | */ 28 | public class JavaxFileCleaner implements ServletContextListener { 29 | 30 | /** 31 | * Attribute name, which is used for storing an instance of {@link FileCleaningTracker} in the web application. 32 | */ 33 | public static final String FILE_CLEANING_TRACKER_ATTRIBUTE = JavaxFileCleaner.class.getName() + ".FileCleaningTracker"; 34 | 35 | /** 36 | * Gets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 37 | * 38 | * @param servletContext The servlet context to query 39 | * @return The contexts tracker 40 | */ 41 | public static FileCleaningTracker getFileCleaningTracker(final ServletContext servletContext) { 42 | return (FileCleaningTracker) servletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); 43 | } 44 | 45 | /** 46 | * Sets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 47 | * 48 | * @param servletContext The servlet context to modify 49 | * @param tracker The tracker to set 50 | */ 51 | public static void setFileCleaningTracker(final ServletContext servletContext, final FileCleaningTracker tracker) { 52 | servletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, tracker); 53 | } 54 | 55 | /** 56 | * Constructs a new instance. 57 | */ 58 | public JavaxFileCleaner() { 59 | // empty 60 | } 61 | 62 | /** 63 | * Called when the web application is being destroyed. Calls {@link FileCleaningTracker#exitWhenFinished()}. 64 | * 65 | * @param sce The servlet context, used for calling {@link #getFileCleaningTracker(ServletContext)}. 66 | */ 67 | @Override 68 | public void contextDestroyed(final ServletContextEvent sce) { 69 | getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); 70 | } 71 | 72 | /** 73 | * Called when the web application is initialized. Does nothing. 74 | * 75 | * @param sce The servlet context, used for calling {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. 76 | */ 77 | @Override 78 | public void contextInitialized(final ServletContextEvent sce) { 79 | setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaFileCleaner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet5; 18 | 19 | import org.apache.commons.io.FileCleaningTracker; 20 | 21 | import jakarta.servlet.ServletContext; 22 | import jakarta.servlet.ServletContextEvent; 23 | import jakarta.servlet.ServletContextListener; 24 | 25 | /** 26 | * A servlet context listener, which ensures that the {@link FileCleaningTracker}'s reaper thread is terminated, when the web application is destroyed. 27 | */ 28 | public class JakartaFileCleaner implements ServletContextListener { 29 | 30 | /** 31 | * Attribute name, which is used for storing an instance of {@link FileCleaningTracker} in the web application. 32 | */ 33 | public static final String FILE_CLEANING_TRACKER_ATTRIBUTE = JakartaFileCleaner.class.getName() + ".FileCleaningTracker"; 34 | 35 | /** 36 | * Gets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 37 | * 38 | * @param servletContext The servlet context to query 39 | * @return The contexts tracker 40 | */ 41 | public static FileCleaningTracker getFileCleaningTracker(final ServletContext servletContext) { 42 | return (FileCleaningTracker) servletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); 43 | } 44 | 45 | /** 46 | * Sets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 47 | * 48 | * @param servletContext The servlet context to modify 49 | * @param tracker The tracker to set 50 | */ 51 | public static void setFileCleaningTracker(final ServletContext servletContext, final FileCleaningTracker tracker) { 52 | servletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, tracker); 53 | } 54 | 55 | /** 56 | * Constructs a new instance. 57 | */ 58 | public JakartaFileCleaner() { 59 | // empty 60 | } 61 | 62 | /** 63 | * Called when the web application is being destroyed. Calls {@link FileCleaningTracker#exitWhenFinished()}. 64 | * 65 | * @param sce The servlet context, used for calling {@link #getFileCleaningTracker(ServletContext)}. 66 | */ 67 | @Override 68 | public void contextDestroyed(final ServletContextEvent sce) { 69 | getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); 70 | } 71 | 72 | /** 73 | * Called when the web application is initialized. Does nothing. 74 | * 75 | * @param sce The servlet context, used for calling {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. 76 | */ 77 | @Override 78 | public void contextInitialized(final ServletContextEvent sce) { 79 | setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaFileCleaner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.jakarta.servlet6; 18 | 19 | import org.apache.commons.io.FileCleaningTracker; 20 | 21 | import jakarta.servlet.ServletContext; 22 | import jakarta.servlet.ServletContextEvent; 23 | import jakarta.servlet.ServletContextListener; 24 | 25 | /** 26 | * A servlet context listener, which ensures that the {@link FileCleaningTracker}'s reaper thread is terminated, when the web application is destroyed. 27 | */ 28 | public class JakartaFileCleaner implements ServletContextListener { 29 | 30 | /** 31 | * Attribute name, which is used for storing an instance of {@link FileCleaningTracker} in the web application. 32 | */ 33 | public static final String FILE_CLEANING_TRACKER_ATTRIBUTE = JakartaFileCleaner.class.getName() + ".FileCleaningTracker"; 34 | 35 | /** 36 | * Gets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 37 | * 38 | * @param servletContext The servlet context to query 39 | * @return The contexts tracker 40 | */ 41 | public static FileCleaningTracker getFileCleaningTracker(final ServletContext servletContext) { 42 | return (FileCleaningTracker) servletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); 43 | } 44 | 45 | /** 46 | * Sets the instance of {@link FileCleaningTracker}, which is associated with the given {@link ServletContext}. 47 | * 48 | * @param servletContext The servlet context to modify 49 | * @param tracker The tracker to set 50 | */ 51 | public static void setFileCleaningTracker(final ServletContext servletContext, final FileCleaningTracker tracker) { 52 | servletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, tracker); 53 | } 54 | 55 | /** 56 | * Constructs a new instance. 57 | */ 58 | public JakartaFileCleaner() { 59 | // empty 60 | } 61 | 62 | /** 63 | * Called when the web application is being destroyed. Calls {@link FileCleaningTracker#exitWhenFinished()}. 64 | * 65 | * @param sce The servlet context, used for calling {@link #getFileCleaningTracker(ServletContext)}. 66 | */ 67 | @Override 68 | public void contextDestroyed(final ServletContextEvent sce) { 69 | getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); 70 | } 71 | 72 | /** 73 | * Called when the web application is initialized. Does nothing. 74 | * 75 | * @param sce The servlet context, used for calling {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. 76 | */ 77 | @Override 78 | public void contextInitialized(final ServletContextEvent sce) { 79 | setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/RFC2231UtilityTestCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertFalse; 21 | import static org.junit.jupiter.api.Assertions.assertThrows; 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | 24 | import java.io.UnsupportedEncodingException; 25 | 26 | import org.junit.jupiter.api.Test; 27 | 28 | /** 29 | * The expected characters are encoded in UTF16, while the actual characters may be encoded in UTF-8/ISO-8859-1 30 | * 31 | * RFC 5987 recommends to support both UTF-8 and ISO 8859-1. Test values are taken from https://tools.ietf.org/html/rfc5987#section-3.2.2 32 | */ 33 | public final class RFC2231UtilityTestCase { 34 | 35 | private static void assertEncoded(final String expected, final String encoded) throws Exception { 36 | assertEquals(expected, RFC2231Utils.decodeText(encoded)); 37 | } 38 | 39 | @Test 40 | void testDecodeInvalidEncoding() throws Exception { 41 | assertThrows(UnsupportedEncodingException.class, () -> RFC2231Utils.decodeText("abc'en'hello")); 42 | } 43 | 44 | @Test 45 | void testDecodeIso88591() throws Exception { 46 | assertEncoded("\u00A3 rate", "iso-8859-1'en'%A3%20rate"); // "£ rate" 47 | } 48 | 49 | @Test 50 | void testDecodeUtf8() throws Exception { 51 | assertEncoded("\u00a3 \u0061\u006e\u0064 \u20ac \u0072\u0061\u0074\u0065\u0073", "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates"); // "£ and € rates" 52 | } 53 | 54 | @Test 55 | void testHasEncodedValue() { 56 | final var nameWithAsteriskAtEnd = "paramname*"; 57 | assertTrue(RFC2231Utils.hasEncodedValue(nameWithAsteriskAtEnd)); 58 | 59 | final var nameWithAsteriskNotAtEnd = "param*name"; 60 | assertFalse(RFC2231Utils.hasEncodedValue(nameWithAsteriskNotAtEnd)); 61 | 62 | final var nameWithoutAsterisk = "paramname"; 63 | assertFalse(RFC2231Utils.hasEncodedValue(nameWithoutAsterisk)); 64 | } 65 | 66 | @Test 67 | void testNoNeedToDecode() throws Exception { 68 | assertEncoded("abc", "abc"); 69 | } 70 | 71 | @Test 72 | void testStripDelimiter() { 73 | final var nameWithAsteriskAtEnd = "paramname*"; 74 | assertEquals("paramname", RFC2231Utils.stripDelimiter(nameWithAsteriskAtEnd)); 75 | 76 | final var nameWithAsteriskNotAtEnd = "param*name"; 77 | assertEquals("param*name", RFC2231Utils.stripDelimiter(nameWithAsteriskNotAtEnd)); 78 | 79 | final var nameWithTwoAsterisks = "param*name*"; 80 | assertEquals("param*name", RFC2231Utils.stripDelimiter(nameWithTwoAsterisks)); 81 | 82 | final var nameWithoutAsterisk = "paramname"; 83 | assertEquals("paramname", RFC2231Utils.stripDelimiter(nameWithoutAsterisk)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/site/xdoc/streaming.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | 22 | 23 | The Streaming API 24 | 25 | 26 | 27 |
28 |

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

35 |

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

40 |
41 | 42 |
43 |

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

49 |
50 | 51 |
52 |

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

57 | 59 |

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

63 | { 71 | String name = item.getFieldName(); 72 | InputStream stream = item.getInputStream(); 73 | if (item.isFormField()) { 74 | System.out.println("Form field " + name + " with value " 75 | + IOUtils.toString(stream, Charset.defaultCharset()) + " detected."); 76 | } else { 77 | System.out.println("File field " + name + " with file name " 78 | + item.getName() + " detected."); 79 | // Process the input stream 80 | ... 81 | } 82 | });]]> 83 |

84 | That's all that's needed. Really! 85 |

86 |
87 | 88 | 89 |
90 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | *

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

23 | *

24 | * While this package provides the generic functionality for file uploads, these classes are not typically used directly. Instead, normal usage involves one of 25 | * the provided extensions of {@link org.apache.commons.fileupload2.core.AbstractFileUpload} such as 26 | * {@code org.apache.commons.fileupload2.core.servlet.ServletFileUpload ServletFileUpload} or 27 | * {@code org.apache.commons.fileupload2.core.portlet.PortletFileUpload PortletFileUpload}, together with a factory for 28 | * {@link org.apache.commons.fileupload2.core.FileItem} instances, such as {@link org.apache.commons.fileupload2.core.DiskFileItemFactory}. 29 | *

30 | *

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

33 | * 34 | *
{@code
35 |  * public void doPost(HttpServletRequest req, HttpServletResponse res) {
36 |  *   DiskFileItemFactory factory = new DiskFileItemFactory.builder()
37 |  *     // maximum size that will be stored in memory
38 |  *     .setSizeThreshold(4096);
39 |  *     // the location for saving data that is larger than getSizeThreshold()
40 |  *     .setPath(Paths.get("/tmp"))
41 |  *     // build it
42 |  *     .get();
43 |  *
44 |  *   ServletFileUpload upload = new ServletFileUpload(factory);
45 |  *   // maximum size before a FileUploadException will be thrown
46 |  *   upload.setSizeMax(1000000);
47 |  *
48 |  *   List fileItems = upload.parseRequest(req);
49 |  *   // assume we know there are two files. The first file is a small
50 |  *   // text file, the second is unknown and is written to a file on
51 |  *   // the server
52 |  *   Iterator i = fileItems.iterator();
53 |  *   String comment = ((FileItem)i.next()).getString();
54 |  *   FileItem fi = (FileItem)i.next();
55 |  *   // file name on the client
56 |  *   String fileName = fi.getName();
57 |  *   // save comment and file name to database
58 |  *   ...
59 |  *   // write the file
60 |  *   fi.write(new File("/www/uploads/", fileName));
61 |  * }
62 |  * }
63 | *

64 | * In the example above, the first file is loaded into memory as a {@code String}. Before calling the {@code getString} method, the data may have been in memory 65 | * 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 66 | * 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 67 | * attempt is made to rename the temporary file to the given location. If it cannot be renamed, it is streamed to the new location. 68 | *

69 | *

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

73 | */ 74 | package org.apache.commons.fileupload2.core; 75 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.commons.fileupload2.core; 19 | 20 | import java.util.Objects; 21 | import java.util.function.Function; 22 | import java.util.function.LongSupplier; 23 | import java.util.regex.Pattern; 24 | 25 | /** 26 | * Abstracts a RequestContext for implementations. 27 | * 28 | * @param The request type. 29 | */ 30 | public abstract class AbstractRequestContext implements RequestContext { 31 | /** 32 | * The Content-Type Pattern for multipart/related Requests. 33 | */ 34 | private static final Pattern MULTIPART_RELATED = 35 | Pattern.compile("^\\s*multipart/related.*", Pattern.CASE_INSENSITIVE); 36 | 37 | /** 38 | * Supplies the content length default. 39 | */ 40 | private final LongSupplier contentLengthDefault; 41 | 42 | /** 43 | * Supplies the content length string. 44 | */ 45 | private final Function contentLengthString; 46 | 47 | /** 48 | * The request. 49 | */ 50 | private final T request; 51 | 52 | /** 53 | * Constructs a new instance. 54 | * 55 | * @param contentLengthString How to get the content length string. 56 | * @param contentLengthDefault How to get the content length default. 57 | * @param request The request. 58 | */ 59 | protected AbstractRequestContext(final Function contentLengthString, final LongSupplier contentLengthDefault, final T request) { 60 | this.contentLengthString = Objects.requireNonNull(contentLengthString, "contentLengthString"); 61 | this.contentLengthDefault = Objects.requireNonNull(contentLengthDefault, "contentLengthDefault"); 62 | this.request = Objects.requireNonNull(request, "request"); 63 | } 64 | 65 | /** 66 | * Gets the content length of the request. 67 | * 68 | * @return The content length of the request. 69 | */ 70 | @Override 71 | public long getContentLength() { 72 | try { 73 | return Long.parseLong(contentLengthString.apply(AbstractFileUpload.CONTENT_LENGTH)); 74 | } catch (final NumberFormatException e) { 75 | return contentLengthDefault.getAsLong(); 76 | } 77 | } 78 | 79 | /** 80 | * Gets the request. 81 | * 82 | * @return the request. 83 | */ 84 | public T getRequest() { 85 | return request; 86 | } 87 | 88 | /** 89 | * Tests whether the Request of type {@code multipart/related}? 90 | * 91 | * @return whether the Request is of type {@code multipart/related} 92 | * @since 2.0.0 93 | */ 94 | @Override 95 | public boolean isMultipartRelated() { 96 | return MULTIPART_RELATED.matcher(getContentType()).matches(); 97 | } 98 | 99 | /** 100 | * Returns a string representation of this object. 101 | * 102 | * @return a string representation of this object. 103 | */ 104 | @Override 105 | public String toString() { 106 | return String.format("%s [ContentLength=%s, ContentType=%s]", getClass().getSimpleName(), getContentLength(), getContentType()); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/changes/release-notes.vm: -------------------------------------------------------------------------------- 1 | ## Licensed to the Apache Software Foundation (ASF) under one 2 | ## or more contributor license agreements. See the NOTICE file 3 | ## distributed with this work for additional information 4 | ## regarding copyright ownership. The ASF licenses this file 5 | ## to you under the Apache License, Version 2.0 (the 6 | ## "License"); you may not use this file except in compliance 7 | ## with the License. You may obtain a copy of the License at 8 | ## 9 | ## https://www.apache.org/licenses/LICENSE-2.0 10 | ## 11 | ## Unless required by applicable law or agreed to in writing, 12 | ## software distributed under the License is distributed on an 13 | ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ## KIND, either express or implied. See the License for the 15 | ## specific language governing permissions and limitations 16 | ## under the License. 17 | ${project.name} ${version} Release Notes 18 | ------------------------------------------------ 19 | 20 | The ${developmentTeam} is pleased to announce the release of ${project.name} ${version}. 21 | 22 | The Apache Commons FileUpload component provides a simple yet flexible means of 23 | adding support for multipart file upload functionality to Servlets and web 24 | applications. This version requires Java 11 or above. 25 | 26 | 27 | ## The available variables are described here: 28 | ## http://maven.apache.org/plugins/maven-changes-plugin/examples/using-a-custom-announcement-template.html 29 | ## 30 | ## Hack to improve layout: replace all pairs of spaces with a single new-line 31 | $release.description.replaceAll(" ", " 32 | ") 33 | 34 | ## set up indent sizes. Only change indent1 35 | #set($props=${project.properties}) 36 | #set($jiralen=$props.get("commons.jira.id").length()) 37 | ## indent1 = POOL-nnnn: 38 | #set($blanklen=$jiralen+6)## +6 for "-nnnn:" 39 | ## must be at least as long as the longest JIRA id 40 | #set($blanks=" ") 41 | #set($indent1=$blanks.substring(0,$blanklen)) 42 | ## indent2 allows for issue wrapper 43 | #set($indent2="$indent1 ") 44 | ## 45 | #macro ( processaction ) 46 | ## Use replaceAll to fix up LF-only line ends on Windows. 47 | #set($action=$actionItem.getAction().replaceAll("\n"," 48 | ")) 49 | ## Fix up indentation for multi-line action descriptions 50 | #set($action=$action.replaceAll("(?m)^ +",$indent2)) 51 | #if ($actionItem.getIssue()) 52 | #set($issue="$actionItem.getIssue():") 53 | ## Pad shorter issue numbers 54 | #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end 55 | #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end 56 | #if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end 57 | #else 58 | #set($issue=$indent1) 59 | #end 60 | #if ($actionItem.getDueTo()) 61 | #set($dueto=" Thanks to $actionItem.getDueTo().") 62 | #else 63 | #set($dueto="") 64 | #end 65 | o $issue ${action}$dueto 66 | #set($action="") 67 | #set($issue="") 68 | #set($dueto="") 69 | #end 70 | ## 71 | #if ($release.getActions().size() == 0) 72 | No changes defined in this version. 73 | #else 74 | Changes in version ${version} include: 75 | 76 | #if ($release.getActions('add').size() !=0) 77 | New features: 78 | #foreach($actionItem in $release.getActions('add')) 79 | #processaction() 80 | #end 81 | #end 82 | 83 | #if ($release.getActions('fix').size() !=0) 84 | Fixed Bugs: 85 | #foreach($actionItem in $release.getActions('fix')) 86 | #processaction() 87 | #end 88 | #end 89 | 90 | #if ($release.getActions('update').size() !=0) 91 | Changes: 92 | #foreach($actionItem in $release.getActions('update')) 93 | #processaction() 94 | #end 95 | #end 96 | 97 | #if ($release.getActions('remove').size() !=0) 98 | Removed: 99 | #foreach($actionItem in $release.getActions('remove')) 100 | #processaction() 101 | #end 102 | #end 103 | ## End of main loop 104 | #end 105 | 106 | For complete information on ${project.name}, including instructions on how to submit bug reports, 107 | patches, or suggestions for improvement, see the ${project.name} website: 108 | 109 | ${project.url} 110 | 111 | Download it from ${project.url}download_fileupload.cgi 112 | 113 | ------------------------------------------------------------------------------ 114 | -------------------------------------------------------------------------------- /commons-fileupload2-portlet/src/test/java/org/apache/commons/fileupload2/portlet/JavaxPortletFileUploadTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.portlet; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertTrue; 21 | 22 | import java.nio.charset.StandardCharsets; 23 | import java.util.List; 24 | 25 | import javax.portlet.ActionRequest; 26 | 27 | import org.apache.commons.fileupload2.core.AbstractFileUploadTest; 28 | import org.apache.commons.fileupload2.core.Constants; 29 | import org.apache.commons.fileupload2.core.DiskFileItem; 30 | import org.apache.commons.fileupload2.core.DiskFileItemFactory; 31 | import org.apache.commons.fileupload2.core.FileUploadException; 32 | import org.junit.jupiter.api.Test; 33 | 34 | /** 35 | * Tests {@link JavaxPortletFileUpload}. 36 | * 37 | * @see AbstractFileUploadTest 38 | */ 39 | class JavaxPortletFileUploadTest 40 | extends AbstractFileUploadTest, ActionRequest, DiskFileItem, DiskFileItemFactory> { 41 | 42 | public JavaxPortletFileUploadTest() { 43 | super(new JavaxPortletFileUpload<>(DiskFileItemFactory.builder().get())); 44 | } 45 | 46 | @Override 47 | public List parseUpload(final JavaxPortletFileUpload upload, final byte[] bytes, final String contentType) 48 | throws FileUploadException { 49 | final ActionRequest request = new JavaxPortletMockActionRequest(bytes, contentType); 50 | return upload.parseRequest(new JavaxPortletRequestContext(request)); 51 | } 52 | 53 | @Test 54 | void testParseParameterMap() throws Exception { 55 | // @formatter:off 56 | final var text = "-----1234\r\n" + 57 | "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + 58 | "Content-Type: text/whatever\r\n" + 59 | "\r\n" + 60 | "This is the content of the file\n" + 61 | "\r\n" + 62 | "-----1234\r\n" + 63 | "Content-Disposition: form-data; name=\"field\"\r\n" + 64 | "\r\n" + 65 | "fieldValue\r\n" + 66 | "-----1234\r\n" + 67 | "Content-Disposition: form-data; name=\"multi\"\r\n" + 68 | "\r\n" + 69 | "value1\r\n" + 70 | "-----1234\r\n" + 71 | "Content-Disposition: form-data; name=\"multi\"\r\n" + 72 | "\r\n" + 73 | "value2\r\n" + 74 | "-----1234--\r\n"; 75 | // @formatter:on 76 | final var bytes = text.getBytes(StandardCharsets.US_ASCII); 77 | final ActionRequest request = new JavaxPortletMockActionRequest(bytes, Constants.CONTENT_TYPE); 78 | 79 | final var mappedParameters = upload.parseParameterMap(request); 80 | assertTrue(mappedParameters.containsKey("file")); 81 | assertEquals(1, mappedParameters.get("file").size()); 82 | 83 | assertTrue(mappedParameters.containsKey("field")); 84 | assertEquals(1, mappedParameters.get("field").size()); 85 | 86 | assertTrue(mappedParameters.containsKey("multi")); 87 | assertEquals(2, mappedParameters.get("multi").size()); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/site/xdoc/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 21 | 22 | 23 | Home 24 | Martin Cooper 25 | 26 | 27 | 28 |
29 |

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

34 |

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

42 |

43 | Starting with version 1.3, FileUpload handles 44 | RFC 2047 encoded header values. 45 |

46 | 47 |

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

48 | 49 | File to upload:
50 | Notes about the file:
51 |
52 | to upload the file! 53 | ]]> 54 |
55 | 56 |
57 |

The following documentation is available:

58 | 66 |

You can also browse the Git repository.

67 |
68 | 69 |
70 |
    71 |
  • Download the binary and source distributions from the 72 | download site. 73 |
  • 74 |
75 | 79 |
80 | 81 |
82 |

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

89 |

90 | Issues may be reported via ASF JIRA. 91 |

92 |
93 | 94 | 95 |
96 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/FileItemHeadersTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertFalse; 21 | import static org.junit.jupiter.api.Assertions.assertNull; 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | 24 | import java.util.Iterator; 25 | 26 | import org.junit.jupiter.api.Test; 27 | 28 | /** 29 | * Tests {@link FileItemHeaders} and {@link FileItemHeadersImpl}. 30 | */ 31 | class FileItemHeadersTest { 32 | 33 | /** 34 | * @throws Exception 35 | */ 36 | @Test 37 | void testFileItemHeaders() throws Exception { 38 | final var mutableFileItemHeaders = new FileItemHeadersImpl(); 39 | mutableFileItemHeaders.addHeader("Content-Disposition", "form-data; name=\"FileItem\"; filename=\"file1.txt\""); 40 | mutableFileItemHeaders.addHeader("Content-Type", "text/plain"); 41 | 42 | mutableFileItemHeaders.addHeader("TestHeader", "headerValue1"); 43 | mutableFileItemHeaders.addHeader("TestHeader", "headerValue2"); 44 | mutableFileItemHeaders.addHeader("TestHeader", "headerValue3"); 45 | mutableFileItemHeaders.addHeader("testheader", "headerValue4"); 46 | 47 | final var headerNameIterator = mutableFileItemHeaders.getHeaderNames(); 48 | assertEquals("content-disposition", headerNameIterator.next()); 49 | assertEquals("content-type", headerNameIterator.next()); 50 | assertEquals("testheader", headerNameIterator.next()); 51 | assertFalse(headerNameIterator.hasNext()); 52 | 53 | assertEquals(mutableFileItemHeaders.getHeader("Content-Disposition"), "form-data; name=\"FileItem\"; filename=\"file1.txt\""); 54 | assertEquals(mutableFileItemHeaders.getHeader("Content-Type"), "text/plain"); 55 | assertEquals(mutableFileItemHeaders.getHeader("content-type"), "text/plain"); 56 | assertEquals(mutableFileItemHeaders.getHeader("TestHeader"), "headerValue1"); 57 | assertNull(mutableFileItemHeaders.getHeader("DummyHeader")); 58 | 59 | Iterator headerValueEnumeration; 60 | 61 | headerValueEnumeration = mutableFileItemHeaders.getHeaders("Content-Type"); 62 | assertTrue(headerValueEnumeration.hasNext()); 63 | assertEquals(headerValueEnumeration.next(), "text/plain"); 64 | assertFalse(headerValueEnumeration.hasNext()); 65 | 66 | headerValueEnumeration = mutableFileItemHeaders.getHeaders("content-type"); 67 | assertTrue(headerValueEnumeration.hasNext()); 68 | assertEquals(headerValueEnumeration.next(), "text/plain"); 69 | assertFalse(headerValueEnumeration.hasNext()); 70 | 71 | headerValueEnumeration = mutableFileItemHeaders.getHeaders("TestHeader"); 72 | assertTrue(headerValueEnumeration.hasNext()); 73 | assertEquals(headerValueEnumeration.next(), "headerValue1"); 74 | assertTrue(headerValueEnumeration.hasNext()); 75 | assertEquals(headerValueEnumeration.next(), "headerValue2"); 76 | assertTrue(headerValueEnumeration.hasNext()); 77 | assertEquals(headerValueEnumeration.next(), "headerValue3"); 78 | assertTrue(headerValueEnumeration.hasNext()); 79 | assertEquals(headerValueEnumeration.next(), "headerValue4"); 80 | assertFalse(headerValueEnumeration.hasNext()); 81 | 82 | headerValueEnumeration = mutableFileItemHeaders.getHeaders("DummyHeader"); 83 | assertFalse(headerValueEnumeration.hasNext()); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | /** 23 | * Provides access to a file or form item that was received within a {@code multipart/form-data} POST request. 24 | *

25 | * The items contents are retrieved by calling {@link #getInputStream()}. 26 | *

27 | *

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

30 | *

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

34 | */ 35 | public interface FileItemInput extends FileItemHeadersProvider { 36 | 37 | /** 38 | * This exception is thrown, if an attempt is made to read data from the {@link InputStream}, which has been returned by 39 | * {@link FileItemInput#getInputStream()}, after {@link java.util.Iterator#hasNext()} has been invoked on the iterator, which created the 40 | * {@link FileItemInput}. 41 | */ 42 | class ItemSkippedException extends FileUploadException { 43 | 44 | /** 45 | * The exceptions serial version UID, which is being used when serializing an exception instance. 46 | */ 47 | private static final long serialVersionUID = 2; 48 | 49 | /** 50 | * Constructs an instance with a given detail message. 51 | * 52 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) 53 | */ 54 | ItemSkippedException(final String message) { 55 | super(message); 56 | } 57 | 58 | } 59 | 60 | /** 61 | * Gets the content type passed by the browser or {@code null} if not defined. 62 | * 63 | * @return The content type passed by the browser or {@code null} if not defined. 64 | */ 65 | String getContentType(); 66 | 67 | /** 68 | * Gets the name of the field in the multipart form corresponding to this file item. 69 | * 70 | * @return The name of the form field. 71 | */ 72 | String getFieldName(); 73 | 74 | /** 75 | * Opens an {@link InputStream}, which allows to read the items contents. 76 | * 77 | * @return The input stream, from which the items data may be read. 78 | * @throws IllegalStateException The method was already invoked on this item. It is not possible to recreate the data stream. 79 | * @throws IOException An I/O error occurred. 80 | * @see ItemSkippedException 81 | */ 82 | InputStream getInputStream() throws IOException; 83 | 84 | /** 85 | * Gets the original file name in the client's file system, as provided by the browser (or other client software). In most cases, this will be the base file 86 | * name, without path information. However, some clients, such as the Opera browser, do include path information. 87 | * 88 | * @return The original file name in the client's file system. 89 | */ 90 | String getName(); 91 | 92 | /** 93 | * Tests whether or not a {@code FileItem} instance represents a simple form field. 94 | * 95 | * @return {@code true} if the instance represents a simple form field; {@code false} if it represents an uploaded file. 96 | */ 97 | boolean isFormField(); 98 | 99 | } 100 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/QuotedPrintableDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | 22 | /** 23 | */ 24 | final class QuotedPrintableDecoder { 25 | 26 | /** 27 | * The shift value required to create the upper nibble from the first of 2 byte values converted from ASCII hex. 28 | */ 29 | private static final int UPPER_NIBBLE_SHIFT = Byte.SIZE / 2; 30 | 31 | /** 32 | * Decodes the encoded byte data writing it to the given output stream. 33 | * 34 | * @param data The array of byte data to decode. 35 | * @param out The output stream used to return the decoded data. 36 | * @return the number of bytes produced. 37 | * @throws IOException if an IO error occurs 38 | */ 39 | public static int decode(final byte[] data, final OutputStream out) throws IOException { 40 | var off = 0; 41 | final var length = data.length; 42 | final var endOffset = off + length; 43 | var bytesWritten = 0; 44 | 45 | while (off < endOffset) { 46 | final var ch = data[off++]; 47 | 48 | // space characters were translated to '_' on encode, so we need to translate them back. 49 | if (ch == '_') { 50 | out.write(' '); 51 | } else if (ch == '=') { 52 | // we found an encoded character. Reduce the 3 char sequence to one. 53 | // but first, make sure we have two characters to work with. 54 | if (off + 1 >= endOffset) { 55 | throw new IOException("Invalid quoted printable encoding; truncated escape sequence"); 56 | } 57 | 58 | final var b1 = data[off++]; 59 | final var b2 = data[off++]; 60 | 61 | // we've found an encoded carriage return. The next char needs to be a newline 62 | if (b1 == '\r') { 63 | if (b2 != '\n') { 64 | throw new IOException("Invalid quoted printable encoding; CR must be followed by LF"); 65 | } 66 | // this was a soft linebreak inserted by the encoding. We just toss this away 67 | // on decode. 68 | } else { 69 | // this is a hex pair we need to convert back to a single byte. 70 | final var c1 = hexToBinary(b1); 71 | final var c2 = hexToBinary(b2); 72 | out.write(c1 << UPPER_NIBBLE_SHIFT | c2); 73 | // 3 bytes in, one byte out 74 | bytesWritten++; 75 | } 76 | } else { 77 | // simple character, just write it out. 78 | out.write(ch); 79 | bytesWritten++; 80 | } 81 | } 82 | 83 | return bytesWritten; 84 | } 85 | 86 | /** 87 | * Converts a hexadecimal digit to the binary value it represents. 88 | * 89 | * @param b the ASCII hexadecimal byte to convert (0-0, A-F, a-f) 90 | * @return the int value of the hexadecimal byte, 0-15 91 | * @throws IOException if the byte is not a valid hexadecimal digit. 92 | */ 93 | private static int hexToBinary(final byte b) throws IOException { 94 | // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE 95 | final var i = Character.digit((char) b, 16); 96 | if (i == -1) { 97 | throw new IOException("Invalid quoted printable encoding: not a valid hex digit: " + b); 98 | } 99 | return i; 100 | } 101 | 102 | /** 103 | * Hidden constructor, this class must not be instantiated. 104 | */ 105 | private QuotedPrintableDecoder() { 106 | // do nothing 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/QuotedPrintableDecoderTestCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertArrayEquals; 20 | import static org.junit.jupiter.api.Assertions.assertThrows; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | import static org.junit.jupiter.api.Assertions.fail; 23 | 24 | import java.io.ByteArrayOutputStream; 25 | import java.io.IOException; 26 | import java.nio.charset.StandardCharsets; 27 | 28 | import org.junit.jupiter.api.Test; 29 | 30 | /** 31 | */ 32 | public final class QuotedPrintableDecoderTestCase { 33 | 34 | private static void assertEncoded(final String clearText, final String encoded) throws Exception { 35 | final var expected = clearText.getBytes(StandardCharsets.US_ASCII); 36 | 37 | final var out = new ByteArrayOutputStream(encoded.length()); 38 | final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII); 39 | QuotedPrintableDecoder.decode(encodedData, out); 40 | final var actual = out.toByteArray(); 41 | 42 | assertArrayEquals(expected, actual); 43 | } 44 | 45 | private static void assertIOException(final String messageText, final String encoded) { 46 | final var out = new ByteArrayOutputStream(encoded.length()); 47 | final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII); 48 | try { 49 | QuotedPrintableDecoder.decode(encodedData, out); 50 | fail("Expected IOException"); 51 | } catch (final IOException e) { 52 | final var em = e.getMessage(); 53 | assertTrue(em.contains(messageText), "Expected to find " + messageText + " in '" + em + "'"); 54 | } 55 | } 56 | 57 | @Test 58 | void testBasicEncodeDecode() throws Exception { 59 | assertEncoded("= Hello there =\r\n", "=3D Hello there =3D=0D=0A"); 60 | } 61 | 62 | @Test 63 | void testEmptyDecode() throws Exception { 64 | assertEncoded("", ""); 65 | } 66 | 67 | @Test 68 | void testInvalidCharDecode() { 69 | assertThrows(IOException.class, () -> assertEncoded("=\r\n", "=3D=XD=XA")); 70 | } 71 | 72 | @Test 73 | void testInvalidQuotedPrintableEncoding() throws Exception { 74 | assertIOException("truncated escape sequence", "YWJjMTIzXy0uKn4hQCMkJV4mKCkre31cIlxcOzpgLC9bXQ=="); 75 | } 76 | 77 | @Test 78 | void testInvalidSoftBreak1() throws Exception { 79 | assertIOException("CR must be followed by LF", "=\r\r"); 80 | } 81 | 82 | @Test 83 | void testInvalidSoftBreak2() throws Exception { 84 | assertIOException("CR must be followed by LF", "=\rn"); 85 | } 86 | 87 | @Test 88 | void testPlainDecode() throws Exception { 89 | // spaces are allowed in encoded data 90 | // There are special rules for trailing spaces; these are not currently implemented. 91 | assertEncoded("The quick brown fox jumps over the lazy dog.", "The quick brown fox jumps over the lazy dog."); 92 | } 93 | 94 | /** 95 | * This is NOT supported by Commons-Codec, see CODEC-121. 96 | * 97 | * @throws Exception 98 | * @see CODEC-121 99 | */ 100 | @Test 101 | void testSoftLineBreakDecode() throws Exception { 102 | assertEncoded("If you believe that truth=beauty, then surely mathematics is the most " + "beautiful branch of philosophy.", 103 | "If you believe that truth=3Dbeauty, then " + "surely=20=\r\nmathematics is the most beautiful branch of philosophy."); 104 | } 105 | 106 | @Test 107 | void testTruncatedEscape() throws Exception { 108 | assertIOException("truncated", "=1"); 109 | } 110 | 111 | @Test 112 | void testUnsafeDecode() throws Exception { 113 | assertEncoded("=\r\n", "=3D=0D=0A"); 114 | } 115 | 116 | @Test 117 | void testUnsafeDecodeLowerCase() throws Exception { 118 | assertEncoded("=\r\n", "=3d=0d=0a"); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.fileupload2.core; 18 | 19 | import java.io.IOException; 20 | 21 | import javax.naming.SizeLimitExceededException; 22 | 23 | import org.apache.commons.io.function.IOIterator; 24 | 25 | /** 26 | * An iterator, as returned by {@link AbstractFileUpload#getItemIterator(RequestContext)}. 27 | */ 28 | public interface FileItemInputIterator extends IOIterator { 29 | 30 | /** 31 | * Gets the maximum size of a single file. An {@link FileUploadByteCountLimitException} will be thrown, if there is an uploaded file, which is exceeding 32 | * this value. By default, this value will be copied from the {@link AbstractFileUpload#getMaxFileSize() FileUploadBase} object, however, the user may 33 | * replace the default value with a request specific value by invoking {@link #setFileSizeMax(long)} on this object. 34 | * 35 | * @return The maximum size of a single, uploaded file. The value -1 indicates "unlimited". 36 | */ 37 | long getFileSizeMax(); 38 | 39 | /** 40 | * Gets the maximum size of the complete HTTP request. A {@link SizeLimitExceededException} will be thrown, if the HTTP request will exceed this value. By 41 | * default, this value will be copied from the {@link AbstractFileUpload#getMaxSize() FileUploadBase} object, however, the user may replace the default 42 | * value with a request specific value by invoking {@link #setSizeMax(long)} on this object. 43 | * 44 | * @return The maximum size of the complete HTTP request. The value -1 indicates "unlimited". 45 | */ 46 | long getSizeMax(); 47 | 48 | /** 49 | * Tests whether another instance of {@link FileItemInput} is available. 50 | * 51 | * @throws FileUploadException Parsing or processing the file item failed. 52 | * @throws IOException Reading the file item failed. 53 | * @return True, if one or more additional file items are available, otherwise false. 54 | */ 55 | @Override 56 | boolean hasNext() throws IOException; 57 | 58 | /** 59 | * Returns the next available {@link FileItemInput}. 60 | * 61 | * @throws java.util.NoSuchElementException No more items are available. Use {@link #hasNext()} to prevent this exception. 62 | * @throws FileUploadException Parsing or processing the file item failed. 63 | * @throws IOException Reading the file item failed. 64 | * @return FileItemInput instance, which provides access to the next file item. 65 | */ 66 | @Override 67 | FileItemInput next() throws IOException; 68 | 69 | /** 70 | * Sets the maximum size of a single file. An {@link FileUploadByteCountLimitException} will be thrown, if there is an uploaded file, which is exceeding 71 | * this value. By default, this value will be copied from the {@link AbstractFileUpload#getMaxFileSize() FileUploadBase} object, however, the user may 72 | * replace the default value with a request specific value by invoking {@link #setFileSizeMax(long)} on this object, so there is no need to configure it 73 | * here. 74 | *

75 | * Note: Changing this value doesn't affect files, that have already been uploaded. 76 | *

77 | * 78 | * @param fileSizeMax The maximum size of a single, uploaded file. The value -1 indicates "unlimited". 79 | */ 80 | void setFileSizeMax(long fileSizeMax); 81 | 82 | /** 83 | * Sets the maximum size of the complete HTTP request. A {@link SizeLimitExceededException} will be thrown, if the HTTP request will exceed this value. By 84 | * default, this value will be copied from the {@link AbstractFileUpload#getMaxSize() FileUploadBase} object, however, the user may replace the default 85 | * value with a request specific value by invoking {@link #setSizeMax(long)} on this object. 86 | *

87 | * Note: Setting the maximum size on this object will work only, if the iterator is not yet initialized. In other words: If the methods 88 | * {@link #hasNext()}, {@link #next()} have not yet been invoked. 89 | *

90 | * 91 | * @param sizeMax The maximum size of the complete HTTP request. The value -1 indicates "unlimited". 92 | */ 93 | void setSizeMax(long sizeMax); 94 | } 95 | -------------------------------------------------------------------------------- /commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MultipartStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.commons.fileupload2.core; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertEquals; 21 | import static org.junit.jupiter.api.Assertions.assertNotNull; 22 | import static org.junit.jupiter.api.Assertions.assertThrows; 23 | import static org.junit.jupiter.api.Assertions.fail; 24 | 25 | import java.io.ByteArrayInputStream; 26 | import java.io.InputStream; 27 | import java.nio.charset.StandardCharsets; 28 | 29 | import org.apache.commons.io.output.NullOutputStream; 30 | import org.junit.jupiter.api.Test; 31 | 32 | /** 33 | * Tests {@link MultipartInput}. 34 | */ 35 | class MultipartStreamTest { 36 | 37 | static private final String BOUNDARY_TEXT = "myboundary"; 38 | 39 | /** 40 | * Tests whether the maxSize works. 41 | */ 42 | @Test 43 | public void testPartHeaderSizeMaxLimit() throws Exception { 44 | final String request = "-----1234\r\n" + "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" + "Content-Type: text/whatever\r\n" 45 | + "Content-Length: 10\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "-----1234\r\n" 46 | + "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" + "Content-Type: text/whatever\r\n" + "\r\n" 47 | + "This is the content of the file\n" + "\r\n" + "-----1234--\r\n"; 48 | final byte[] byteContents = request.getBytes(StandardCharsets.UTF_8); 49 | final InputStream input = new ByteArrayInputStream(byteContents); 50 | final byte[] boundary = "---1234".getBytes(); 51 | final MultipartInput mi = MultipartInput.builder().setInputStream(input).setBoundary(boundary).setMaxPartHeaderSize(100).get(); 52 | assertNotNull(mi); 53 | try { 54 | boolean nextPart = mi.skipPreamble(); 55 | while (nextPart) { 56 | final String headers = mi.readHeaders(); 57 | System.out.print("Headers=" + headers.length() + ", " + headers); 58 | assertNotNull(headers); 59 | // process headers 60 | // create some output stream 61 | mi.readBodyData(NullOutputStream.INSTANCE); 62 | nextPart = mi.readBoundary(); 63 | } 64 | fail("Expected Exception"); 65 | } catch (final FileUploadSizeException fuse) { 66 | assertEquals(100, fuse.getPermitted()); 67 | } 68 | } 69 | 70 | @Test 71 | void testSmallBuffer() { 72 | final var strData = "foobar"; 73 | final var contents = strData.getBytes(); 74 | final InputStream input = new ByteArrayInputStream(contents); 75 | final var boundary = BOUNDARY_TEXT.getBytes(); 76 | final var iBufSize = 1; 77 | assertThrows(IllegalArgumentException.class, () -> MultipartInput.builder().setInputStream(input).setBoundary(boundary).setBufferSize(iBufSize) 78 | .setProgressNotifier(new MultipartInput.ProgressNotifier(null, contents.length)).get()); 79 | } 80 | 81 | @Test 82 | void testThreeParamConstructor() throws Exception { 83 | final var strData = "foobar"; 84 | final var contents = strData.getBytes(); 85 | final InputStream input = new ByteArrayInputStream(contents); 86 | final var boundary = BOUNDARY_TEXT.getBytes(); 87 | final var iBufSize = boundary.length + MultipartInput.BOUNDARY_PREFIX.length + 1; 88 | final var ms = MultipartInput.builder().setInputStream(input).setBoundary(boundary).setBufferSize(iBufSize) 89 | .setProgressNotifier(new MultipartInput.ProgressNotifier(null, contents.length)).get(); 90 | assertNotNull(ms); 91 | } 92 | 93 | @Test 94 | void testTwoParamConstructor() throws Exception { 95 | final var strData = "foobar"; 96 | final var contents = strData.getBytes(); 97 | final InputStream input = new ByteArrayInputStream(contents); 98 | final var boundary = BOUNDARY_TEXT.getBytes(); 99 | final var ms = MultipartInput.builder().setInputStream(input).setBoundary(boundary) 100 | .setProgressNotifier(new MultipartInput.ProgressNotifier(null, contents.length)).get(); 101 | assertNotNull(ms); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/conf/pmd-ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 22 | 23 | This ruleset checks the code for discouraged programming constructs. 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | --------------------------------------------------------------------------------