FileItemInputImpl.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.fileupload2.core;
- import java.io.IOException;
- import java.io.InputStream;
- import java.nio.file.InvalidPathException;
- import org.apache.commons.io.input.BoundedInputStream;
- /**
- * Default implementation of {@link FileItemInput}.
- */
- class FileItemInputImpl implements FileItemInput {
- /**
- * The File Item iterator implementation.
- *
- * @see FileItemInputIteratorImpl
- */
- private final FileItemInputIteratorImpl fileItemInputIteratorImpl;
- /**
- * The file items content type.
- */
- private final String contentType;
- /**
- * The file items field name.
- */
- private final String fieldName;
- /**
- * The file items file name.
- */
- private final String fileName;
- /**
- * Whether the file item is a form field.
- */
- private final boolean formField;
- /**
- * The file items input stream.
- */
- private final InputStream inputStream;
- /**
- * The file items input stream closed flag.
- */
- private boolean inputStreamClosed;
- /**
- * The headers, if any.
- */
- private FileItemHeaders headers;
- /**
- * Creates a new instance.
- *
- * @param fileItemIterator The {@link FileItemInputIteratorImpl iterator}, which returned this file item.
- * @param fileName The items file name, or null.
- * @param fieldName The items field name.
- * @param contentType The items content type, or null.
- * @param formField Whether the item is a form field.
- * @param contentLength The items content length, if known, or -1
- * @throws IOException Creating the file item failed.
- * @throws FileUploadException Parsing the incoming data stream failed.
- */
- FileItemInputImpl(final FileItemInputIteratorImpl fileItemIterator, final String fileName, final String fieldName, final String contentType,
- final boolean formField, final long contentLength) throws FileUploadException, IOException {
- this.fileItemInputIteratorImpl = fileItemIterator;
- this.fileName = fileName;
- this.fieldName = fieldName;
- this.contentType = contentType;
- this.formField = formField;
- final var fileSizeMax = fileItemInputIteratorImpl.getFileSizeMax();
- if (fileSizeMax != -1 && contentLength != -1 && contentLength > fileSizeMax) {
- throw new FileUploadByteCountLimitException(String.format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, fileSizeMax),
- contentLength, fileSizeMax, fileName, fieldName);
- }
- // OK to construct stream now
- final var itemInputStream = fileItemInputIteratorImpl.getMultiPartInput().newInputStream();
- InputStream istream = itemInputStream;
- if (fileSizeMax != -1) {
- // onMaxLength will be called when the length is greater than _or equal to_ the supplied maxLength.
- // Because we only want to throw an exception when the length is greater than fileSizeMax, we
- // increment fileSizeMax by 1.
- // @formatter:off
- istream = BoundedInputStream.builder()
- .setInputStream(istream)
- .setMaxCount(fileSizeMax + 1)
- .setOnMaxCount((max, count) -> {
- itemInputStream.close(true);
- throw new FileUploadByteCountLimitException(
- String.format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, fileSizeMax), count, fileSizeMax, fileName,
- fieldName);
- })
- .get();
- // @formatter:on
- }
- this.inputStream = istream;
- }
- /**
- * Closes the file item.
- *
- * @throws IOException An I/O error occurred.
- */
- public void close() throws IOException {
- inputStream.close();
- inputStreamClosed = true;
- }
- /**
- * Gets the content type, or null.
- *
- * @return Content type, if known, or null.
- */
- @Override
- public String getContentType() {
- return contentType;
- }
- /**
- * Gets the items field name.
- *
- * @return Field name.
- */
- @Override
- public String getFieldName() {
- return fieldName;
- }
- /**
- * Gets the headers.
- *
- * @return The items header object
- */
- @Override
- public FileItemHeaders getHeaders() {
- return headers;
- }
- /**
- * Gets the input stream, which may be used to read the items contents.
- *
- * @return Opened input stream.
- * @throws IOException An I/O error occurred.
- */
- @Override
- public InputStream getInputStream() throws IOException {
- if (inputStreamClosed) {
- throw new FileItemInput.ItemSkippedException("getInputStream()");
- }
- return inputStream;
- }
- /**
- * Gets the file name.
- *
- * @return File name, if known, or null.
- * @throws InvalidPathException The file name is invalid, for example it contains a NUL character, which might be an indicator of a security attack. If you
- * intend to use the file name anyways, catch the exception and use InvalidPathException#getInput().
- */
- @Override
- public String getName() {
- return DiskFileItem.checkFileName(fileName);
- }
- /**
- * Tests whether this is a form field.
- *
- * @return True, if the item is a form field, otherwise false.
- */
- @Override
- public boolean isFormField() {
- return formField;
- }
- /**
- * Sets the file item headers.
- *
- * @param headers The items header object
- */
- @Override
- public FileItemInputImpl setHeaders(final FileItemHeaders headers) {
- this.headers = headers;
- return this;
- }
- }