Author: ieb
Date: Fri Aug 12 11:57:30 2016
New Revision: 1756166
URL: http://svn.apache.org/viewvc?rev=1756166&view=rev
Log:
SLING-5948 Support Streaming - Implementation of proposal 1 using a
Interator<Part>
Added:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
(with props)
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.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=1756166&r1=1756165&r2=1756166&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:57:30 2016
@@ -281,10 +281,27 @@ public class ParameterSupport {
// Multipart POST
if (ServletFileUpload.isMultipartContent(new
ServletRequestContext(this.getServletRequest()))) {
- this.parseMultiPartPost(parameters);
- this.requestDataUsed = true;
- addContainerParameters = checkForAdditionalParameters;
- useFallback = false;
+ 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.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);
+ } catch (FileUploadException e) {
+ this.log.error("getRequestParameterMapInternal:
Error parsing mulmultipart streamed request", e);
+ }
+ // The request data has been passed to the
RequestPartsIterator, hence from a RequestParameter pov its been used, and must
not be used again.
+ this.requestDataUsed = true;
+ // must not try and get anything from the request at
this point so avoid jumping through the stream.
+ addContainerParameters = false;
+ useFallback = false;
+ } else {
+ this.parseMultiPartPost(parameters);
+ this.requestDataUsed = true;
+ addContainerParameters = checkForAdditionalParameters;
+ useFallback = false;
+ }
}
}
if ( useFallback ) {
@@ -300,6 +317,22 @@ public class ParameterSupport {
return this.postParameterMap;
}
+
+ /**
+ * Checks to see if there is an upload mode header or uploadmode parameter
indicating the request is
+ * to be streamed from the client to the server.
+ * @param parameters parameters processed from the query string only.
+ * @param servletRequest the servlet request, where the body has not been
processed.
+ * @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") ) ) {
+ return true;
+ }
+ RequestParameter[] rp = parameters.get("uploadmode");
+ return ( rp != null && rp.length == 1 &&
"stream".equals(rp[0].getString()));
+ }
+
private void getContainerParameters(final ParameterMap parameters, final
String encoding, final boolean alwaysAdd) {
final Map<?, ?> pMap = getServletRequest().getParameterMap();
for (Map.Entry<?, ?> entry : pMap.entrySet()) {
@@ -368,4 +401,6 @@ public class ParameterSupport {
}
}
+
+
}
\ No newline at end of file
Added:
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=1756166&view=auto
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
(added)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
Fri Aug 12 11:57:30 2016
@@ -0,0 +1,141 @@
+/*
+ * 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.sling.engine.impl.parameters;
+
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.Part;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+public class RequestPartsIterator implements Iterator<Part> {
+ private static final Logger LOG =
LoggerFactory.getLogger(RequestPartsIterator.class);
+ private final FileItemIterator itemIterator;
+
+ public RequestPartsIterator(HttpServletRequest servletRequest) throws
IOException, FileUploadException {
+ ServletFileUpload upload = new ServletFileUpload();
+ itemIterator = upload.getItemIterator(servletRequest);
+ }
+
+ @Override
+ public boolean hasNext() {
+ try {
+ return itemIterator.hasNext();
+ } catch (FileUploadException e) {
+ LOG.error("hasNext Item failed cause:" + e.getMessage(), e);
+ } catch (IOException e) {
+ LOG.error("hasNext Item failed cause:" + e.getMessage(), e);
+ }
+ return false;
+ }
+
+ @Override
+ public Part next() {
+ try {
+ return new StreamedRequestPart(itemIterator.next());
+ } catch (IOException e) {
+ LOG.error("next Item failed cause:" + e.getMessage(), e);
+ } catch (FileUploadException e) {
+ LOG.error("next Item failed cause:" + e.getMessage(), e);
+ }
+ return null;
+ }
+
+ private static class StreamedRequestPart implements Part {
+ private final FileItemStream fileItem;
+ private final InputStream inputStream;
+
+ public StreamedRequestPart(FileItemStream fileItem) throws IOException
{
+ this.fileItem = fileItem;
+ inputStream = fileItem.openStream();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return inputStream;
+ }
+
+ @Override
+ public String getContentType() {
+ return fileItem.getContentType();
+ }
+
+ @Override
+ public String getName() {
+ return fileItem.getName();
+ }
+
+ @Override
+ public long getSize() {
+ return 0;
+ }
+
+ @Override
+ public void write(String s) throws IOException {
+ throw new UnsupportedOperationException("Writing parts directly to
disk is not supported by this implementation, use getInputStream instead");
+ }
+
+ @Override
+ public void delete() throws IOException {
+ // no underlying storage is used, so nothing to delete.
+ }
+
+ @Override
+ public String getHeader(String headerName) {
+ return fileItem.getHeaders().getHeader(headerName);
+ }
+
+ @Override
+ public Collection<String> getHeaders(String headerName) {
+ return toCollection(fileItem.getHeaders().getHeaders(headerName));
+ }
+
+
+ @Override
+ public Collection<String> getHeaderNames() {
+ return toCollection(fileItem.getHeaders().getHeaderNames());
+ }
+
+ @Override
+ public String getSubmittedFileName() {
+ return fileItem.getFieldName();
+ }
+
+ private <T> Collection<T> toCollection(Iterator<T> i) {
+ if ( i == null ) {
+ return Collections.emptyList();
+ } else {
+ List<T> c = new ArrayList<T>();
+ while(i.hasNext()) {
+ c.add(i.next());
+ }
+ return c;
+ }
+ }
+
+ }
+}
Propchange:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestPartsIterator.java
------------------------------------------------------------------------------
svn:eol-style = native