Author: pauls Date: Tue Sep 19 14:15:50 2017 New Revision: 1808882 URL: http://svn.apache.org/viewvc?rev=1808882&view=rev Log: Add a fork of the api and the engine to prototype using the default servlet 3.1 support for multipart requests
Added: sling/whiteboard/pauls/api/ - copied from r1808880, sling/trunk/bundles/api/ sling/whiteboard/pauls/engine/ - copied from r1808880, sling/trunk/bundles/engine/ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportFilter.java Removed: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportConfigurer.java Modified: sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/SlingHttpServletRequest.java sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameter.java sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameterMap.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ContainerRequestParameter.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/MultipartRequestParameter.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupportHttpServletRequestWrapper.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingPart.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingUnsupportedEncodingException.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/Util.java sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java Modified: sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/SlingHttpServletRequest.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/SlingHttpServletRequest.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/SlingHttpServletRequest.java (original) +++ sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/SlingHttpServletRequest.java Tue Sep 19 14:15:50 2017 @@ -109,6 +109,7 @@ public interface SlingHttpServletRequest * @see RequestParameterMap#getValue(String) * @throws IllegalArgumentException if name is <code>null</code>. */ + @Deprecated @CheckForNull RequestParameter getRequestParameter(@Nonnull String name); /** @@ -129,6 +130,7 @@ public interface SlingHttpServletRequest * @see RequestParameterMap#getValues(String) * @throws IllegalArgumentException if name is <code>null</code>. */ + @Deprecated @CheckForNull RequestParameter[] getRequestParameters(@Nonnull String name); /** @@ -145,6 +147,7 @@ public interface SlingHttpServletRequest * parameter map are of type String. The values in the parameter map * are of type {@link RequestParameter} array (<code>RequestParameter[]</code>). */ + @Deprecated @Nonnull RequestParameterMap getRequestParameterMap(); /** @@ -157,6 +160,7 @@ public interface SlingHttpServletRequest * order. * @since 2.3 (Sling API Bundle 2.6.0) */ + @Deprecated @Nonnull List<RequestParameter> getRequestParameterList(); /** Modified: sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameter.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameter.java (original) +++ sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameter.java Tue Sep 19 14:15:50 2017 @@ -39,6 +39,7 @@ import org.osgi.annotation.versioning.Pr * @see org.apache.sling.api.SlingHttpServletRequest#getRequestParameterMap() */ @ProviderType +@Deprecated public interface RequestParameter { /** Modified: sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameterMap.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameterMap.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameterMap.java (original) +++ sling/whiteboard/pauls/api/src/main/java/org/apache/sling/api/request/RequestParameterMap.java Tue Sep 19 14:15:50 2017 @@ -31,6 +31,7 @@ import org.osgi.annotation.versioning.Pr * a request. */ @ProviderType +@Deprecated public interface RequestParameterMap extends Map<String, RequestParameter[]> { /** Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java Tue Sep 19 14:15:50 2017 @@ -24,6 +24,7 @@ import java.net.URL; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.sling.api.request.RequestParameter; import org.apache.sling.api.request.RequestProgressTracker; import org.apache.sling.auth.core.AuthenticationSupport; import org.apache.sling.commons.mime.MimeTypeService; @@ -125,8 +126,10 @@ class SlingHttpContext extends ServletCo if (authenticator != null) { // SLING-559: ensure correct parameter handling according to - // ParameterSupport - request = ParameterSupport.getParameterSupportRequestWrapper(request); + // ParameterSupport if path is configured to match + if (ParameterSupport.matches(request.getRequestURI())) { + request = ParameterSupport.getParameterSupportRequestWrapper(request); + } final boolean result = authenticator.handleSecurity(request, response); t.logTimer(timerName, "authenticator {0} returns {1}", authenticator, result); Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java Tue Sep 19 14:15:50 2017 @@ -18,27 +18,6 @@ */ package org.apache.sling.engine.impl; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletInputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.Part; - import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.request.RequestDispatcherOptions; import org.apache.sling.api.request.RequestParameter; @@ -48,12 +27,41 @@ import org.apache.sling.api.request.Requ import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.engine.impl.helper.NullResourceBundle; -import org.apache.sling.engine.impl.parameters.ParameterSupport; import org.apache.sling.engine.impl.request.ContentData; import org.apache.sling.engine.impl.request.RequestData; import org.apache.sling.engine.impl.request.SlingRequestDispatcher; import org.osgi.service.http.HttpContext; import org.osgi.service.useradmin.Authorization; +import sun.misc.IOUtils; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.Part; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; public class SlingHttpServletRequestImpl extends HttpServletRequestWrapper implements SlingHttpServletRequest { @@ -91,10 +99,6 @@ public class SlingHttpServletRequestImpl //---------- SlingHttpServletRequest interface - ParameterSupport getParameterSupport() { - return this.getRequestData().getParameterSupport(); - } - @Override public Resource getResource() { final ContentData cd = getRequestData().getContentData(); @@ -146,51 +150,42 @@ public class SlingHttpServletRequestImpl } /** - * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String) - */ - @Override - public String getParameter(String name) { - return this.getParameterSupport().getParameter(name); - } - - /** - * @see javax.servlet.ServletRequestWrapper#getParameterMap() - */ - @Override - public Map<String, String[]> getParameterMap() { - return this.getParameterSupport().getParameterMap(); - } - - /** - * @see javax.servlet.ServletRequestWrapper#getParameterNames() - */ - @Override - public Enumeration<String> getParameterNames() { - return this.getParameterSupport().getParameterNames(); - } - - /** - * @see javax.servlet.ServletRequestWrapper#getParameterValues(java.lang.String) - */ - @Override - public String[] getParameterValues(String name) { - return this.getParameterSupport().getParameterValues(name); - } - - /** - * @see org.apache.sling.api.SlingHttpServletRequest#getRequestParameter(java.lang.String) - */ - @Override - public RequestParameter getRequestParameter(String name) { - return this.getParameterSupport().getRequestParameter(name); - } - - /** * @see org.apache.sling.api.SlingHttpServletRequest#getRequestParameters(java.lang.String) */ @Override public RequestParameter[] getRequestParameters(String name) { - return this.getParameterSupport().getRequestParameters(name); + if (getContentType() != null && getContentType().startsWith("multipart/form-data")) { + try { + List<RequestParameter> result = new ArrayList<>(); + for (Part part : getParts()) { + if (part.getName().equals(name)) { + result.add(new PartRequestParameterImpl(name, part)); + } + } + if (!result.isEmpty()) { + return result.toArray(new RequestParameter[0]); + } else { + return null; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + String[] values = getRequest().getParameterValues(name); + if (values != null) { + RequestParameter[] result = new RequestParameter[values.length]; + for (int i = 0; i < values.length; i++) { + try { + result[i] = new StringRequestParameterImpl(name, values[i], values[i].getBytes(getEncoding())); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + return result; + } else { + return null; + } + } } /** @@ -198,7 +193,7 @@ public class SlingHttpServletRequestImpl */ @Override public RequestParameterMap getRequestParameterMap() { - return this.getParameterSupport().getRequestParameterMap(); + return new RequestParametersMapImpl(); } /** @@ -206,7 +201,28 @@ public class SlingHttpServletRequestImpl */ @Override public List<RequestParameter> getRequestParameterList() { - return this.getParameterSupport().getRequestParameterList(); + List<RequestParameter> result = new ArrayList<>(); + if (getContentType().startsWith("multipart/form-data")) { + try { + for (Part part : getParts()) { + RequestParameter[] params = getRequestParameters(part.getName()); + if (params != null) { + result.addAll(Arrays.asList(params)); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + else { + for (Enumeration<String> names = getParameterNames(); names.hasMoreElements(); ) { + RequestParameter[] params = getRequestParameters(names.nextElement()); + if (params != null) { + result.addAll(Arrays.asList(params)); + } + } + } + return result; } /** @@ -236,6 +252,15 @@ public class SlingHttpServletRequestImpl return (cd == null) ? null : cd.getRequestPathInfo(); } + @Override + public RequestParameter getRequestParameter(String name) { + RequestParameter[] params = getRequestParameters(name); + if (params != null && params.length > 0) { + return params[0]; + } + return null; + } + /** * @see org.apache.sling.api.SlingHttpServletRequest#getResourceBundle(java.util.Locale) */ @@ -345,15 +370,6 @@ public class SlingHttpServletRequestImpl return pathInfo; } - public Part getPart(String name) { - return (Part) this.getParameterSupport().getPart(name); - } - - @SuppressWarnings("unchecked") - public Collection<Part> getParts() { - return (Collection<Part>) this.getParameterSupport().getParts(); - } - /** * A <code>UserPrincipal</code> ... */ @@ -406,4 +422,206 @@ public class SlingHttpServletRequestImpl } } + private String getEncoding(Part target) { + try { + Part part = getPart("_charset_"); + if (part != null) { + return new String(org.apache.commons.io.IOUtils.toByteArray(part.getInputStream()), getCharacterEncoding() != null ? getCharacterEncoding() : "UTF-8"); + } + } catch (Exception e) { + // Don't care + } + if (getCharacterEncoding() != null) { + return getCharacterEncoding(); + } + + return "UTF-8"; + } + + private String getEncoding() { + String part = getParameter("_charset_"); + if (part != null) { + return part; + } + if (getCharacterEncoding() != null) { + return getCharacterEncoding(); + } + + return "UTF-8"; + } + + private static final class StringRequestParameterImpl implements RequestParameter { + private final String name; + private final String value; + private final byte[] bytes; + + StringRequestParameterImpl(String name, String value, byte[] bytes) { + this.name = name; + this.value = value; + this.bytes = bytes; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isFormField() { + return true; + } + + @Override + public String getContentType() { + return null; + } + + @Override + public long getSize() { + return this.bytes.length; + } + + @Override + public byte[] get() { + return this.bytes.clone(); + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(this.bytes); + } + + @Override + public String getFileName() { + return null; + } + + @Override + public String getString() { + return this.value; + } + + @Override + public String getString(String encoding) throws UnsupportedEncodingException { + return new String(this.bytes, encoding); + } + } + + private final class PartRequestParameterImpl implements RequestParameter { + private final String name; + private final Part part; + + PartRequestParameterImpl(String name, Part part) { + this.name = name; + this.part = part; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isFormField() { + String contentDisposition = this.part.getHeader("content-disposition"); + return contentDisposition != null && contentDisposition.contains("form-data") && ! contentDisposition.contains("filename"); + } + + @Override + public String getContentType() { + return this.part.getContentType(); + } + + @Override + public long getSize() { + return this.part.getSize(); + } + + @Override + public byte[] get() { + ByteArrayOutputStream tmp = new ByteArrayOutputStream(); + + byte[] buffer = new byte[8 * 1024]; + + try (InputStream input = this.part.getInputStream()) { + + for (int i = input.read(buffer); i != -1; i = input.read(buffer)) { + tmp.write(buffer, 0, i); + } + } catch (IOException e) { + throw new RuntimeException(); + } + return tmp.toByteArray(); + } + + @Override + public InputStream getInputStream() throws IOException { + return this.part.getInputStream(); + } + + @Override + public String getFileName() { + return this.part.getSubmittedFileName(); + } + + @Override + public String getString() { + try { + return getString(getEncoding(this.part)); + } catch (UnsupportedEncodingException e) { + return new String(get()); + } + } + + @Override + public String getString(String encoding) throws UnsupportedEncodingException { + return new String(get(), encoding); + } + } + + private final class RequestParametersMapImpl extends AbstractMap<String, RequestParameter[]> implements RequestParameterMap { + @Override + public RequestParameter[] put(String key, RequestParameter[] value) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<Entry<String, RequestParameter[]>> entrySet() { + Map<String, Entry<String, RequestParameter[]>> result = new LinkedHashMap<>(); + if (getContentType() != null && getContentType().startsWith("multipart/form-data")) { + try { + for (Part part : getParts()) { + if (!result.containsKey(part.getName())) { + result.put(part.getName(), new AbstractMap.SimpleImmutableEntry<>(part.getName(), getRequestParameters(part.getName()))); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + else { + for (Enumeration<String> params = getParameterNames(); params.hasMoreElements(); ) { + String name = params.nextElement(); + result.put(name, new AbstractMap.SimpleImmutableEntry<>(name, getRequestParameters(name))); + } + } + return new HashSet<>(result.values()); + } + + @Override + public RequestParameter[] getValues(String name) { + + return getRequestParameters(name); + } + + @Override + public RequestParameter getValue(String name) { + RequestParameter[] params = getRequestParameters(name); + if (params != null && params.length > 0) { + return params[0]; + } + return null; + } + } + } Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java Tue Sep 19 14:15:50 2017 @@ -31,6 +31,7 @@ import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -76,6 +77,7 @@ import org.slf4j.LoggerFactory; Constants.SERVICE_DESCRIPTION + "=Sling Servlet" }) @Designate(ocd=SlingMainServlet.Config.class) +@MultipartConfig public class SlingMainServlet extends GenericServlet { @ObjectClassDefinition(name ="Apache Sling Main Servlet", Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java Tue Sep 19 14:15:50 2017 @@ -53,7 +53,6 @@ import org.apache.sling.engine.impl.filt import org.apache.sling.engine.impl.filter.ServletFilterManager; import org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType; import org.apache.sling.engine.impl.filter.SlingComponentFilterChain; -import org.apache.sling.engine.impl.parameters.ParameterSupport; import org.apache.sling.engine.impl.request.ContentData; import org.apache.sling.engine.impl.request.RequestData; import org.apache.sling.engine.impl.request.RequestHistoryConsolePlugin; @@ -240,19 +239,7 @@ public class SlingRequestProcessorImpl i public void processRequest(final HttpServletRequest servletRequest, final HttpServletResponse servletResponse, final ResourceResolver resourceResolver) throws IOException { - // set the marker for the parameter support - final Object oldValue = servletRequest.getAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING); - servletRequest.setAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING, Boolean.TRUE); - try { - this.doProcessRequest(servletRequest, servletResponse, resourceResolver); - } finally { - // restore the old value - if ( oldValue != null ) { - servletRequest.setAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING, oldValue); - } else { - servletRequest.removeAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING); - } - } + this.doProcessRequest(servletRequest, servletResponse, resourceResolver); } /** Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ContainerRequestParameter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ContainerRequestParameter.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ContainerRequestParameter.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ContainerRequestParameter.java Tue Sep 19 14:15:50 2017 @@ -103,7 +103,7 @@ public class ContainerRequestParameter e } /** - * @see org.apache.sling.api.request.RequestParameter#getString(java.lang.String) + * @see org.apache.sling.api.request.RequestParameter#getString(String) */ public String getString(String encoding) throws UnsupportedEncodingException { Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/MultipartRequestParameter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/MultipartRequestParameter.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/MultipartRequestParameter.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/MultipartRequestParameter.java Tue Sep 19 14:15:50 2017 @@ -18,12 +18,12 @@ */ package org.apache.sling.engine.impl.parameters; +import org.apache.commons.fileupload.FileItem; + import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import org.apache.commons.fileupload.FileItem; - /** * The <code>MultipartRequestParameter</code> represents a request parameter * from a multipart/form-data POST request. Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java Tue Sep 19 14:15:50 2017 @@ -18,6 +18,11 @@ */ package org.apache.sling.engine.impl.parameters; +import org.apache.sling.api.request.RequestParameter; +import org.apache.sling.api.request.RequestParameterMap; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.Part; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -25,12 +30,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import javax.servlet.http.Part; - -import org.apache.sling.api.request.RequestParameter; -import org.apache.sling.api.request.RequestParameterMap; -import org.slf4j.LoggerFactory; - /** * The <code>ParameterMap</code> TODO */ @@ -136,9 +135,11 @@ public class ParameterMap extends Linked public Collection<?> getParts() { final ArrayList<Part> parts = new ArrayList<Part>(this.size()); - for (RequestParameter[] param : this.values()) { - if (param.length >= 1 && param[0] instanceof MultipartRequestParameter) { - parts.add(new SlingPart((MultipartRequestParameter) param[0])); + for (RequestParameter[] params : this.values()) { + for (RequestParameter param : params) { + if (param instanceof MultipartRequestParameter) { + parts.add(new SlingPart((MultipartRequestParameter) param)); + } } } return parts; Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java Tue Sep 19 14:15:50 2017 @@ -18,21 +18,6 @@ */ package org.apache.sling.engine.impl.parameters; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; - import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.RequestContext; @@ -45,6 +30,21 @@ import org.apache.sling.api.resource.Res import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Pattern; + public class ParameterSupport { /** @@ -79,6 +79,8 @@ public class ParameterSupport { /** value of upload mode header/parameter indicating streaming is requested */ public static final String STREAM_UPLOAD = "stream"; + private static String[] patterns = null; + /** default log */ private final Logger log = LoggerFactory.getLogger(getClass()); @@ -155,12 +157,14 @@ public class ParameterSupport { static void configure(final long maxRequestSize, final String location, final long maxFileSize, final int fileSizeThreshold, - final boolean checkForAdditionalParameters) { + final boolean checkForAdditionalParameters, + final String[] patterns) { ParameterSupport.maxRequestSize = (maxRequestSize > 0) ? maxRequestSize : -1; ParameterSupport.location = (location != null) ? new File(location) : null; ParameterSupport.maxFileSize = (maxFileSize > 0) ? maxFileSize : -1; ParameterSupport.fileSizeThreshold = (fileSizeThreshold > 0) ? fileSizeThreshold : 256000; ParameterSupport.checkForAdditionalParameters = checkForAdditionalParameters; + ParameterSupport.patterns = patterns; } private ParameterSupport(HttpServletRequest servletRequest) { @@ -175,6 +179,17 @@ public class ParameterSupport { return this.requestDataUsed; } + public static boolean matches(String path) { + if (ParameterSupport.patterns != null) { + for (String pattern : ParameterSupport.patterns) { + if (path.startsWith(pattern)) { + return true; + } + } + } + return false; + } + public String getParameter(String name) { return getRequestParameterMapInternal().getStringValue(name); } Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupportHttpServletRequestWrapper.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupportHttpServletRequestWrapper.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupportHttpServletRequestWrapper.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupportHttpServletRequestWrapper.java Tue Sep 19 14:15:50 2017 @@ -18,13 +18,12 @@ */ package org.apache.sling.engine.impl.parameters; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Map; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.Part; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Map; public class ParameterSupportHttpServletRequestWrapper extends HttpServletRequestWrapper { public ParameterSupportHttpServletRequestWrapper(HttpServletRequest request) { Added: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportFilter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportFilter.java?rev=1808882&view=auto ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportFilter.java (added) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportFilter.java Tue Sep 19 14:15:50 2017 @@ -0,0 +1,192 @@ +/* + * 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.sling.settings.SlingSettingsService; +import org.osgi.framework.Constants; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.regex.Pattern; + +@Component( + name = RequestParameterSupportFilter.PID, + property = { + Constants.SERVICE_RANKING + ":Integer=" + Integer.MAX_VALUE, + "osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=org.apache.sling)" + }, + service = Filter.class) +@Designate(ocd=RequestParameterSupportFilter.Config.class) +public class RequestParameterSupportFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (request instanceof HttpServletRequest) { + log.info("Request: " + ((HttpServletRequest) request).getRequestURI()); + + chain.doFilter(ParameterSupport.getParameterSupportRequestWrapper((HttpServletRequest) request), response); + } + else { + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + + } + + @ObjectClassDefinition(name = "Apache Sling Request Parameter Handling", + description = "Configures Sling's request parameter handling.") + public @interface Config { + @AttributeDefinition( + name = "Default Parameter Encoding", + description = "The default request parameter encoding used to decode request " + + "parameters into strings. If this property is not set the default encoding " + + "is 'ISO-8859-1' as mandated by the Servlet API spec. This default encoding " + + "is used if the '_charset_' request parameter is not set to another " + + "(supported) character encoding. Applications being sure to always use the " + + "same encoding (e.g. UTF-8) can set this default here and may omit the " + + "'_charset_' request parameter") + String sling_default_parameter_encoding() default Util.ENCODING_DIRECT; + + @AttributeDefinition( + name = "Maximum POST Parameters", + description = "The maximum number of parameters supported. To prevent a DOS-style attack with an " + + "overrunning number of parameters the number of parameters supported can be limited. This " + + "includes all of the query string as well as application/x-www-form-urlencoded and " + + "multipart/form-data parameters. The default value is " + ParameterMap.DEFAULT_MAX_PARAMS + ".") + int sling_default_max_parameters() default ParameterMap.DEFAULT_MAX_PARAMS; + + @AttributeDefinition( + name = "Temporary File Location", + description = "The temporary directory where uploaded files are written to disk. The default is " + + "null, which means the directory given by the 'java.io.tmpdir' system property.") + String file_location(); + + @AttributeDefinition( + name = "File Save Threshold", + description = "The size threshold after which the file will be written to disk. The default is 256KB.") + int file_threshold() default 256000; + + @AttributeDefinition( + name = "Maximum File Size", + description = "The maximum size allowed for uploaded files. The default is -1, which means unlimited.") + long file_max() default -1; + + @AttributeDefinition( + name = "Maximum Request Size", + description = "The maximum size allowed for multipart/form-data requests. The default is -1, which means unlimited.") + long request_max() default -1; + + @AttributeDefinition( + name = "Check Additional Parameters", + description = "Enable this if you want to include request parameters added through the container, e.g through a valve.") + boolean sling_default_parameter_checkForAdditionalContainerParameters() default false; + + @AttributeDefinition( + name = "Path patterns", + description = "Requests with a path matching the pattern will get parameter support - default is null (i.e., none)" + ) + String[] osgi_http_whiteboard_filter_pattern(); + } + + static final String PID = "org.apache.sling.engine.parameters"; + + /** default log */ + private final Logger log = LoggerFactory.getLogger(PID); + + + + @Reference + private SlingSettingsService settignsService; + + @Activate + private void configure(final Config config) { + final String fixEncoding = config.sling_default_parameter_encoding(); + final int maxParams = config.sling_default_max_parameters(); + final long maxRequestSize = config.request_max(); + final String fileLocation = getFileLocation(config.file_location()); + final long maxFileSize = config.file_max(); + final int fileSizeThreshold = config.file_threshold(); + final boolean checkAddParameters = config.sling_default_parameter_checkForAdditionalContainerParameters(); + String[] pattern = config.osgi_http_whiteboard_filter_pattern(); + + if (log.isInfoEnabled()) { + log.info("Default Character Encoding: {}", fixEncoding); + log.info("Parameter Number Limit: {}", (maxParams < 0) ? "unlimited" : maxParams); + log.info("Maximum Request Size: {}", (maxParams < 0) ? "unlimited" : maxRequestSize); + log.info("Temporary File Location: {}", fileLocation); + log.info("Maximum File Size: {}", maxFileSize); + log.info("Tempory File Creation Threshold: {}", fileSizeThreshold); + log.info("Check for additional container parameters: {}", checkAddParameters); + log.info("Patterns: {}", pattern != null ? Arrays.asList(pattern) : null); + } + + Util.setDefaultFixEncoding(fixEncoding); + ParameterMap.setMaxParameters(maxParams); + ParameterSupport.configure(maxRequestSize, fileLocation, maxFileSize, + fileSizeThreshold, checkAddParameters, pattern); + } + + private String getFileLocation(String fileLocation) { + if (fileLocation != null) { + File file = new File(fileLocation); + if (!file.isAbsolute()) { + file = new File(this.settignsService.getSlingHomePath(), fileLocation); + fileLocation = file.getAbsolutePath(); + } + if (file.exists()) { + if (!file.isDirectory()) { + log.error( + "Configured temporary file location {} exists but is not a directory; using java.io.tmpdir instead", + fileLocation); + fileLocation = null; + } + } else { + if (!file.mkdirs()) { + log.error("Cannot create temporary file directory {}; using java.io.tmpdir instead", fileLocation); + fileLocation = null; + } + } + } + return fileLocation; + } +} Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingPart.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingPart.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingPart.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingPart.java Tue Sep 19 14:15:50 2017 @@ -18,14 +18,13 @@ */ package org.apache.sling.engine.impl.parameters; +import javax.servlet.http.Part; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; -import javax.servlet.http.Part; - public class SlingPart implements Part { private final MultipartRequestParameter param; Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingUnsupportedEncodingException.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingUnsupportedEncodingException.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingUnsupportedEncodingException.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/SlingUnsupportedEncodingException.java Tue Sep 19 14:15:50 2017 @@ -18,10 +18,10 @@ */ package org.apache.sling.engine.impl.parameters; -import java.io.UnsupportedEncodingException; - import org.apache.sling.api.SlingIOException; +import java.io.UnsupportedEncodingException; + public class SlingUnsupportedEncodingException extends SlingIOException { private static final long serialVersionUID = -4482276105859280247L; Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/Util.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/Util.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/Util.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/parameters/Util.java Tue Sep 19 14:15:50 2017 @@ -18,6 +18,8 @@ */ package org.apache.sling.engine.impl.parameters; +import org.apache.sling.api.request.RequestParameter; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -26,8 +28,6 @@ import java.io.UnsupportedEncodingExcept import java.util.LinkedHashMap; import java.util.Map; -import org.apache.sling.api.request.RequestParameter; - public class Util { // ISO-8859-1 mapps all characters 0..255 to \u0000..\u00ff directly Modified: sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java?rev=1808882&r1=1808880&r2=1808882&view=diff ============================================================================== --- sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java (original) +++ sling/whiteboard/pauls/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java Tue Sep 19 14:15:50 2017 @@ -55,7 +55,6 @@ import org.apache.sling.engine.impl.Slin import org.apache.sling.engine.impl.StaticResponseHeader; import org.apache.sling.engine.impl.adapter.SlingServletRequestAdapter; import org.apache.sling.engine.impl.adapter.SlingServletResponseAdapter; -import org.apache.sling.engine.impl.parameters.ParameterSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -140,9 +139,6 @@ public class RequestData { /** The original servlet Servlet Response object */ private SlingHttpServletResponse slingResponse; - /** The parameter support class */ - private ParameterSupport parameterSupport; - private ResourceResolver resourceResolver; private RequestProgressTracker requestProgressTracker; @@ -665,10 +661,6 @@ public class RequestData { // ---------- Parameter support ------------------------------------------- public ServletInputStream getInputStream() throws IOException { - if (parameterSupport != null && parameterSupport.requestDataUsed()) { - throw new IllegalStateException( - "Request Data has already been read"); - } // may throw IllegalStateException if the reader has already been // acquired @@ -677,24 +669,12 @@ public class RequestData { public BufferedReader getReader() throws UnsupportedEncodingException, IOException { - if (parameterSupport != null && parameterSupport.requestDataUsed()) { - throw new IllegalStateException( - "Request Data has already been read"); - } // may throw IllegalStateException if the input stream has already been // acquired return getServletRequest().getReader(); } - public ParameterSupport getParameterSupport() { - if (parameterSupport == null) { - parameterSupport = ParameterSupport.getInstance(getServletRequest()); - } - - return parameterSupport; - } - // SlingHttpServletRequest instance factory private static SlingHttpServletRequestFactory getSlingHttpServletRequestFactory() {