From b7b28cc896ec6cc76c60af62a62ec9c80960c212 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 20 Dec 2013 17:10:18 -0500 Subject: [PATCH] VIVO-617 Change the way we deal with Multipart requests. --- .../controller/MultipartRequestWrapper.java | 288 ++++++++++++++++++ .../webapp/controller/VitroHttpServlet.java | 25 +- .../vitro/webapp/controller/VitroRequest.java | 63 ++++ .../FileUploadServletRequest.java | 112 ------- .../MultipartHttpServletRequest.java | 261 ---------------- .../SimpleHttpServletRequestWrapper.java | 81 ----- 6 files changed, 373 insertions(+), 457 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java new file mode 100644 index 000000000..02a7eee72 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java @@ -0,0 +1,288 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Wraps a multipart HTTP request, and pre-parses it for file uploads, without + * losing the request parameters. + * + * Parsing through the request with an Apache ServletFileUpload builds a list of + * FileItems that includes the parameters and the file parts. After that, + * however, the parameters are no longer accessible from the request. This + * wrapper will see that they don't get lost. + * + * The List of FileItems includes both "formField" items and "file" items. As + * with the usual parameters on a request, we can have more than one value with + * the same name. So this creates a map of > to hold the + * parameters, and a map of > to hold the files. + * + * The parameters will be available to the wrapper through the normal methods. + * The files will be available as an attribute that holds the map. Also, a + * separate attribute will hold a Boolean to indicate that this was indeed a + * multipart request. + * + * Conveninence methods in VitroRequest will make these easy to handle, without + * actually touching the attributes. + */ +public class MultipartRequestWrapper extends HttpServletRequestWrapper { + private static final Log log = LogFactory + .getLog(MultipartRequestWrapper.class); + + private static final String CLASS_NAME = MultipartRequestWrapper.class + .getSimpleName(); + public static final String ATTRIBUTE_IS_MULTIPART = CLASS_NAME + + "_isMultipart"; + public static final String ATTRIBUTE_FILE_ITEM_MAP = CLASS_NAME + + "_fileItemMap"; + public static final String ATTRIBUTE_FILE_SIZE_EXCEPTION = CLASS_NAME + + "_fileSizeException"; + + private static final String[] EMPTY_ARRAY = new String[0]; + + // ---------------------------------------------------------------------- + // The factory + // ---------------------------------------------------------------------- + + /** + * If this is a multipart request, wrap it. Otherwise, just return the + * request as it is. + */ + public static HttpServletRequest parse(HttpServletRequest req, + ParsingStrategy strategy) throws IOException { + if (!ServletFileUpload.isMultipartContent(req)) { + return req; + } + + ListsMap parameters = new ListsMap<>(); + ListsMap files = new ListsMap<>(); + + parseQueryString(req.getQueryString(), parameters); + parseFileParts(req, parameters, files, strategy); + + return new MultipartRequestWrapper(req, parameters, files); + } + + /** + * Pull any parameters out of the URL. + */ + private static void parseQueryString(String queryString, + ListsMap parameters) { + log.debug("Query string is : '" + queryString + "'"); + if (queryString != null) { + String[] pieces = queryString.split("&"); + + for (String piece : pieces) { + int equalsHere = piece.indexOf('='); + if (piece.trim().isEmpty()) { + // Ignore an empty piece. + } else if (equalsHere <= 0) { + // A parameter without a value. + parameters.add(decode(piece), ""); + } else { + // A parameter with a value. + String key = piece.substring(0, equalsHere); + String value = piece.substring(equalsHere + 1); + parameters.add(decode(key), decode(value)); + } + } + } + log.debug("Parameters from query string are: " + parameters); + } + + /** + * Remove any special URL-style encoding. + */ + private static String decode(String encoded) { + try { + return URLDecoder.decode(encoded, "UTF-8"); + } catch (UnsupportedEncodingException e) { + log.error(e, e); + return encoded; + } + } + + private static void parseFileParts(HttpServletRequest req, + ListsMap parameters, ListsMap files, + ParsingStrategy strategy) throws IOException { + + ServletFileUpload upload = createUploadHandler(req, + strategy.maximumMultipartFileSize()); + List items = parseRequestIntoFileItems(req, upload, strategy); + + for (FileItem item : items) { + // Process a regular form field + String name = item.getFieldName(); + if (item.isFormField()) { + String value; + try { + value = item.getString("UTF-8"); + } catch (UnsupportedEncodingException e) { + value = item.getString(); + } + parameters.add(name, value); + log.debug("Form field (parameter) " + name + "=" + value); + } else { + files.add(name, item); + log.debug("File " + name + ": " + item.getSize() + " bytes."); + } + } + } + + /** + * Create an upload handler that will throw an exception if the file is too + * large. + */ + private static ServletFileUpload createUploadHandler( + HttpServletRequest req, long maxFileSize) { + File tempDir = figureTemporaryDirectory(req); + + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD); + factory.setRepository(tempDir); + + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setSizeMax(maxFileSize); + return upload; + } + + /** + * Find the temporary storage directory for this webapp. + */ + private static File figureTemporaryDirectory(HttpServletRequest request) { + return (File) request.getSession().getServletContext() + .getAttribute("javax.servlet.context.tempdir"); + } + + /** + * Parse the raw request into a list of parts. + * + * If there is a parsing error, let the strategy handle it. If the strategy + * throws it back, wrap it in an IOException and throw it on up. + */ + @SuppressWarnings("unchecked") + private static List parseRequestIntoFileItems( + HttpServletRequest req, ServletFileUpload upload, + ParsingStrategy strategy) throws IOException { + try { + return upload.parseRequest(req); + } catch (FileSizeLimitExceededException e) { + if (strategy.stashFileSizeException()) { + req.setAttribute(ATTRIBUTE_FILE_SIZE_EXCEPTION, e); + return Collections.emptyList(); + } else { + throw new IOException(e); + } + } catch (FileUploadException e) { + throw new IOException(e); + } + } + + // ---------------------------------------------------------------------- + // The instance + // ---------------------------------------------------------------------- + + private final ListsMap parameters; + + public MultipartRequestWrapper(HttpServletRequest req, + ListsMap parameters, ListsMap files) { + super(req); + + this.parameters = parameters; + + req.setAttribute(ATTRIBUTE_IS_MULTIPART, Boolean.TRUE); + req.setAttribute(ATTRIBUTE_FILE_ITEM_MAP, files); + } + + /** + * Look in the map of parsed parameters. + */ + @Override + public String getParameter(String name) { + if (parameters.containsKey(name)) { + return parameters.get(name).get(0); + } else { + return null; + } + } + + /** + * Look in the map of parsed parameters. Make a protective copy. + */ + @Override + public Enumeration getParameterNames() { + return Collections.enumeration(new HashSet<>(parameters.keySet())); + } + + /** + * Look in the map of parsed parameters. + */ + @Override + public String[] getParameterValues(String name) { + if (parameters.containsKey(name)) { + return parameters.get(name).toArray(EMPTY_ARRAY); + } else { + return null; + } + } + + /** + * Make a copy of the map of parsed parameters; + */ + @Override + public Map getParameterMap() { + Map result = new HashMap(); + for (String key : parameters.keySet()) { + result.put(key, parameters.get(key).toArray(EMPTY_ARRAY)); + } + return result; + } + + // ---------------------------------------------------------------------- + // Helper classes + // ---------------------------------------------------------------------- + + private static class ListsMap extends HashMap> { + void add(String key, T value) { + if (!containsKey(key)) { + put(key, new ArrayList()); + } + get(key).add(value); + } + } + + public interface ParsingStrategy { + long maximumMultipartFileSize(); + + /** + * Allows you to handle the exception in your code. + * + * Be aware that the multipart parameters have been lost, and that may + * include form fields. + */ + boolean stashFileSizeException(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java index dcc80a040..bf082aa56 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java @@ -30,14 +30,13 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.ResourceBean; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.i18n.I18n; -public class VitroHttpServlet extends HttpServlet { +public class VitroHttpServlet extends HttpServlet implements MultipartRequestWrapper.ParsingStrategy { private static final long serialVersionUID = 1L; protected static DateFormat publicDateFormat = new SimpleDateFormat( @@ -60,8 +59,9 @@ public class VitroHttpServlet extends HttpServlet { if ((req instanceof HttpServletRequest) && (resp instanceof HttpServletResponse)) { HttpServletRequest hreq = (HttpServletRequest) req; - HttpServletResponse hresp = (HttpServletResponse) resp; + hreq = MultipartRequestWrapper.parse(hreq, this); + if (log.isTraceEnabled()) { dumpRequestHeaders(hreq); } @@ -70,6 +70,25 @@ public class VitroHttpServlet extends HttpServlet { super.service(req, resp); } + /** + * Override this to change the maximum size of uploaded files in multipart + * requests. + */ + @Override + public long maximumMultipartFileSize() { + return 50 * 1024 * 1024; // default is 50 megabytes + } + + /** + * Override this to change the way that exceptions are handled when parsing + * a multipart request. Be aware that multipart parameters have been lost, + * and that may include form fields. + */ + @Override + public boolean stashFileSizeException() { + return false; + } + /** * doGet does nothing. */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index 05c0fc158..9878fe0b9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -3,12 +3,20 @@ package edu.cornell.mannlib.vitro.webapp.controller; +import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_ITEM_MAP; +import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_SIZE_EXCEPTION; +import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_IS_MULTIPART; + import java.text.Collator; +import java.util.Collections; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -231,4 +239,59 @@ public class VitroRequest extends HttpServletRequestWrapper { public WebappDaoFactory getLanguageNeutralWebappDaoFactory() { return (WebappDaoFactory) getAttribute("languageNeutralWebappDaoFactory"); } + + // ---------------------------------------------------------------------- + // Deal with parsed multipart requests. + // ---------------------------------------------------------------------- + + public boolean isMultipart() { + return getAttribute(ATTRIBUTE_IS_MULTIPART) != null; + } + + @SuppressWarnings("unchecked") + public Map> getFiles() { + Map> map; + map = (Map>) getAttribute(ATTRIBUTE_FILE_ITEM_MAP); + if (map == null) { + return Collections.emptyMap(); + } else { + return map; + } + } + + /** + * There may be more than one file item with the given name. If the first + * one is empty (size is zero), keep looking for a non-empty one. + */ + public FileItem getFileItem(String name) { + Map> map = getFiles(); + List items = map.get(name); + if (items == null) { + return null; + } + for (FileItem item : items) { + if (item.getSize() > 0L) { + return item; + } + } + return null; + } + + /** + * If the uploaded file exceeded the maximum size, and if the strategy said + * to stash the exception, it will be stored as a request attribute. + */ + public boolean hasFileSizeException() { + return getFileSizeException() != null; + } + + public FileSizeLimitExceededException getFileSizeException() { + Object e = getAttribute(ATTRIBUTE_FILE_SIZE_EXCEPTION); + if (e instanceof FileSizeLimitExceededException) { + return (FileSizeLimitExceededException) e; + } else { + return null; + } + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java deleted file mode 100644 index 519e2f07c..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.servlet.ServletFileUpload; - -/** - *

- * Wraps an HTTP request and parses it for file uploads, without losing the - * request parameters. - *

- *

- * The request will have an attribute named by {@link #FILE_ITEM_MAP}. Either - * this attribute or the call to {@link #getFiles()} will produce a map that may - * be empty but is never null. The keys to the map are the field names for the - * file fields. Since a form may have multiple fields with the same name, each - * field name maps to a list of items. If a user does not provide a file to be - * uploaded in a given field, the length of the file will be 0. - *

- *

- * If the uploaded file(s) would be larger than the maxFileSize, - * {@link #parseRequest(HttpServletRequest, int)} does not throw an Exception. - * Instead, it records the exception in a request attribute named by - * {@link #FILE_UPLOAD_EXCEPTION}. This attribute can be accessed directly, or - * indirectly via the methods {@link #hasFileUploadException()} and - * {@link #getFileUploadException()}. If there is an exception, the file item - * map (see above) will still be non-null, but it will be empty. - *

- *

- * Most methods are declared here simply delegate to the wrapped request. - * Methods that have to do with parameters, files, or parsing exceptions, are - * handled differently for simple requests and multipart request, and are - * implemented in the sub-classes. - *

- */ -public abstract class FileUploadServletRequest extends HttpServletRequestWrapper { - public static final String FILE_ITEM_MAP = "file_item_map"; - public static final String FILE_UPLOAD_EXCEPTION = "file_upload_exception"; - - // ---------------------------------------------------------------------- - // The factory method - // ---------------------------------------------------------------------- - - /** - * Wrap this {@link HttpServletRequest} in an appropriate wrapper class. - */ - public static FileUploadServletRequest parseRequest( - HttpServletRequest request, int maxFileSize) throws IOException { - boolean isMultipart = ServletFileUpload.isMultipartContent(request); - if (isMultipart) { - return new MultipartHttpServletRequest(request, maxFileSize); - } else { - return new SimpleHttpServletRequestWrapper(request); - } - } - - // ---------------------------------------------------------------------- - // The constructor and the delegate. - // ---------------------------------------------------------------------- - - private final HttpServletRequest delegate; - - public FileUploadServletRequest(HttpServletRequest delegate) { - super(delegate); - this.delegate = delegate; - } - - protected HttpServletRequest getDelegate() { - return this.delegate; - } - - // ---------------------------------------------------------------------- - // New functionality to be implemented by the subclasses. - // ---------------------------------------------------------------------- - - /** Was this a multipart HTTP request? */ - public abstract boolean isMultipart(); - - /** - * Get the map of file items, by name. - */ - public abstract Map> getFiles(); - - /** - * Find a non-empty file item with this name. - * - * @return the first such file item, or null if no matching, - * non-empty items were found. - */ - public abstract FileItem getFileItem(String string); - - /** - * Was there an exception when uploading the file items? - */ - public abstract boolean hasFileUploadException(); - - /** - * Get the exception that occurred when uploading the file items. If no such - * exception, return null. - */ - public abstract FileUploadException getFileUploadException(); - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java deleted file mode 100644 index 56cf480fc..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest; - -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A wrapper for a servlet request that holds multipart content. Parsing the - * request will consume the parameters, so we need to hold them here to answer - * any parameter-related requests. File-related information will also be held - * here, to answer file-related requests. - */ -class MultipartHttpServletRequest extends FileUploadServletRequest { - private static final Log log = LogFactory - .getLog(MultipartHttpServletRequest.class); - - private static final String[] EMPTY_ARRAY = new String[0]; - - private final Map> parameters; - private final Map> files; - private FileUploadException fileUploadException; - - /** - * Parse the multipart request. Store the info about the request parameters - * and the uploaded files. - */ - public MultipartHttpServletRequest(HttpServletRequest request, - int maxFileSize) throws IOException { - super(request); - - Map> parameters = new HashMap>(); - Map> files = new HashMap>(); - - File tempDir = figureTemporaryDirectory(request); - ServletFileUpload upload = createUploadHandler(maxFileSize, tempDir); - - parseQueryString(request.getQueryString(), parameters); - - try { - List items = parseRequestIntoFileItems(request, upload); - - for (FileItem item : items) { - // Process a regular form field - if (item.isFormField()) { - addToParameters(parameters, item.getFieldName(), item - .getString("UTF-8")); - log.debug("Form field (parameter) " + item.getFieldName() - + "=" + item.getString()); - } else { - addToFileItems(files, item); - log.debug("File " + item.getFieldName() + ": " - + item.getName()); - } - } - } catch (FileUploadException e) { - fileUploadException = e; - request.setAttribute( - FileUploadServletRequest.FILE_UPLOAD_EXCEPTION, e); - } - - this.parameters = Collections.unmodifiableMap(parameters); - log.debug("Parameters are: " + this.parameters); - this.files = Collections.unmodifiableMap(files); - log.debug("Files are: " + this.files); - request.setAttribute(FILE_ITEM_MAP, this.files); - } - - /** - * Pull any parameters out of the URL. - */ - private void parseQueryString(String queryString, - Map> parameters) { - log.debug("Query string is : '" + queryString + "'"); - if (queryString != null) { - String[] pieces = queryString.split("&"); - - for (String piece : pieces) { - int equalsHere = piece.indexOf('='); - if (piece.trim().isEmpty()) { - // Ignore an empty piece. - } else if (equalsHere <= 0) { - // A parameter without a value. - addToParameters(parameters, decode(piece), ""); - } else { - // A parameter with a value. - String key = piece.substring(0, equalsHere); - String value = piece.substring(equalsHere + 1); - addToParameters(parameters, decode(key), decode(value)); - } - } - } - log.debug("Parameters from query string are: " + parameters); - } - - /** - * Remove any special URL-style encoding. - */ - private String decode(String encoded) { - try { - return URLDecoder.decode(encoded, "UTF-8"); - } catch (UnsupportedEncodingException e) { - log.error(e, e); - return encoded; - } - } - - /** - * Find the temporary storage directory for this webapp. - */ - private File figureTemporaryDirectory(HttpServletRequest request) { - return (File) request.getSession().getServletContext().getAttribute( - "javax.servlet.context.tempdir"); - } - - /** - * Create an upload handler that will throw an exception if the file is too - * large. - */ - private ServletFileUpload createUploadHandler(int maxFileSize, File tempDir) { - DiskFileItemFactory factory = new DiskFileItemFactory(); - factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD); - factory.setRepository(tempDir); - - ServletFileUpload upload = new ServletFileUpload(factory); - upload.setSizeMax(maxFileSize); - - return upload; - } - - /** Either create a new List for the value, or add to an existing List. */ - private void addToParameters(Map> map, String name, - String value) { - if (!map.containsKey(name)) { - map.put(name, new ArrayList()); - } - map.get(name).add(value); - } - - /** Either create a new List for the file, or add to an existing List. */ - private void addToFileItems(Map> map, FileItem file) { - String name = file.getFieldName(); - if (!map.containsKey(name)) { - map.put(name, new ArrayList()); - } - map.get(name).add(file); - } - - /** Minimize the code that uses the unchecked cast. */ - @SuppressWarnings("unchecked") - private List parseRequestIntoFileItems(HttpServletRequest req, - ServletFileUpload upload) throws FileUploadException { - return upload.parseRequest(req); - } - - // ---------------------------------------------------------------------- - // This is a multipart request, so make the file info available. If there - // was an exception during parsing, make that available too. - // ---------------------------------------------------------------------- - - @Override - public boolean isMultipart() { - return true; - } - - @Override - public Map> getFiles() { - return files; - } - - /** - * {@inheritDoc} - *

- * There may be more than one file item with the given name. If the first - * one is empty (size is zero), keep looking for a non-empty one. - *

- */ - @Override - public FileItem getFileItem(String name) { - List items = files.get(name); - if (items == null) { - return null; - } - - for (FileItem item : items) { - if (item.getSize() > 0L) { - return item; - } - } - - return null; - } - - @Override - public FileUploadException getFileUploadException() { - return fileUploadException; - } - - @Override - public boolean hasFileUploadException() { - return fileUploadException != null; - } - - // ---------------------------------------------------------------------- - // Parameter-related methods won't find anything on the delegate request, - // since parsing consumed the parameters. So we need to look to the parsed - // info for the answers. - // ---------------------------------------------------------------------- - - @Override - public String getParameter(String name) { - if (parameters.containsKey(name)) { - return parameters.get(name).get(0); - } else { - return null; - } - } - - @Override - public Enumeration getParameterNames() { - return Collections.enumeration(parameters.keySet()); - } - - @Override - public String[] getParameterValues(String name) { - if (parameters.containsKey(name)) { - return parameters.get(name).toArray(EMPTY_ARRAY); - } else { - return null; - } - } - - @Override - public Map getParameterMap() { - Map result = new HashMap(); - for (Entry> entry : parameters.entrySet()) { - result.put(entry.getKey(), entry.getValue().toArray(EMPTY_ARRAY)); - } - log.debug("resulting parameter map: " + result); - return result; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java deleted file mode 100644 index 246377048..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java +++ /dev/null @@ -1,81 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUploadException; - -/** - * A wrapper for a servlet request that does not hold multipart content. Pass - * all parameter-related requests to the delegate, and give simple answers to - * all file-related requests. - */ -class SimpleHttpServletRequestWrapper extends FileUploadServletRequest { - - SimpleHttpServletRequestWrapper(HttpServletRequest request) { - super(request); - request.setAttribute(FILE_ITEM_MAP, Collections.EMPTY_MAP); - } - - // ---------------------------------------------------------------------- - // Not a multipart request, so there are no files or upload exceptions. - // ---------------------------------------------------------------------- - - @Override - public boolean isMultipart() { - return false; - } - - @Override - public Map> getFiles() { - return Collections.emptyMap(); - } - - @Override - public FileItem getFileItem(String string) { - return null; - } - - @Override - public FileUploadException getFileUploadException() { - return null; - } - - @Override - public boolean hasFileUploadException() { - return false; - } - - // ---------------------------------------------------------------------- - // Since this is not a multipart request, the parameter methods can be - // delegated. - // ---------------------------------------------------------------------- - - @Override - public String getParameter(String name) { - return getDelegate().getParameter(name); - } - - @Override - public Map getParameterMap() { - return getDelegate().getParameterMap(); - } - - @Override - public Enumeration getParameterNames() { - return getDelegate().getParameterNames(); - } - - @Override - public String[] getParameterValues(String name) { - return getDelegate().getParameterValues(name); - } - -}