Quick fix for the commons fileupload component that cannot handle custom head information

  • 2020-04-01 02:12:08
  • OfStack

Jakarta Commons fileupload component can handle HTTP requests and responses, most of the time are used to handle file uploads, but recently found that when our custom file upload, diy mime information, add a custom file upload the head node, the fileupload component can't get the head of the custom nodes, after carefully analyzing the fileupload component source code, find core method in FileUploadBase file findNextItem method, The problem is that after the fileupload component parsed the custom head node, it forgot to pass it to FileItemStreamImpl, which can be fixed with a few revisions.

/** Parse file list 
         * Called for finding the nex item, if any.
         * @return True, if an next item was found, otherwise false.
         * @throws IOException An I/O error occurred.
         */
        private boolean findNextItem() throws IOException {
            if (eof) {
                return false;
            }
            if (currentItem != null) {
                currentItem.close();
                currentItem = null;
            }
            for (;;) {
                boolean nextPart;
                if (skipPreamble) {
                    nextPart = multi.skipPreamble();
                } else {
                    nextPart = multi.readBoundary();
                }
                if (!nextPart) {
                    if (currentFieldName == null) {
                        // Outer multipart terminated -> No more data
                        eof = true;
                        return false;
                    }
                    // Inner multipart terminated -> Return to parsing the outer
                    multi.setBoundary(boundary);
                    currentFieldName = null;
                    continue;
                }
                FileItemHeaders headers = getParsedHeaders(multi.readHeaders());
                if (currentFieldName == null) {
                    // We're parsing the outer multipart
                    String fieldName = getFieldName(headers);
                    if (fieldName != null) {
                        String subContentType = headers.getHeader(CONTENT_TYPE);
                        if (subContentType != null
                                &&  subContentType.toLowerCase()
                                        .startsWith(MULTIPART_MIXED)) {
                            currentFieldName = fieldName;
                            // Multiple files associated with this field name
                            byte[] subBoundary = getBoundary(subContentType);
                            multi.setBoundary(subBoundary);
                            skipPreamble = true;
                            continue;
                        }
                        String fileName = getFileName(headers);
                        currentItem = new FileItemStreamImpl(fileName,
                                fieldName, headers.getHeader(CONTENT_TYPE),
                                fileName == null, getContentLength(headers));
                        notifier.noteItem();
                        itemValid = true;
                        return true;
                    }
                } else {
                    String fileName = getFileName(headers);
                    if (fileName != null) {
                             //The code needs to be revised here
                        //This is the original code, no headers passed in
                        //currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers));
                        //This is the new code, and we're going to pass in the header
                        currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers),headers);
                        notifier.noteItem();
                        itemValid = true;
                        return true;
                    }
                }
                multi.discardBodyData();
            }
        }

 

            
            FileItemStreamImpl(String pName, String pFieldName,
                    String pContentType, boolean pFormField,
                    long pContentLength) throws IOException {
                name = pName;
                fieldName = pFieldName;
                contentType = pContentType;
                formField = pFormField;
                final ItemInputStream itemStream = multi.newInputStream();
                InputStream istream = itemStream;
                if (fileSizeMax != -1) {
                    if (pContentLength != -1
                            &&  pContentLength > fileSizeMax) {
                        FileUploadException e =
                            new FileSizeLimitExceededException(
                                "The field " + fieldName
                                + " exceeds its maximum permitted "
                                + " size of " + fileSizeMax
                                + " characters.",
                                pContentLength, fileSizeMax);
                        throw new FileUploadIOException(e);
                    }
                    istream = new LimitedInputStream(istream, fileSizeMax) {
                        protected void raiseError(long pSizeMax, long pCount)
                                throws IOException {
                            itemStream.close(true);
                            FileUploadException e =
                                new FileSizeLimitExceededException(
                                    "The field " + fieldName
                                    + " exceeds its maximum permitted "
                                    + " size of " + pSizeMax
                                    + " characters.",
                                    pCount, pSizeMax);
                            throw new FileUploadIOException(e);
                        }
                    };
                }
                stream = istream;
            }

 

            
            FileItemStreamImpl(String pName, String pFieldName,
                    String pContentType, boolean pFormField,
                    long pContentLength,FileItemHeaders headers) throws IOException {
                name = pName;
                fieldName = pFieldName;
                contentType = pContentType;
                formField = pFormField;
                if(headers!=null){
                        this.headers = headers;
                }
                final ItemInputStream itemStream = multi.newInputStream();
                InputStream istream = itemStream;
                if (fileSizeMax != -1) {
                    if (pContentLength != -1
                            &&  pContentLength > fileSizeMax) {
                        FileUploadException e =
                            new FileSizeLimitExceededException(
                                "The field " + fieldName
                                + " exceeds its maximum permitted "
                                + " size of " + fileSizeMax
                                + " characters.",
                                pContentLength, fileSizeMax);
                        throw new FileUploadIOException(e);
                    }
                    istream = new LimitedInputStream(istream, fileSizeMax) {
                        protected void raiseError(long pSizeMax, long pCount)
                                throws IOException {
                            itemStream.close(true);
                            FileUploadException e =
                                new FileSizeLimitExceededException(
                                    "The field " + fieldName
                                    + " exceeds its maximum permitted "
                                    + " size of " + pSizeMax
                                    + " characters.",
                                    pCount, pSizeMax);
                            throw new FileUploadIOException(e);
                        }
                    };
                }
                stream = istream;
            }

Related articles: