Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadBase.java.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadBase.java.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadBase.java.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1,1538 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>FileUploadBase.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.source.html" class="el_package">org.apache.commons.fileupload</a> > <span class= "el_source">FileUploadBase.java</span></div><h1>FileUploadBase.java</h1><pre class="source lang-java linenums">/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload; + +import static java.lang.String.format; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.fileupload.MultipartStream.ItemInputStream; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.fileupload.servlet.ServletRequestContext; +import org.apache.commons.fileupload.util.Closeable; +import org.apache.commons.fileupload.util.FileItemHeadersImpl; +import org.apache.commons.fileupload.util.LimitedInputStream; +import org.apache.commons.fileupload.util.Streams; +import org.apache.commons.io.IOUtils; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(RequestContext)} to acquire a list of {@link + * org.apache.commons.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + */ +<span class="fc" id="L57">public abstract class FileUploadBase {</span> + + // ---------------------------------------------------------- Class methods + + /** + * <p>Utility method that determines whether the request contains multipart + * content.</p> + * + * <p><strong>NOTE:</strong>This method will be moved to the + * <code>ServletFileUpload</code> class after the FileUpload 1.1 release. + * Unfortunately, since this method is static, it is not possible to + * provide its replacement until this method is removed.</p> + * + * @param ctx The request context to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(RequestContext ctx) { +<span class="nc" id="L76"> String contentType = ctx.getContentType();</span> +<span class="nc bnc" id="L77" title="All 2 branches missed."> if (contentType == null) {</span> +<span class="nc" id="L78"> return false;</span> + } +<span class="nc bnc" id="L80" title="All 2 branches missed."> if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) {</span> +<span class="nc" id="L81"> return true;</span> + } +<span class="nc" id="L83"> return false;</span> + } + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param req The servlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + * + * @deprecated 1.1 Use the method on <code>ServletFileUpload</code> instead. + */ + @Deprecated + public static boolean isMultipartContent(HttpServletRequest req) { +<span class="nc" id="L99"> return ServletFileUpload.isMultipartContent(req);</span> + } + + // ----------------------------------------------------- Manifest constants + + /** + * HTTP content type header name. + */ + public static final String CONTENT_TYPE = "Content-type"; + + /** + * HTTP content disposition header name. + */ + public static final String CONTENT_DISPOSITION = "Content-disposition"; + + /** + * HTTP content length header name. + */ + public static final String CONTENT_LENGTH = "Content-length"; + + /** + * Content-disposition value for form data. + */ + public static final String FORM_DATA = "form-data"; + + /** + * Content-disposition value for file attachment. + */ + public static final String ATTACHMENT = "attachment"; + + /** + * Part of HTTP content type header. + */ + public static final String MULTIPART = "multipart/"; + + /** + * HTTP content type header for multipart forms. + */ + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + + /** + * HTTP content type header for multiple uploads. + */ + public static final String MULTIPART_MIXED = "multipart/mixed"; + + /** + * The maximum length of a single header line that will be parsed + * (1024 bytes). + * @deprecated This constant is no longer used. As of commons-fileupload + * 1.2, the only applicable limit is the total size of a parts headers, + * {@link MultipartStream#HEADER_PART_SIZE_MAX}. + */ + @Deprecated + public static final int MAX_HEADER_SIZE = 1024; + + // ----------------------------------------------------------- Data members + + /** + * The maximum size permitted for the complete request, as opposed to + * {@link #fileSizeMax}. A value of -1 indicates no maximum. + */ +<span class="fc" id="L160"> private long sizeMax = -1;</span> + + /** + * The maximum size permitted for a single uploaded file, as opposed + * to {@link #sizeMax}. A value of -1 indicates no maximum. + */ +<span class="fc" id="L166"> private long fileSizeMax = -1;</span> + + /** + * The maximum permitted number of files that may be uploaded in a single + * request. A value of -1 indicates no maximum. + */ +<span class="fc" id="L172"> private long fileCountMax = -1;</span> + + /** + * The content encoding to use when reading part headers. + */ + private String headerEncoding; + + /** + * The progress listener. + */ + private ProgressListener listener; + + // ----------------------------------------------------- Property accessors + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public abstract FileItemFactory getFileItemFactory(); + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public abstract void setFileItemFactory(FileItemFactory factory); + + /** + * Returns the maximum allowed size of a complete request, as opposed + * to {@link #getFileSizeMax()}. + * + * @return The maximum allowed size, in bytes. The default value of + * -1 indicates, that there is no limit. + * + * @see #setSizeMax(long) + * + */ + public long getSizeMax() { +<span class="nc" id="L211"> return sizeMax;</span> + } + + /** + * Sets the maximum allowed size of a complete request, as opposed + * to {@link #setFileSizeMax(long)}. + * + * @param sizeMax The maximum allowed size, in bytes. The default value of + * -1 indicates, that there is no limit. + * + * @see #getSizeMax() + * + */ + public void setSizeMax(long sizeMax) { +<span class="fc" id="L225"> this.sizeMax = sizeMax;</span> +<span class="fc" id="L226"> }</span> + + /** + * Returns the maximum allowed size of a single uploaded file, + * as opposed to {@link #getSizeMax()}. + * + * @see #setFileSizeMax(long) + * @return Maximum size of a single uploaded file. + */ + public long getFileSizeMax() { +<span class="nc" id="L236"> return fileSizeMax;</span> + } + + /** + * Sets the maximum allowed size of a single uploaded file, + * as opposed to {@link #getSizeMax()}. + * + * @see #getFileSizeMax() + * @param fileSizeMax Maximum size of a single uploaded file. + */ + public void setFileSizeMax(long fileSizeMax) { +<span class="fc" id="L247"> this.fileSizeMax = fileSizeMax;</span> +<span class="fc" id="L248"> }</span> + + /** + * Returns the maximum number of files allowed in a single request. + * + * @return The maximum number of files allowed in a single request. + */ + public long getFileCountMax() { +<span class="nc" id="L256"> return fileCountMax;</span> + } + + /** + * Sets the maximum number of files allowed per request. + * + * @param fileCountMax The new limit. {@code -1} means no limit. + */ + public void setFileCountMax(final long fileCountMax) { +<span class="nc" id="L265"> this.fileCountMax = fileCountMax;</span> +<span class="nc" id="L266"> }</span> + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the request + * encoding is used. If that is also not specified, or <code>null</code>, + * the platform default encoding is used. + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { +<span class="nc" id="L278"> return headerEncoding;</span> + } + + /** + * Specifies the character encoding to be used when reading the headers of + * individual part. When not specified, or <code>null</code>, the request + * encoding is used. If that is also not specified, or <code>null</code>, + * the platform default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { +<span class="nc" id="L290"> headerEncoding = encoding;</span> +<span class="nc" id="L291"> }</span> + + // --------------------------------------------------------- Public methods + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param req The servlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated 1.1 Use {@link ServletFileUpload#parseRequest(HttpServletRequest)} instead. + */ + @Deprecated + public List<FileItem> parseRequest(HttpServletRequest req) + throws FileUploadException { +<span class="fc" id="L312"> return parseRequest(new ServletRequestContext(req));</span> + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param ctx The context for the request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(RequestContext ctx) + throws FileUploadException, IOException { + try { +<span class="fc" id="L334"> return new FileItemIteratorImpl(ctx);</span> +<span class="fc" id="L335"> } catch (FileUploadIOException e) {</span> + // unwrap encapsulated SizeException +<span class="fc" id="L337"> throw (FileUploadException) e.getCause();</span> + } + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param ctx The context for the request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List<FileItem> parseRequest(RequestContext ctx) + throws FileUploadException { +<span class="fc" id="L355"> List<FileItem> items = new ArrayList<FileItem>();</span> +<span class="fc" id="L356"> boolean successful = false;</span> + try { +<span class="fc" id="L358"> FileItemIterator iter = getItemIterator(ctx);</span> +<span class="fc" id="L359"> FileItemFactory fac = getFileItemFactory();</span> +<span class="fc" id="L360"> final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE];</span> +<span class="pc bpc" id="L361" title="1 of 2 branches missed."> if (fac == null) {</span> +<span class="nc" id="L362"> throw new NullPointerException("No FileItemFactory has been set.");</span> + } +<span class="fc bfc" id="L364" title="All 2 branches covered."> while (iter.hasNext()) {</span> +<span class="pc bpc" id="L365" title="1 of 2 branches missed."> if (items.size() == fileCountMax) {</span> + // The next item will exceed the limit. +<span class="nc" id="L367"> throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax());</span> + } +<span class="fc" id="L369"> final FileItemStream item = iter.next();</span> + // Don't use getName() here to prevent an InvalidFileNameException. +<span class="fc" id="L371"> final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;</span> +<span class="fc" id="L372"> FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(),</span> +<span class="fc" id="L373"> item.isFormField(), fileName);</span> +<span class="fc" id="L374"> items.add(fileItem);</span> + try { +<span class="fc" id="L376"> Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);</span> +<span class="fc" id="L377"> } catch (FileUploadIOException e) {</span> +<span class="fc" id="L378"> throw (FileUploadException) e.getCause();</span> +<span class="fc" id="L379"> } catch (IOException e) {</span> +<span class="fc" id="L380"> throw new IOFileUploadException(format("Processing of %s request failed. %s",</span> +<span class="fc" id="L381"> MULTIPART_FORM_DATA, e.getMessage()), e);</span> +<span class="fc" id="L382"> }</span> +<span class="fc" id="L383"> final FileItemHeaders fih = item.getHeaders();</span> +<span class="fc" id="L384"> fileItem.setHeaders(fih);</span> +<span class="fc" id="L385"> }</span> +<span class="fc" id="L386"> successful = true;</span> +<span class="fc" id="L387"> return items;</span> +<span class="nc" id="L388"> } catch (FileUploadIOException e) {</span> +<span class="nc" id="L389"> throw (FileUploadException) e.getCause();</span> +<span class="fc" id="L390"> } catch (IOException e) {</span> +<span class="fc" id="L391"> throw new FileUploadException(e.getMessage(), e);</span> + } finally { +<span class="fc bfc" id="L393" title="All 2 branches covered."> if (!successful) {</span> +<span class="fc bfc" id="L394" title="All 2 branches covered."> for (FileItem fileItem : items) {</span> + try { +<span class="fc" id="L396"> fileItem.delete();</span> +<span class="nc" id="L397"> } catch (Exception ignored) {</span> + // ignored TODO perhaps add to tracker delete failure list somehow? +<span class="fc" id="L399"> }</span> +<span class="fc" id="L400"> }</span> + } + } + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param ctx The context for the request to be parsed. + * + * @return A map of <code>FileItem</code> instances parsed from the request. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @since 1.3 + */ + public Map<String, List<FileItem>> parseParameterMap(RequestContext ctx) + throws FileUploadException { +<span class="fc" id="L420"> final List<FileItem> items = parseRequest(ctx);</span> +<span class="fc" id="L421"> final Map<String, List<FileItem>> itemsMap = new HashMap<String, List<FileItem>>(items.size());</span> + +<span class="fc bfc" id="L423" title="All 2 branches covered."> for (FileItem fileItem : items) {</span> +<span class="fc" id="L424"> String fieldName = fileItem.getFieldName();</span> +<span class="fc" id="L425"> List<FileItem> mappedItems = itemsMap.get(fieldName);</span> + +<span class="fc bfc" id="L427" title="All 2 branches covered."> if (mappedItems == null) {</span> +<span class="fc" id="L428"> mappedItems = new ArrayList<FileItem>();</span> +<span class="fc" id="L429"> itemsMap.put(fieldName, mappedItems);</span> + } + +<span class="fc" id="L432"> mappedItems.add(fileItem);</span> +<span class="fc" id="L433"> }</span> + +<span class="fc" id="L435"> return itemsMap;</span> + } + + // ------------------------------------------------------ Protected methods + + /** + * Retrieves the boundary from the <code>Content-type</code> header. + * + * @param contentType The value of the content type header from which to + * extract the boundary value. + * + * @return The boundary, as a byte array. + */ + protected byte[] getBoundary(String contentType) { +<span class="fc" id="L449"> ParameterParser parser = new ParameterParser();</span> +<span class="fc" id="L450"> parser.setLowerCaseNames(true);</span> + // Parameter parser can handle null input +<span class="fc" id="L452"> Map<String, String> params = parser.parse(contentType, new char[] {';', ','});</span> +<span class="fc" id="L453"> String boundaryStr = params.get("boundary");</span> + +<span class="fc bfc" id="L455" title="All 2 branches covered."> if (boundaryStr == null) {</span> +<span class="fc" id="L456"> return null;</span> + } + byte[] boundary; + try { +<span class="fc" id="L460"> boundary = boundaryStr.getBytes("ISO-8859-1");</span> +<span class="nc" id="L461"> } catch (UnsupportedEncodingException e) {</span> +<span class="nc" id="L462"> boundary = boundaryStr.getBytes(); // Intentionally falls back to default charset</span> +<span class="fc" id="L463"> }</span> +<span class="fc" id="L464"> return boundary;</span> + } + + /** + * Retrieves the file name from the <code>Content-disposition</code> + * header. + * + * @param headers A <code>Map</code> containing the HTTP request headers. + * + * @return The file name for the current <code>encapsulation</code>. + * @deprecated 1.2.1 Use {@link #getFileName(FileItemHeaders)}. + */ + @Deprecated + protected String getFileName(Map<String, String> headers) { +<span class="nc" id="L478"> return getFileName(getHeader(headers, CONTENT_DISPOSITION));</span> + } + + /** + * Retrieves the file name from the <code>Content-disposition</code> + * header. + * + * @param headers The HTTP headers object. + * + * @return The file name for the current <code>encapsulation</code>. + */ + protected String getFileName(FileItemHeaders headers) { +<span class="fc" id="L490"> return getFileName(headers.getHeader(CONTENT_DISPOSITION));</span> + } + + /** + * Returns the given content-disposition headers file name. + * @param pContentDisposition The content-disposition headers value. + * @return The file name + */ + private String getFileName(String pContentDisposition) { +<span class="fc" id="L499"> String fileName = null;</span> +<span class="pc bpc" id="L500" title="1 of 2 branches missed."> if (pContentDisposition != null) {</span> +<span class="fc" id="L501"> String cdl = pContentDisposition.toLowerCase(Locale.ENGLISH);</span> +<span class="pc bpc" id="L502" title="1 of 4 branches missed."> if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) {</span> +<span class="fc" id="L503"> ParameterParser parser = new ParameterParser();</span> +<span class="fc" id="L504"> parser.setLowerCaseNames(true);</span> + // Parameter parser can handle null input +<span class="fc" id="L506"> Map<String, String> params = parser.parse(pContentDisposition, ';');</span> +<span class="fc bfc" id="L507" title="All 2 branches covered."> if (params.containsKey("filename")) {</span> +<span class="fc" id="L508"> fileName = params.get("filename");</span> +<span class="fc bfc" id="L509" title="All 2 branches covered."> if (fileName != null) {</span> +<span class="fc" id="L510"> fileName = fileName.trim();</span> + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. +<span class="fc" id="L515"> fileName = "";</span> + } + } + } + } +<span class="fc" id="L520"> return fileName;</span> + } + + /** + * Retrieves the field name from the <code>Content-disposition</code> + * header. + * + * @param headers A <code>Map</code> containing the HTTP request headers. + * + * @return The field name for the current <code>encapsulation</code>. + */ + protected String getFieldName(FileItemHeaders headers) { +<span class="fc" id="L532"> return getFieldName(headers.getHeader(CONTENT_DISPOSITION));</span> + } + + /** + * Returns the field name, which is given by the content-disposition + * header. + * @param pContentDisposition The content-dispositions header value. + * @return The field jake + */ + private String getFieldName(String pContentDisposition) { +<span class="fc" id="L542"> String fieldName = null;</span> +<span class="pc bpc" id="L543" title="1 of 2 branches missed."> if (pContentDisposition != null</span> +<span class="pc bpc" id="L544" title="1 of 2 branches missed."> && pContentDisposition.toLowerCase(Locale.ENGLISH).startsWith(FORM_DATA)) {</span> +<span class="fc" id="L545"> ParameterParser parser = new ParameterParser();</span> +<span class="fc" id="L546"> parser.setLowerCaseNames(true);</span> + // Parameter parser can handle null input +<span class="fc" id="L548"> Map<String, String> params = parser.parse(pContentDisposition, ';');</span> +<span class="fc" id="L549"> fieldName = params.get("name");</span> +<span class="pc bpc" id="L550" title="1 of 2 branches missed."> if (fieldName != null) {</span> +<span class="fc" id="L551"> fieldName = fieldName.trim();</span> + } + } +<span class="fc" id="L554"> return fieldName;</span> + } + + /** + * Retrieves the field name from the <code>Content-disposition</code> + * header. + * + * @param headers A <code>Map</code> containing the HTTP request headers. + * + * @return The field name for the current <code>encapsulation</code>. + * @deprecated 1.2.1 Use {@link #getFieldName(FileItemHeaders)}. + */ + @Deprecated + protected String getFieldName(Map<String, String> headers) { +<span class="nc" id="L568"> return getFieldName(getHeader(headers, CONTENT_DISPOSITION));</span> + } + + /** + * Creates a new {@link FileItem} instance. + * + * @param headers A <code>Map</code> containing the HTTP request + * headers. + * @param isFormField Whether or not this item is a form field, as + * opposed to a file. + * + * @return A newly created <code>FileItem</code> instance. + * + * @throws FileUploadException if an error occurs. + * @deprecated 1.2 This method is no longer used in favour of + * internally created instances of {@link FileItem}. + */ + @Deprecated + protected FileItem createItem(Map<String, String> headers, + boolean isFormField) + throws FileUploadException { +<span class="nc" id="L589"> return getFileItemFactory().createItem(getFieldName(headers),</span> +<span class="nc" id="L590"> getHeader(headers, CONTENT_TYPE),</span> + isFormField, +<span class="nc" id="L592"> getFileName(headers));</span> + } + + /** + * <p> Parses the <code>header-part</code> and returns as key/value + * pairs. + * + * <p> If there are multiple headers of the same names, the name + * will map to a comma-separated list containing the values. + * + * @param headerPart The <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * @return A <code>Map</code> containing the parsed HTTP request headers. + */ + protected FileItemHeaders getParsedHeaders(String headerPart) { +<span class="fc" id="L608"> final int len = headerPart.length();</span> +<span class="fc" id="L609"> FileItemHeadersImpl headers = newFileItemHeaders();</span> +<span class="fc" id="L610"> int start = 0;</span> + for (;;) { +<span class="fc" id="L612"> int end = parseEndOfLine(headerPart, start);</span> +<span class="fc bfc" id="L613" title="All 2 branches covered."> if (start == end) {</span> +<span class="fc" id="L614"> break;</span> + } +<span class="fc" id="L616"> StringBuilder header = new StringBuilder(headerPart.substring(start, end));</span> +<span class="fc" id="L617"> start = end + 2;</span> +<span class="pc bpc" id="L618" title="1 of 2 branches missed."> while (start < len) {</span> +<span class="fc" id="L619"> int nonWs = start;</span> +<span class="pc bpc" id="L620" title="1 of 2 branches missed."> while (nonWs < len) {</span> +<span class="fc" id="L621"> char c = headerPart.charAt(nonWs);</span> +<span class="fc bfc" id="L622" title="All 4 branches covered."> if (c != ' ' && c != '\t') {</span> +<span class="fc" id="L623"> break;</span> + } +<span class="fc" id="L625"> ++nonWs;</span> +<span class="fc" id="L626"> }</span> +<span class="fc bfc" id="L627" title="All 2 branches covered."> if (nonWs == start) {</span> +<span class="fc" id="L628"> break;</span> + } + // Continuation line found +<span class="fc" id="L631"> end = parseEndOfLine(headerPart, nonWs);</span> +<span class="fc" id="L632"> header.append(" ").append(headerPart.substring(nonWs, end));</span> +<span class="fc" id="L633"> start = end + 2;</span> +<span class="fc" id="L634"> }</span> +<span class="fc" id="L635"> parseHeaderLine(headers, header.toString());</span> +<span class="fc" id="L636"> }</span> +<span class="fc" id="L637"> return headers;</span> + } + + /** + * Creates a new instance of {@link FileItemHeaders}. + * @return The new instance. + */ + protected FileItemHeadersImpl newFileItemHeaders() { +<span class="fc" id="L645"> return new FileItemHeadersImpl();</span> + } + + /** + * <p> Parses the <code>header-part</code> and returns as key/value + * pairs. + * + * <p> If there are multiple headers of the same names, the name + * will map to a comma-separated list containing the values. + * + * @param headerPart The <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * @return A <code>Map</code> containing the parsed HTTP request headers. + * @deprecated 1.2.1 Use {@link #getParsedHeaders(String)} + */ + @Deprecated + protected Map<String, String> parseHeaders(String headerPart) { +<span class="nc" id="L663"> FileItemHeaders headers = getParsedHeaders(headerPart);</span> +<span class="nc" id="L664"> Map<String, String> result = new HashMap<String, String>();</span> +<span class="nc bnc" id="L665" title="All 2 branches missed."> for (Iterator<String> iter = headers.getHeaderNames(); iter.hasNext();) {</span> +<span class="nc" id="L666"> String headerName = iter.next();</span> +<span class="nc" id="L667"> Iterator<String> iter2 = headers.getHeaders(headerName);</span> +<span class="nc" id="L668"> StringBuilder headerValue = new StringBuilder(iter2.next());</span> +<span class="nc bnc" id="L669" title="All 2 branches missed."> while (iter2.hasNext()) {</span> +<span class="nc" id="L670"> headerValue.append(",").append(iter2.next());</span> + } +<span class="nc" id="L672"> result.put(headerName, headerValue.toString());</span> +<span class="nc" id="L673"> }</span> +<span class="nc" id="L674"> return result;</span> + } + + /** + * Skips bytes until the end of the current line. + * @param headerPart The headers, which are being parsed. + * @param end Index of the last byte, which has yet been + * processed. + * @return Index of the \r\n sequence, which indicates + * end of line. + */ + private int parseEndOfLine(String headerPart, int end) { +<span class="fc" id="L686"> int index = end;</span> + for (;;) { +<span class="fc" id="L688"> int offset = headerPart.indexOf('\r', index);</span> +<span class="pc bpc" id="L689" title="2 of 4 branches missed."> if (offset == -1 || offset + 1 >= headerPart.length()) {</span> +<span class="nc" id="L690"> throw new IllegalStateException(</span> + "Expected headers to be terminated by an empty line."); + } +<span class="pc bpc" id="L693" title="1 of 2 branches missed."> if (headerPart.charAt(offset + 1) == '\n') {</span> +<span class="fc" id="L694"> return offset;</span> + } +<span class="nc" id="L696"> index = offset + 1;</span> +<span class="nc" id="L697"> }</span> + } + + /** + * Reads the next header line. + * @param headers String with all headers. + * @param header Map where to store the current header. + */ + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { +<span class="fc" id="L706"> final int colonOffset = header.indexOf(':');</span> +<span class="pc bpc" id="L707" title="1 of 2 branches missed."> if (colonOffset == -1) {</span> + // This header line is malformed, skip it. +<span class="nc" id="L709"> return;</span> + } +<span class="fc" id="L711"> String headerName = header.substring(0, colonOffset).trim();</span> +<span class="fc" id="L712"> String headerValue =</span> +<span class="fc" id="L713"> header.substring(header.indexOf(':') + 1).trim();</span> +<span class="fc" id="L714"> headers.addHeader(headerName, headerValue);</span> +<span class="fc" id="L715"> }</span> + + /** + * Returns the header with the specified name from the supplied map. The + * header lookup is case-insensitive. + * + * @param headers A <code>Map</code> containing the HTTP request headers. + * @param name The name of the header to return. + * + * @return The value of specified header, or a comma-separated list if + * there were multiple headers of that name. + * @deprecated 1.2.1 Use {@link FileItemHeaders#getHeader(String)}. + */ + @Deprecated + protected final String getHeader(Map<String, String> headers, + String name) { +<span class="nc" id="L731"> return headers.get(name.toLowerCase(Locale.ENGLISH));</span> + } + + /** + * The iterator, which is returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ + private class FileItemIteratorImpl implements FileItemIterator { + + /** + * Default implementation of {@link FileItemStream}. + */ + class FileItemStreamImpl implements FileItemStream { + + /** + * The file items content type. + */ + private final String contentType; + + /** + * The file items field name. + */ + private final String fieldName; + + /** + * The file items file name. + */ + private final String name; + + /** + * Whether the file item is a form field. + */ + private final boolean formField; + + /** + * The file items input stream. + */ + private final InputStream stream; + + /** + * Whether the file item was already opened. + */ + private boolean opened; + + /** + * The headers, if any. + */ + private FileItemHeaders headers; + + /** + * Creates a new instance. + * + * @param pName The items file name, or null. + * @param pFieldName The items field name. + * @param pContentType The items content type, or null. + * @param pFormField Whether the item is a form field. + * @param pContentLength The items content length, if known, or -1 + * @throws IOException Creating the file item failed. + */ + FileItemStreamImpl(String pName, String pFieldName, + String pContentType, boolean pFormField, +<span class="fc" id="L792"> long pContentLength) throws IOException {</span> +<span class="fc" id="L793"> name = pName;</span> +<span class="fc" id="L794"> fieldName = pFieldName;</span> +<span class="fc" id="L795"> contentType = pContentType;</span> +<span class="fc" id="L796"> formField = pFormField;</span> +<span class="fc bfc" id="L797" title="All 2 branches covered."> if (fileSizeMax != -1) { // Check if limit is already exceeded</span> +<span class="fc bfc" id="L798" title="All 2 branches covered."> if (pContentLength != -1</span> +<span class="fc bfc" id="L799" title="All 2 branches covered."> && pContentLength > fileSizeMax) {</span> +<span class="fc" id="L800"> FileSizeLimitExceededException e =</span> + new FileSizeLimitExceededException( +<span class="fc" id="L802"> format("The field %s exceeds its maximum permitted size of %s bytes.",</span> +<span class="fc" id="L803"> fieldName, Long.valueOf(fileSizeMax)),</span> +<span class="fc" id="L804"> pContentLength, fileSizeMax);</span> +<span class="fc" id="L805"> e.setFileName(pName);</span> +<span class="fc" id="L806"> e.setFieldName(pFieldName);</span> +<span class="fc" id="L807"> throw new FileUploadIOException(e);</span> + } + } + // OK to construct stream now +<span class="fc" id="L811"> final ItemInputStream itemStream = multi.newInputStream();</span> +<span class="fc" id="L812"> InputStream istream = itemStream;</span> +<span class="fc bfc" id="L813" title="All 2 branches covered."> if (fileSizeMax != -1) {</span> +<span class="fc" id="L814"> istream = new LimitedInputStream(istream, fileSizeMax) {</span> + @Override + protected void raiseError(long pSizeMax, long pCount) + throws IOException { +<span class="fc" id="L818"> itemStream.close(true);</span> +<span class="fc" id="L819"> FileSizeLimitExceededException e =</span> + new FileSizeLimitExceededException( +<span class="fc" id="L821"> format("The field %s exceeds its maximum permitted size of %s bytes.",</span> +<span class="fc" id="L822"> fieldName, Long.valueOf(pSizeMax)),</span> + pCount, pSizeMax); +<span class="fc" id="L824"> e.setFieldName(fieldName);</span> +<span class="fc" id="L825"> e.setFileName(name);</span> +<span class="fc" id="L826"> throw new FileUploadIOException(e);</span> + } + }; + } +<span class="fc" id="L830"> stream = istream;</span> +<span class="fc" id="L831"> }</span> + + /** + * Returns the items content type, or null. + * + * @return Content type, if known, or null. + */ + @Override + public String getContentType() { +<span class="fc" id="L840"> return contentType;</span> + } + + /** + * Returns the items field name. + * + * @return Field name. + */ + @Override + public String getFieldName() { +<span class="fc" id="L850"> return fieldName;</span> + } + + /** + * Returns the items file name. + * + * @return File name, if known, or null. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + @Override + public String getName() { +<span class="fc" id="L864"> return Streams.checkFileName(name);</span> + } + + /** + * Returns, whether this is a form field. + * + * @return True, if the item is a form field, + * otherwise false. + */ + @Override + public boolean isFormField() { +<span class="fc" id="L875"> return formField;</span> + } + + /** + * Returns an 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 openStream() throws IOException { +<span class="pc bpc" id="L887" title="1 of 2 branches missed."> if (opened) {</span> +<span class="nc" id="L888"> throw new IllegalStateException(</span> + "The stream was already opened."); + } +<span class="pc bpc" id="L891" title="1 of 2 branches missed."> if (((Closeable) stream).isClosed()) {</span> +<span class="nc" id="L892"> throw new FileItemStream.ItemSkippedException();</span> + } +<span class="fc" id="L894"> return stream;</span> + } + + /** + * Closes the file item. + * + * @throws IOException An I/O error occurred. + */ + void close() throws IOException { +<span class="fc" id="L903"> stream.close();</span> +<span class="fc" id="L904"> }</span> + + /** + * Returns the file item headers. + * + * @return The items header object + */ + @Override + public FileItemHeaders getHeaders() { +<span class="fc" id="L913"> return headers;</span> + } + + /** + * Sets the file item headers. + * + * @param pHeaders The items header object + */ + @Override + public void setHeaders(FileItemHeaders pHeaders) { +<span class="fc" id="L923"> headers = pHeaders;</span> +<span class="fc" id="L924"> }</span> + + } + + /** + * The multi part stream to process. + */ + private final MultipartStream multi; + + /** + * The notifier, which used for triggering the + * {@link ProgressListener}. + */ + private final MultipartStream.ProgressNotifier notifier; + + /** + * The boundary, which separates the various parts. + */ + private final byte[] boundary; + + /** + * The item, which we currently process. + */ + private FileItemStreamImpl currentItem; + + /** + * The current items field name. + */ + private String currentFieldName; + + /** + * Whether we are currently skipping the preamble. + */ + private boolean skipPreamble; + + /** + * Whether the current item may still be read. + */ + private boolean itemValid; + + /** + * Whether we have seen the end of the file. + */ + private boolean eof; + + /** + * Creates a new instance. + * + * @param ctx The request context. + * @throws FileUploadException An error occurred while + * parsing the request. + * @throws IOException An I/O error occurred. + */ + FileItemIteratorImpl(RequestContext ctx) +<span class="fc" id="L978"> throws FileUploadException, IOException {</span> +<span class="pc bpc" id="L979" title="1 of 2 branches missed."> if (ctx == null) {</span> +<span class="nc" id="L980"> throw new NullPointerException("ctx parameter");</span> + } + +<span class="fc" id="L983"> String contentType = ctx.getContentType();</span> +<span class="fc bfc" id="L984" title="All 2 branches covered."> if ((null == contentType)</span> +<span class="pc bpc" id="L985" title="1 of 2 branches missed."> || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {</span> +<span class="fc" id="L986"> throw new InvalidContentTypeException(</span> +<span class="fc" id="L987"> format("the request doesn't contain a %s or %s stream, content type header is %s",</span> + MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); + } + + + @SuppressWarnings("deprecation") // still has to be backward compatible +<span class="fc" id="L993"> final int contentLengthInt = ctx.getContentLength();</span> + +<span class="pc bpc" id="L995" title="1 of 2 branches missed."> final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass())</span> + // Inline conditional is OK here CHECKSTYLE:OFF +<span class="pc" id="L997"> ? ((UploadContext) ctx).contentLength()</span> + : contentLengthInt; + // CHECKSTYLE:ON + + InputStream input; // N.B. this is eventually closed in MultipartStream processing +<span class="fc bfc" id="L1002" title="All 2 branches covered."> if (sizeMax >= 0) {</span> +<span class="pc bpc" id="L1003" title="1 of 4 branches missed."> if (requestSize != -1 && requestSize > sizeMax) {</span> +<span class="fc" id="L1004"> throw new SizeLimitExceededException(</span> +<span class="fc" id="L1005"> format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",</span> +<span class="fc" id="L1006"> Long.valueOf(requestSize), Long.valueOf(sizeMax)),</span> +<span class="fc" id="L1007"> requestSize, sizeMax);</span> + } + // N.B. this is eventually closed in MultipartStream processing +<span class="fc" id="L1010"> input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {</span> + @Override + protected void raiseError(long pSizeMax, long pCount) + throws IOException { +<span class="fc" id="L1014"> FileUploadException ex = new SizeLimitExceededException(</span> +<span class="fc" id="L1015"> format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",</span> +<span class="fc" id="L1016"> Long.valueOf(pCount), Long.valueOf(pSizeMax)),</span> + pCount, pSizeMax); +<span class="fc" id="L1018"> throw new FileUploadIOException(ex);</span> + } + }; + } else { +<span class="fc" id="L1022"> input = ctx.getInputStream();</span> + } + +<span class="fc" id="L1025"> String charEncoding = headerEncoding;</span> +<span class="pc bpc" id="L1026" title="1 of 2 branches missed."> if (charEncoding == null) {</span> +<span class="fc" id="L1027"> charEncoding = ctx.getCharacterEncoding();</span> + } + +<span class="fc" id="L1030"> boundary = getBoundary(contentType);</span> +<span class="fc bfc" id="L1031" title="All 2 branches covered."> if (boundary == null) {</span> +<span class="fc" id="L1032"> IOUtils.closeQuietly(input); // avoid possible resource leak</span> +<span class="fc" id="L1033"> throw new FileUploadException("the request was rejected because no multipart boundary was found");</span> + } + +<span class="fc" id="L1036"> notifier = new MultipartStream.ProgressNotifier(listener, requestSize);</span> + try { +<span class="fc" id="L1038"> multi = new MultipartStream(input, boundary, notifier);</span> +<span class="nc" id="L1039"> } catch (IllegalArgumentException iae) {</span> +<span class="nc" id="L1040"> IOUtils.closeQuietly(input); // avoid possible resource leak</span> +<span class="nc" id="L1041"> throw new InvalidContentTypeException(</span> +<span class="nc" id="L1042"> format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);</span> +<span class="fc" id="L1043"> }</span> +<span class="fc" id="L1044"> multi.setHeaderEncoding(charEncoding);</span> + +<span class="fc" id="L1046"> skipPreamble = true;</span> +<span class="fc" id="L1047"> findNextItem();</span> +<span class="fc" id="L1048"> }</span> + + /** + * Called for finding the next item, if any. + * + * @return True, if an next item was found, otherwise false. + * @throws IOException An I/O error occurred. + */ + private boolean findNextItem() throws IOException { +<span class="pc bpc" id="L1057" title="1 of 2 branches missed."> if (eof) {</span> +<span class="nc" id="L1058"> return false;</span> + } +<span class="fc bfc" id="L1060" title="All 2 branches covered."> if (currentItem != null) {</span> +<span class="fc" id="L1061"> currentItem.close();</span> +<span class="fc" id="L1062"> currentItem = null;</span> + } + for (;;) { + boolean nextPart; +<span class="pc bpc" id="L1066" title="1 of 2 branches missed."> if (skipPreamble) {</span> +<span class="fc" id="L1067"> nextPart = multi.skipPreamble();</span> + } else { +<span class="nc" id="L1069"> nextPart = multi.readBoundary();</span> + } +<span class="fc bfc" id="L1071" title="All 2 branches covered."> if (!nextPart) {</span> +<span class="fc bfc" id="L1072" title="All 2 branches covered."> if (currentFieldName == null) {</span> + // Outer multipart terminated -> No more data +<span class="fc" id="L1074"> eof = true;</span> +<span class="fc" id="L1075"> return false;</span> + } + // Inner multipart terminated -> Return to parsing the outer +<span class="fc" id="L1078"> multi.setBoundary(boundary);</span> +<span class="fc" id="L1079"> currentFieldName = null;</span> +<span class="fc" id="L1080"> continue;</span> + } +<span class="fc" id="L1082"> FileItemHeaders headers = getParsedHeaders(multi.readHeaders());</span> +<span class="fc bfc" id="L1083" title="All 2 branches covered."> if (currentFieldName == null) {</span> + // We're parsing the outer multipart +<span class="fc" id="L1085"> String fieldName = getFieldName(headers);</span> +<span class="pc bpc" id="L1086" title="1 of 2 branches missed."> if (fieldName != null) {</span> +<span class="fc" id="L1087"> String subContentType = headers.getHeader(CONTENT_TYPE);</span> +<span class="fc bfc" id="L1088" title="All 2 branches covered."> if (subContentType != null</span> +<span class="fc" id="L1089"> && subContentType.toLowerCase(Locale.ENGLISH)</span> +<span class="fc bfc" id="L1090" title="All 2 branches covered."> .startsWith(MULTIPART_MIXED)) {</span> +<span class="fc" id="L1091"> currentFieldName = fieldName;</span> + // Multiple files associated with this field name +<span class="fc" id="L1093"> byte[] subBoundary = getBoundary(subContentType);</span> +<span class="fc" id="L1094"> multi.setBoundary(subBoundary);</span> +<span class="fc" id="L1095"> skipPreamble = true;</span> +<span class="fc" id="L1096"> continue;</span> + } +<span class="fc" id="L1098"> String fileName = getFileName(headers);</span> +<span class="fc" id="L1099"> currentItem = new FileItemStreamImpl(fileName,</span> +<span class="fc bfc" id="L1100" title="All 2 branches covered."> fieldName, headers.getHeader(CONTENT_TYPE),</span> +<span class="fc" id="L1101"> fileName == null, getContentLength(headers));</span> +<span class="fc" id="L1102"> currentItem.setHeaders(headers);</span> +<span class="fc" id="L1103"> notifier.noteItem();</span> +<span class="fc" id="L1104"> itemValid = true;</span> +<span class="fc" id="L1105"> return true;</span> + } +<span class="nc" id="L1107"> } else {</span> +<span class="fc" id="L1108"> String fileName = getFileName(headers);</span> +<span class="pc bpc" id="L1109" title="1 of 2 branches missed."> if (fileName != null) {</span> +<span class="fc" id="L1110"> currentItem = new FileItemStreamImpl(fileName,</span> + currentFieldName, +<span class="fc" id="L1112"> headers.getHeader(CONTENT_TYPE),</span> +<span class="fc" id="L1113"> false, getContentLength(headers));</span> +<span class="fc" id="L1114"> currentItem.setHeaders(headers);</span> +<span class="fc" id="L1115"> notifier.noteItem();</span> +<span class="fc" id="L1116"> itemValid = true;</span> +<span class="fc" id="L1117"> return true;</span> + } + } +<span class="nc" id="L1120"> multi.discardBodyData();</span> +<span class="nc" id="L1121"> }</span> + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { +<span class="fc" id="L1126"> return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH));</span> +<span class="fc" id="L1127"> } catch (Exception e) {</span> +<span class="fc" id="L1128"> return -1;</span> + } + } + + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + @Override + public boolean hasNext() throws FileUploadException, IOException { +<span class="pc bpc" id="L1144" title="1 of 2 branches missed."> if (eof) {</span> +<span class="nc" id="L1145"> return false;</span> + } +<span class="fc bfc" id="L1147" title="All 2 branches covered."> if (itemValid) {</span> +<span class="fc" id="L1148"> return true;</span> + } + try { +<span class="fc" id="L1151"> return findNextItem();</span> +<span class="nc" id="L1152"> } catch (FileUploadIOException e) {</span> + // unwrap encapsulated SizeException +<span class="nc" id="L1154"> throw (FileUploadException) e.getCause();</span> + } + } + + /** + * Returns the next available {@link FileItemStream}. + * + * @throws java.util.NoSuchElementException No more items are + * available. Use {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + @Override + public FileItemStream next() throws FileUploadException, IOException { +<span class="pc bpc" id="L1171" title="2 of 6 branches missed."> if (eof || (!itemValid && !hasNext())) {</span> +<span class="nc" id="L1172"> throw new NoSuchElementException();</span> + } +<span class="fc" id="L1174"> itemValid = false;</span> +<span class="fc" id="L1175"> return currentItem;</span> + } + + } + + /** + * This exception is thrown for hiding an inner + * {@link FileUploadException} in an {@link IOException}. + */ + public static class FileUploadIOException extends IOException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = -7047616958165584154L; + + /** + * The exceptions cause; we overwrite the parent + * classes field, which is available since Java + * 1.4 only. + */ + private final FileUploadException cause; + + /** + * Creates a <code>FileUploadIOException</code> with the + * given cause. + * + * @param pCause The exceptions cause, if any, or null. + */ +<span class="fc" id="L1204"> public FileUploadIOException(FileUploadException pCause) {</span> + // We're not doing super(pCause) cause of 1.3 compatibility. +<span class="fc" id="L1206"> cause = pCause;</span> +<span class="fc" id="L1207"> }</span> + + /** + * Returns the exceptions cause. + * + * @return The exceptions cause, if any, or null. + */ + @Override + public Throwable getCause() { +<span class="fc" id="L1216"> return cause;</span> + } + + } + + /** + * Thrown to indicate that the request is not a multipart request. + */ + public static class InvalidContentTypeException + extends FileUploadException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = -9073026332015646668L; + + /** + * Constructs a <code>InvalidContentTypeException</code> with no + * detail message. + */ + public InvalidContentTypeException() { +<span class="nc" id="L1237"> super();</span> +<span class="nc" id="L1238"> }</span> + + /** + * Constructs an <code>InvalidContentTypeException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public InvalidContentTypeException(String message) { +<span class="fc" id="L1247"> super(message);</span> +<span class="fc" id="L1248"> }</span> + + /** + * Constructs an <code>InvalidContentTypeException</code> with + * the specified detail message and cause. + * + * @param msg The detail message. + * @param cause the original cause + * + * @since 1.3.1 + */ + public InvalidContentTypeException(String msg, Throwable cause) { +<span class="nc" id="L1260"> super(msg, cause);</span> +<span class="nc" id="L1261"> }</span> + } + + /** + * Thrown to indicate an IOException. + */ + public static class IOFileUploadException extends FileUploadException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = 1749796615868477269L; + + /** + * The exceptions cause; we overwrite the parent + * classes field, which is available since Java + * 1.4 only. + */ + private final IOException cause; + + /** + * Creates a new instance with the given cause. + * + * @param pMsg The detail message. + * @param pException The exceptions cause. + */ + public IOFileUploadException(String pMsg, IOException pException) { +<span class="fc" id="L1288"> super(pMsg);</span> +<span class="fc" id="L1289"> cause = pException;</span> +<span class="fc" id="L1290"> }</span> + + /** + * Returns the exceptions cause. + * + * @return The exceptions cause, if any, or null. + */ + @Override + public Throwable getCause() { +<span class="fc" id="L1299"> return cause;</span> + } + + } + + /** + * This exception is thrown, if a requests permitted size + * is exceeded. + */ + protected abstract static class SizeException extends FileUploadException { + + /** + * Serial version UID, being used, if serialized. + */ + private static final long serialVersionUID = -8776225574705254126L; + + /** + * The actual size of the request. + */ + private final long actual; + + /** + * The maximum permitted size of the request. + */ + private final long permitted; + + /** + * Creates a new instance. + * + * @param message The detail message. + * @param actual The actual number of bytes in the request. + * @param permitted The requests size limit, in bytes. + */ + protected SizeException(String message, long actual, long permitted) { +<span class="fc" id="L1333"> super(message);</span> +<span class="fc" id="L1334"> this.actual = actual;</span> +<span class="fc" id="L1335"> this.permitted = permitted;</span> +<span class="fc" id="L1336"> }</span> + + /** + * Retrieves the actual size of the request. + * + * @return The actual size of the request. + * @since 1.3 + */ + public long getActualSize() { +<span class="nc" id="L1345"> return actual;</span> + } + + /** + * Retrieves the permitted size of the request. + * + * @return The permitted size of the request. + * @since 1.3 + */ + public long getPermittedSize() { +<span class="fc" id="L1355"> return permitted;</span> + } + + } + + /** + * Thrown to indicate that the request size is not specified. In other + * words, it is thrown, if the content-length header is missing or + * contains the value -1. + * + * @deprecated 1.2 As of commons-fileupload 1.2, the presence of a + * content-length header is no longer required. + */ + @Deprecated + public static class UnknownSizeException + extends FileUploadException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = 7062279004812015273L; + + /** + * Constructs a <code>UnknownSizeException</code> with no + * detail message. + */ + public UnknownSizeException() { +<span class="nc" id="L1382"> super();</span> +<span class="nc" id="L1383"> }</span> + + /** + * Constructs an <code>UnknownSizeException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public UnknownSizeException(String message) { +<span class="nc" id="L1392"> super(message);</span> +<span class="nc" id="L1393"> }</span> + + } + + /** + * Thrown to indicate that the request size exceeds the configured maximum. + */ + public static class SizeLimitExceededException + extends SizeException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = -2474893167098052828L; + + /** + * @deprecated 1.2 Replaced by + * {@link #SizeLimitExceededException(String, long, long)} + */ + @Deprecated + public SizeLimitExceededException() { +<span class="nc" id="L1414"> this(null, 0, 0);</span> +<span class="nc" id="L1415"> }</span> + + /** + * @deprecated 1.2 Replaced by + * {@link #SizeLimitExceededException(String, long, long)} + * @param message The exceptions detail message. + */ + @Deprecated + public SizeLimitExceededException(String message) { +<span class="nc" id="L1424"> this(message, 0, 0);</span> +<span class="nc" id="L1425"> }</span> + + /** + * Constructs a <code>SizeExceededException</code> with + * the specified detail message, and actual and permitted sizes. + * + * @param message The detail message. + * @param actual The actual request size. + * @param permitted The maximum permitted request size. + */ + public SizeLimitExceededException(String message, long actual, + long permitted) { +<span class="fc" id="L1437"> super(message, actual, permitted);</span> +<span class="fc" id="L1438"> }</span> + + } + + /** + * Thrown to indicate that A files size exceeds the configured maximum. + */ + public static class FileSizeLimitExceededException + extends SizeException { + + /** + * The exceptions UID, for serializing an instance. + */ + private static final long serialVersionUID = 8150776562029630058L; + + /** + * File name of the item, which caused the exception. + */ + private String fileName; + + /** + * Field name of the item, which caused the exception. + */ + private String fieldName; + + /** + * Constructs a <code>SizeExceededException</code> with + * the specified detail message, and actual and permitted sizes. + * + * @param message The detail message. + * @param actual The actual request size. + * @param permitted The maximum permitted request size. + */ + public FileSizeLimitExceededException(String message, long actual, + long permitted) { +<span class="fc" id="L1473"> super(message, actual, permitted);</span> +<span class="fc" id="L1474"> }</span> + + /** + * Returns the file name of the item, which caused the + * exception. + * + * @return File name, if known, or null. + */ + public String getFileName() { +<span class="nc" id="L1483"> return fileName;</span> + } + + /** + * Sets the file name of the item, which caused the + * exception. + * + * @param pFileName the file name of the item, which caused the exception. + */ + public void setFileName(String pFileName) { +<span class="fc" id="L1493"> fileName = pFileName;</span> +<span class="fc" id="L1494"> }</span> + + /** + * Returns the field name of the item, which caused the + * exception. + * + * @return Field name, if known, or null. + */ + public String getFieldName() { +<span class="nc" id="L1503"> return fieldName;</span> + } + + /** + * Sets the field name of the item, which caused the + * exception. + * + * @param pFieldName the field name of the item, + * which caused the exception. + */ + public void setFieldName(String pFieldName) { +<span class="fc" id="L1514"> fieldName = pFieldName;</span> +<span class="fc" id="L1515"> }</span> + + } + + /** + * Returns the progress listener. + * + * @return The progress listener, if any, or null. + */ + public ProgressListener getProgressListener() { +<span class="nc" id="L1525"> return listener;</span> + } + + /** + * Sets the progress listener. + * + * @param pListener The progress listener, if any. Defaults to null. + */ + public void setProgressListener(ProgressListener pListener) { +<span class="fc" id="L1534"> listener = pListener;</span> +<span class="fc" id="L1535"> }</span> + +} +</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file
Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>FileUploadException</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">FileUploadException</span></div><h1>FileUploadException</h1><table class="coverage" cellspa cing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">33 of 48</td><td class="ctr2">31%</td><td class="bar">4 of 4</td><td class="ctr2">0%</td><td class="ctr1">5< /td><td class="ctr2">8</td><td class="ctr1">12</td><td class="ctr2">18</td><td class="ctr1">3</td><td class="ctr2">6</td></tr></tfoot><tbody><tr><td id="a4"><a href="FileUploadException.java.html#L75" class="el_method">printStackTrace(PrintStream)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="14" alt="14"/></td><td class="ctr2" id="c3">0%</td><td class="bar" id="d0"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="2" alt="2"/></td><td class="ctr2" id="e0">0%</td><td class="ctr1" id="f0">2</td><td class="ctr2" id="g0">2</td><td class="ctr1" id="h0">5</td><td class="ctr2" id="i0">5</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a5"><a href="FileUploadException.java.html#L90" class="el_method">printStackTrace(PrintWriter)</a></td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="14" alt="14"/></td><td class="ctr2" id="c4"> 0%</td><td class="bar" id="d1"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="2" alt="2"/></td><td class="ctr2" id="e1">0%</td><td class="ctr1" id="f1">2</td><td class="ctr2" id="g1">2</td><td class="ctr1" id="h1">5</td><td class="ctr2" id="i1">5</td><td class="ctr1" id="j1">1</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a0"><a href="FileUploadException.java.html#L43" class="el_method">FileUploadException()</a></td><td class="bar" id="b2"><img src="../jacoco-resources/redbar.gif" width="42" height="10" title="5" alt="5"/></td><td class="ctr2" id="c5">0%</td><td class="bar" id="d2"/><td class="ctr2" id="e2">n/a</td><td class="ctr1" id="f2">1</td><td class="ctr2" id="g2">1</td><td class="ctr1" id="h2">2</td><td class="ctr2" id="i3">2</td><td class="ctr1" id="j2">1</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a2"><a href="FileUploadException.java.html#L64" class="el_method">FileUploadException(String, Throwable)</a></td><td class="bar" id="b3"><i mg src="../jacoco-resources/greenbar.gif" width="60" height="10" title="7" alt="7"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d3"/><td class="ctr2" id="e3">n/a</td><td class="ctr1" id="f3">0</td><td class="ctr2" id="g3">1</td><td class="ctr1" id="h3">0</td><td class="ctr2" id="i2">3</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k3">1</td></tr><tr><td id="a1"><a href="FileUploadException.java.html#L53" class="el_method">FileUploadException(String)</a></td><td class="bar" id="b4"><img src="../jacoco-resources/greenbar.gif" width="42" height="10" title="5" alt="5"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d4"/><td class="ctr2" id="e4">n/a</td><td class="ctr1" id="f4">0</td><td class="ctr2" id="g4">1</td><td class="ctr1" id="h4">0</td><td class="ctr2" id="i4">2</td><td class="ctr1" id="j4">0</td><td class="ctr2" id="k4">1</td></tr><tr><td id="a3"><a href="FileUploadException.java.html#L102" class="el_method">getCause()</a></td><td class="bar" id="b5"><img src="../jacoco-resources/greenbar.gif" width="25" height="10" title="3" alt="3"/></td><td class="ctr2" id="c2">100%</td><td class="bar" id="d5"/><td class="ctr2" id="e5">n/a</td><td class="ctr1" id="f5">0</td><td class="ctr2" id="g5">1</td><td class="ctr1" id="h5">0</td><td class="ctr2" id="i5">1</td><td class="ctr1" id="j5">0</td><td class="ctr2" id="k5">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.java.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.java.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/FileUploadException.java.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>FileUploadException.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.source.html" class="el_package">org.apache.commons.fileupload</a> > <span c lass="el_source">FileUploadException.java</span></div><h1>FileUploadException.java</h1><pre class="source lang-java linenums">/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.fileupload; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * Exception for errors encountered while processing the request. + */ +public class FileUploadException extends Exception { + + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { +<span class="nc" id="L43"> this(null, null);</span> +<span class="nc" id="L44"> }</span> + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { +<span class="fc" id="L53"> this(msg, null);</span> +<span class="fc" id="L54"> }</span> + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { +<span class="fc" id="L64"> super(msg);</span> +<span class="fc" id="L65"> this.cause = cause;</span> +<span class="fc" id="L66"> }</span> + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + @Override + public void printStackTrace(PrintStream stream) { +<span class="nc" id="L75"> super.printStackTrace(stream);</span> +<span class="nc bnc" id="L76" title="All 2 branches missed."> if (cause != null) {</span> +<span class="nc" id="L77"> stream.println("Caused by:");</span> +<span class="nc" id="L78"> cause.printStackTrace(stream);</span> + } +<span class="nc" id="L80"> }</span> + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + @Override + public void printStackTrace(PrintWriter writer) { +<span class="nc" id="L90"> super.printStackTrace(writer);</span> +<span class="nc bnc" id="L91" title="All 2 branches missed."> if (cause != null) {</span> +<span class="nc" id="L92"> writer.println("Caused by:");</span> +<span class="nc" id="L93"> cause.printStackTrace(writer);</span> + } +<span class="nc" id="L95"> }</span> + + /** + * {@inheritDoc} + */ + @Override + public Throwable getCause() { +<span class="fc" id="L102"> return cause;</span> + } + +} +</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>InvalidFileNameException</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">InvalidFileNameException</span></div><h1>InvalidFileNameException</h1><table class="co verage" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">0 of 10</td><td class="ctr2">100%</td><td class="bar">0 of 0</td><td class="ctr2">n/a</td><td class="ctr1">0</td><td class="ctr2">2</td><td class="ctr1">0</td><td class="ctr2">4</td><td class="ctr1">0</td><td class="ctr2">2</td></tr></tfoot><tbody><tr><td id="a1"><a href="InvalidFileNameException.java.html#L49" class="el_method">InvalidFileNameException(String, String)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="7" alt="7"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d0"/><td class="ctr2" id="e0">n/a</td><td class="ctr1" id="f0">0</td><td class="ctr2" id="g0">1</td><td class="ctr1" id="h0">0</td><td class="ctr2" id="i0">3</td><td class="ctr1" id="j0">0</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a0"><a href="InvalidFileNameException.java.html#L59" class="el_method">getName()</a></td><td class="bar" id="b1"><img src="../jacoco-resources/greenbar.gif" width="51" height="10" title="3" alt="3"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">0</td><td class="ctr2" id="g1">1</td><td class="ctr1" id="h1">0</td><td class="ctr2" id="i1">1</td><td class="ctr1" id="j1">0</td><td class="ctr2" id="k1">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file
