Author: ieb
Date: Fri Aug 12 11:58:06 2016
New Revision: 1756169
URL: http://svn.apache.org/viewvc?rev=1756169&view=rev
Log:
SLING-5948 Support Streaming - Cleaned up headers, added more javadoc,
incorporated feedback from RTC
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java?rev=1756169&r1=1756168&r2=1756169&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java
Fri Aug 12 11:58:06 2016
@@ -70,6 +70,15 @@ public class ParameterSupport {
/** Content type signaling parameters in request body */
private static final String WWW_FORM_URL_ENC =
"application/x-www-form-urlencoded";
+ /** name of the header used to identify an upload mode */
+ public static final String SLING_UPLOADMODE_HEADER = "Sling-uploadmode";
+ /** name of the parameter used to identify upload mode */
+ public static final String UPLOADMODE_PARAM = "uploadmode";
+ /** request attribute that stores the parts iterator when streaming */
+ public static final String REQUEST_PARTS_ITERATOR_ATTRIBUTE =
"request-parts-iterator";
+ /** value of upload mode header/parameter indicating streaming is
requested */
+ public static final String STREAM_UPLOAD = "stream";
+
/** default log */
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -284,7 +293,7 @@ public class ParameterSupport {
if (isStreamed(parameters, this.getServletRequest())) {
// special case, the request is Mutipart and streamed
processing has been requested
try {
-
this.getServletRequest().setAttribute("request-parts-iterator", new
RequestPartsIterator(this.getServletRequest()));
+
this.getServletRequest().setAttribute(REQUEST_PARTS_ITERATOR_ATTRIBUTE, new
RequestPartsIterator(this.getServletRequest()));
this.log.debug("getRequestParameterMapInternal:
Iterator<javax.servlet.http.Part> available as request attribute named
request-parts-iterator");
} catch (IOException e) {
this.log.error("getRequestParameterMapInternal:
Error parsing mulmultipart streamed requesttipart streamed request", e);
@@ -326,11 +335,11 @@ public class ParameterSupport {
* @return true if the request was made with streaming in mind.
*/
private boolean isStreamed(ParameterMap parameters, HttpServletRequest
servletRequest) {
- if ( "stream".equals(servletRequest.getHeader("X-uploadmode") ) ) {
+ if (
STREAM_UPLOAD.equals(servletRequest.getHeader(SLING_UPLOADMODE_HEADER)) ) {
return true;
}
- RequestParameter[] rp = parameters.get("uploadmode");
- return ( rp != null && rp.length == 1 &&
"stream".equals(rp[0].getString()));
+ RequestParameter[] rp = parameters.get(UPLOADMODE_PARAM);
+ return ( rp != null && rp.length == 1 &&
STREAM_UPLOAD.equals(rp[0].getString()));
}
private void getContainerParameters(final ParameterMap parameters, final
String encoding, final boolean alwaysAdd) {
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java?rev=1756169&r1=1756168&r2=1756169&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
Fri Aug 12 11:58:06 2016
@@ -36,10 +36,22 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+/**
+ * Contains a Lazy iterator of Parts from the request stream loaded as the
request is streamed using the Commons FileUpload API.
+ */
public class RequestPartsIterator implements Iterator<Part> {
private static final Logger LOG =
LoggerFactory.getLogger(RequestPartsIterator.class);
+
+ /** The CommonsFile Upload streaming API iterator */
private final FileItemIterator itemIterator;
+ /**
+ * Create and initialse the iterator using the request. The request must
be fresh. Headers can have been read but the stream
+ * must not have been parsed.
+ * @param servletRequest the request
+ * @throws IOException when there is a problem reading the request.
+ * @throws FileUploadException when there is a problem parsing the request.
+ */
public RequestPartsIterator(HttpServletRequest servletRequest) throws
IOException, FileUploadException {
ServletFileUpload upload = new ServletFileUpload();
itemIterator = upload.getItemIterator(servletRequest);
@@ -69,6 +81,9 @@ public class RequestPartsIterator implem
return null;
}
+ /**
+ * Internal implementation of the Part API from Servlet 3 wrapping the
Commons File Upload FIleItemStream object.
+ */
private static class StreamedRequestPart implements Part {
private final FileItemStream fileItem;
private final InputStream inputStream;
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java?rev=1756169&r1=1756168&r2=1756169&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
(original)
+++
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
Fri Aug 12 11:58:06 2016
@@ -71,6 +71,13 @@ public class StreamedUploadOperation ext
}
+ /**
+ * Check the request and return true if there is a parts iterator
attribute present. This attribute
+ * will have been put there by the Sling Engine ParameterSupport class. If
its not present, the request
+ * is not streamed and cant be processed by this class. Check this first
before using this class.
+ * @param request the request.
+ * @return true if the request can be streamed.
+ */
public boolean isRequestStreamed(SlingHttpServletRequest request) {
return request.getAttribute("request-parts-iterator") != null;
}
@@ -108,6 +115,12 @@ public class StreamedUploadOperation ext
}
+ /**
+ * Add a field to the store of formFields.
+ * @param formFields the formFileds
+ * @param name the name of the field.
+ * @param part the part.
+ */
private void addField(Map<String, List<String>> formFields, String name,
Part part) {
List<String> values = formFields.get(name);
if ( values == null ) {
@@ -122,6 +135,17 @@ public class StreamedUploadOperation ext
}
+ /**
+ * Write content to the resource API creating a standard JCR structure of
nt:file - nt:resource - jcr:data.
+ * This method will commit to the repository to force the repository to
read from the input stream and write
+ * to the target. How efficient that is depends on the repository
implementation.
+ * @param resolver the resource resolver.
+ * @param part the part containing the file body.
+ * @param formFields form fields collected so far.
+ * @param response the response object, updated by the operation.
+ * @param changes changes made to the repo.
+ * @throws PersistenceException
+ */
private void writeContent(final ResourceResolver resolver,
final Part part,
final Map<String, List<String>> formFields,
@@ -172,10 +196,20 @@ public class StreamedUploadOperation ext
}
}
+ /**
+ * Is the part a form field ?
+ * @param part
+ * @return
+ */
private boolean isFormField(Part part) {
return (part.getSubmittedFileName() == null);
}
+ /**
+ * Get the upload file name from the part.
+ * @param part
+ * @return
+ */
private String getUploadName(Part part) {
String name = part.getSubmittedFileName();
// strip of possible path (some browsers include the entire path)
@@ -184,12 +218,21 @@ public class StreamedUploadOperation ext
return Text.escapeIllegalJcrChars(name);
}
+ /**
+ * Does the resource exist ?
+ * @param resource
+ * @return
+ */
private boolean resourceExists(final Resource resource) {
return (resource != null &&
!ResourceUtil.isSyntheticResource(resource));
}
-
+ /**
+ * Get the content type of the part.
+ * @param part
+ * @return
+ */
private String getContentType(final Part part) {
String contentType = part.getContentType();
if (contentType != null) {