Class LockssMultipartHttpServletRequest
- All Implemented Interfaces:
jakarta.servlet.http.HttpServletRequest,jakarta.servlet.ServletRequest,org.springframework.web.multipart.MultipartHttpServletRequest,org.springframework.web.multipart.MultipartRequest
StandardMultipartHttpServletRequest and
Tomcat's Request, and adapted to workaround issues in those implementations that prevent
us from supporting features necessary for the operation of LOCKSS Repository Service:
1. Computing part digests should ideally be done as they're read from the network stream, but it
is not possible to do this early enough: StandardMultipartHttpServletRequest wraps an
HttpServletRequest from the servlet framework and calls HttpServletRequest.getParts()
in its parsing of the request. The Tomcat implementation (Request), is hardcoded to use
DiskFileItemFactory and FileUpload which write parts (over a size threshold) to
temporary files, prior to making them available to controller methods through
StandardMultipartHttpServletRequest.StandardMultipartFile. Jetty appears to use its own
multipart parsing logic that is similarly hardcoded. I did not check Undertow.
To work around this, Tomcat's Request.getParts() and Request.parseParts(boolean)}
implementations were copied here and adapted to parse the wrapped HttpServletRequest using
a DigestFileItemFactory. Since Tomcat's ApplicationPart does not allow access to
its wrapped FileItem, and there is no getDigest() or similar in the Part
API, it was also necessary to introduce LockssMultipartHttpServletRequest.LockssApplicationPart. Those are in turn used to
construct LockssMultipartHttpServletRequest.LockssMultipartFiles, which are the objects ultimately returned to the REST
controller method.
2.Malformed part Content-Type header handling: We've chosen to transmit the content-type of
an artifact in the part's Content-Type header. Malformed content types were found to cause
problems during the serialization of a multipart request (and previously, multipart responses). To
work around this, the content type is transmitted via a custom header and falls back to the usual
Content-Type if it is not present. Support for receiving a part employing this workaround and
returning the intended, malformed type was added to LockssMultipartHttpServletRequest.LockssMultipartFile.getContentType().
- See Also:
-
StandardMultipartHttpServletRequestStandardServletMultipartResolverLockssMultipartResolverDigestFileItemFactoryDigestFileItem
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classLOCKSS implementation of a SpringMultipartFileadapter, wrapping a LOCKSS Servlet Part object (seeLockssMultipartHttpServletRequest.LockssApplicationPart). -
Field Summary
FieldsFields inherited from interface jakarta.servlet.http.HttpServletRequest
BASIC_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH, FORM_AUTH -
Constructor Summary
ConstructorsConstructorDescriptionLockssMultipartHttpServletRequest(jakarta.servlet.http.HttpServletRequest request) Create a new LockssMultipartHttpServletRequest wrapper for the given request, immediately parsing the multipart content.LockssMultipartHttpServletRequest(jakarta.servlet.http.HttpServletRequest request, boolean lazyParsing) Create a new LockssMultipartHttpServletRequest wrapper for the given request. -
Method Summary
Modifier and TypeMethodDescriptionTaken unmodified fromRequest.getCharset().booleanintintjakarta.servlet.MultipartConfigElementgetMultipartContentType(String paramOrFileName) Taken unmodified fromStandardMultipartHttpServletRequest.getMultipartContentType(String).org.springframework.http.HttpHeadersgetMultipartHeaders(String paramOrFileName) Taken unmodified fromStandardMultipartHttpServletRequest.getMultipartHeaders(String).Taken unmodified fromStandardMultipartHttpServletRequest.getParameterMap().Taken unmodified fromStandardMultipartHttpServletRequest.getParameterNames().String[]getParameterValues(String name) Adapted fromServletRequestWrapper.getParameterValues(String), a parent class ofStandardMultipartHttpServletRequest.jakarta.servlet.http.PartTaken unmodified fromRequest.getPart(String).Collection<jakarta.servlet.http.Part>getParts()Taken unmodified fromRequest.getParts().protected voidTaken unmodified fromStandardMultipartHttpServletRequest.handleParseFailure(Throwable).protected voidTaken unmodified fromStandardMultipartHttpServletRequest.initializeMultipart().voidsetCreateUploadTargets(boolean createUploadTargets) voidsetMaxParameterCount(int maxParameterCount) voidsetMaxPostSize(int maxPostSize) setMultipartConfigElement(jakarta.servlet.MultipartConfigElement mce) Methods inherited from class org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest
getFile, getFileMap, getFileNames, getFiles, getMultiFileMap, getMultipartFiles, getRequest, getRequestHeaders, getRequestMethod, isResolved, setMultipartFilesMethods inherited from class jakarta.servlet.http.HttpServletRequestWrapper
authenticate, changeSessionId, getAuthType, getContextPath, getCookies, getDateHeader, getHeader, getHeaderNames, getHeaders, getHttpServletMapping, getIntHeader, getMethod, getPathInfo, getPathTranslated, getQueryString, getRemoteUser, getRequestedSessionId, getRequestURI, getRequestURL, getServletPath, getSession, getSession, getTrailerFields, getUserPrincipal, isRequestedSessionIdFromCookie, isRequestedSessionIdFromURL, isRequestedSessionIdValid, isTrailerFieldsReady, isUserInRole, login, logout, newPushBuilder, upgradeMethods inherited from class jakarta.servlet.ServletRequestWrapper
getAsyncContext, getAttribute, getAttributeNames, getCharacterEncoding, getContentLength, getContentLengthLong, getContentType, getDispatcherType, getInputStream, getLocalAddr, getLocale, getLocales, getLocalName, getLocalPort, getParameter, getProtocol, getProtocolRequestId, getReader, getRemoteAddr, getRemoteHost, getRemotePort, getRequestDispatcher, getRequestId, getScheme, getServerName, getServerPort, getServletConnection, getServletContext, isAsyncStarted, isAsyncSupported, isSecure, isWrapperFor, isWrapperFor, removeAttribute, setAttribute, setCharacterEncoding, setRequest, startAsync, startAsyncMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface jakarta.servlet.http.HttpServletRequest
authenticate, changeSessionId, getAuthType, getContextPath, getCookies, getDateHeader, getHeader, getHeaderNames, getHeaders, getHttpServletMapping, getIntHeader, getMethod, getPathInfo, getPathTranslated, getQueryString, getRemoteUser, getRequestedSessionId, getRequestURI, getRequestURL, getServletPath, getSession, getSession, getTrailerFields, getUserPrincipal, isRequestedSessionIdFromCookie, isRequestedSessionIdFromURL, isRequestedSessionIdValid, isTrailerFieldsReady, isUserInRole, login, logout, newPushBuilder, upgradeMethods inherited from interface jakarta.servlet.ServletRequest
getAsyncContext, getAttribute, getAttributeNames, getCharacterEncoding, getContentLength, getContentLengthLong, getContentType, getDispatcherType, getInputStream, getLocalAddr, getLocale, getLocales, getLocalName, getLocalPort, getParameter, getProtocol, getProtocolRequestId, getReader, getRemoteAddr, getRemoteHost, getRemotePort, getRequestDispatcher, getRequestId, getScheme, getServerName, getServerPort, getServletConnection, getServletContext, isAsyncStarted, isAsyncSupported, isSecure, removeAttribute, setAttribute, setCharacterEncoding, startAsync, startAsync
-
Field Details
-
partsParseException
-
-
Constructor Details
-
LockssMultipartHttpServletRequest
public LockssMultipartHttpServletRequest(jakarta.servlet.http.HttpServletRequest request) throws org.springframework.web.multipart.MultipartException Create a new LockssMultipartHttpServletRequest wrapper for the given request, immediately parsing the multipart content.- Parameters:
request- the servlet request to wrap- Throws:
org.springframework.web.multipart.MultipartException- if parsing failed
-
LockssMultipartHttpServletRequest
public LockssMultipartHttpServletRequest(jakarta.servlet.http.HttpServletRequest request, boolean lazyParsing) throws org.springframework.web.multipart.MultipartException Create a new LockssMultipartHttpServletRequest wrapper for the given request.- Parameters:
request- the servlet request to wraplazyParsing- whether multipart parsing should be triggered lazily on first access of multipart files or parameters- Throws:
org.springframework.web.multipart.MultipartException- if an immediate parsing attempt failed
-
-
Method Details
-
setMaxParameterCount
public void setMaxParameterCount(int maxParameterCount) -
getMaxParameterCount
public int getMaxParameterCount() -
setMaxPostSize
public void setMaxPostSize(int maxPostSize) -
getMaxPostSize
public int getMaxPostSize() -
setCreateUploadTargets
public void setCreateUploadTargets(boolean createUploadTargets) -
getCreateUploadTargets
public boolean getCreateUploadTargets() -
setMultipartConfigElement
public LockssMultipartHttpServletRequest setMultipartConfigElement(jakarta.servlet.MultipartConfigElement mce) -
getMultipartConfigElement
public jakarta.servlet.MultipartConfigElement getMultipartConfigElement() -
getCharset
Taken unmodified fromRequest.getCharset().- Throws:
UnsupportedEncodingException
-
getParts
public Collection<jakarta.servlet.http.Part> getParts() throws IOException, IllegalStateException, jakarta.servlet.ServletExceptionTaken unmodified fromRequest.getParts().- Specified by:
getPartsin interfacejakarta.servlet.http.HttpServletRequest- Overrides:
getPartsin classjakarta.servlet.http.HttpServletRequestWrapper- Throws:
IOExceptionIllegalStateExceptionjakarta.servlet.ServletException
-
handleParseFailure
Taken unmodified fromStandardMultipartHttpServletRequest.handleParseFailure(Throwable). -
initializeMultipart
protected void initializeMultipart()Taken unmodified fromStandardMultipartHttpServletRequest.initializeMultipart().- Overrides:
initializeMultipartin classorg.springframework.web.multipart.support.AbstractMultipartHttpServletRequest
-
getParameterNames
Taken unmodified fromStandardMultipartHttpServletRequest.getParameterNames().- Specified by:
getParameterNamesin interfacejakarta.servlet.ServletRequest- Overrides:
getParameterNamesin classjakarta.servlet.ServletRequestWrapper
-
getParameterValues
Adapted fromServletRequestWrapper.getParameterValues(String), a parent class ofStandardMultipartHttpServletRequest.- Specified by:
getParameterValuesin interfacejakarta.servlet.ServletRequest- Overrides:
getParameterValuesin classjakarta.servlet.ServletRequestWrapper
-
getParameterMap
Taken unmodified fromStandardMultipartHttpServletRequest.getParameterMap().- Specified by:
getParameterMapin interfacejakarta.servlet.ServletRequest- Overrides:
getParameterMapin classjakarta.servlet.ServletRequestWrapper
-
getMultipartContentType
Taken unmodified fromStandardMultipartHttpServletRequest.getMultipartContentType(String). -
getMultipartHeaders
Taken unmodified fromStandardMultipartHttpServletRequest.getMultipartHeaders(String). -
getPart
public jakarta.servlet.http.Part getPart(String name) throws IOException, IllegalStateException, jakarta.servlet.ServletException Taken unmodified fromRequest.getPart(String).- Specified by:
getPartin interfacejakarta.servlet.http.HttpServletRequest- Overrides:
getPartin classjakarta.servlet.http.HttpServletRequestWrapper- Throws:
IOExceptionIllegalStateExceptionjakarta.servlet.ServletException
-