This is an automated email from the ASF dual-hosted git repository. ffang pushed a commit to branch camel-2.23.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-2.23.x by this push: new 9f91d2c [CAMEL-14105]avoid using deprecated org.eclipse.jetty.util.MultiPartInputStreamParser 9f91d2c is described below commit 9f91d2cc6dbae55af7193e1beeba0a146ea13368 Author: Freeman Fang <freeman.f...@gmail.com> AuthorDate: Wed Oct 23 11:36:40 2019 -0400 [CAMEL-14105]avoid using deprecated org.eclipse.jetty.util.MultiPartInputStreamParser (cherry picked from commit b71cf87b0d29db8d3ba265f443555e410456d27a) (cherry picked from commit 57e95a1b3aa742f64567a6618fba1b72bb32295d) --- .../camel/component/jetty/JettyHttpComponent.java | 14 ++++- .../camel/component/jetty/JettyHttpEndpoint.java | 4 +- .../camel/component/jetty/MultiPartFilter.java | 66 ++++++++++++++++++++++ .../src/main/docs/jetty-component.adoc | 2 +- .../component/jetty9/AttachmentHttpBinding.java | 18 ++++-- .../jetty/MultiPartFormWithCustomFilterTest.java | 2 +- 6 files changed, 96 insertions(+), 10 deletions(-) diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java index 0f47261..5f79c23 100644 --- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java +++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java @@ -32,6 +32,7 @@ import java.util.Locale; import java.util.Map; import javax.management.MBeanServer; import javax.servlet.Filter; +import javax.servlet.MultipartConfigElement; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -78,6 +79,8 @@ import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.MultiPartFormDataCompliance; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; @@ -90,7 +93,6 @@ import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlets.CrossOriginFilter; -import org.eclipse.jetty.servlets.MultiPartFilter; import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -1344,9 +1346,19 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements holder.setAsyncSupported(true); holder.setInitParameter(CamelServlet.ASYNC_PARAM, Boolean.toString(endpoint.isAsync())); context.addServlet(holder, "/*"); + + File file = File.createTempFile("camel", ""); + file.delete(); + + //must register the MultipartConfig to make jetty server multipart aware + holder.getRegistration().setMultipartConfig(new MultipartConfigElement(file.getParentFile().getAbsolutePath(), -1, -1, 0)); // use rest enabled resolver in case we use rest camelServlet.setServletResolveConsumerStrategy(new HttpRestServletResolveConsumerStrategy()); + + //must make RFC7578 as default to avoid using the deprecated MultiPartInputStreamParser + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(MultiPartFormDataCompliance.RFC7578); return camelServlet; } diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java index ac2a460..68344bb 100644 --- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java +++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java @@ -64,7 +64,7 @@ public abstract class JettyHttpEndpoint extends HttpCommonEndpoint { @UriParam(label = "consumer", description = "If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX support for more details.") private boolean enableJmx; - @UriParam(description = "Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled or not." + @UriParam(description = "Whether org.apache.camel.component.jetty.MultiPartFilter is enabled or not." + " You should set this value to false when bridging endpoints, to ensure multipart requests is proxied/bridged as well.") private boolean enableMultipartFilter; @UriParam(label = "consumer", defaultValue = "true", @@ -297,7 +297,7 @@ public abstract class JettyHttpEndpoint extends HttpCommonEndpoint { } /** - * Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled or not. + * Whether org.apache.camel.component.jetty.MultiPartFilter is enabled or not. * You should set this value to false when bridging endpoints, to ensure multipart requests is proxied/bridged as well. */ public void setEnableMultipartFilter(boolean enableMultipartFilter) { diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/MultiPartFilter.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/MultiPartFilter.java new file mode 100644 index 0000000..87f141d --- /dev/null +++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/MultiPartFilter.java @@ -0,0 +1,66 @@ +/** + * 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.camel.component.jetty; + +import java.io.IOException; + +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; + + +/** + * To enable handle attachments with Jetty 9 when this filter is set. + * <p/> + * To replace the deprecated org.eclipse.jetty.servlets.MultiPartFilter + * Tell AttachmentHttpBinding to use Servlet 3 HttpServletRequest.getParts API + */ +public class MultiPartFilter implements Filter { + + public static final String MULTIPART = "populate.multipart"; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest srequest = (HttpServletRequest)request; + if (srequest.getContentType() == null || !srequest.getContentType().startsWith("multipart/form-data")) { + chain.doFilter(request, response); + } else { + srequest.getParts(); //load and init attachments + request.setAttribute(MULTIPART, Boolean.TRUE); + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + + } + + + +} diff --git a/components/camel-jetty9/src/main/docs/jetty-component.adoc b/components/camel-jetty9/src/main/docs/jetty-component.adoc index 0c313f7..a404909 100644 --- a/components/camel-jetty9/src/main/docs/jetty-component.adoc +++ b/components/camel-jetty9/src/main/docs/jetty-component.adoc @@ -131,7 +131,7 @@ with the following path and query parameters: | Name | Description | Default | Type | *chunked* (common) | If this option is false the Servlet will disable the HTTP streaming and set the content-length header on the response | true | boolean | *disableStreamCache* (common) | Determines whether or not the raw input stream from Servlet is cached or not (Camel will read the stream into a in memory/overflow to file, Stream caching) cache. By default Camel will cache the Servlet input stream to support reading it multiple times to ensure it Camel can retrieve all data from the stream. However you can set this option to true when you for example need to access the raw stream, such as streaming it directly to a file or other persis [...] -| *enableMultipartFilter* (common) | Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled or not. You should set this value to false when bridging endpoints, to ensure multipart requests is proxied/bridged as well. | false | boolean +| *enableMultipartFilter* (common) | Whether org.apache.camel.component.jetty.MultiPartFilter is enabled or not. You should set this value to false when bridging endpoints, to ensure multipart requests is proxied/bridged as well. | false | boolean | *headerFilterStrategy* (common) | To use a custom HeaderFilterStrategy to filter header to and from Camel message. | | HeaderFilterStrategy | *transferException* (common) | If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application/x-java-serialized-object content type. On the producer side the exception will be deserialized and thrown as is, instead of the HttpOperationFailedException. The caused exception is required to be serialized. This is by default turned off. If you enable this then be aware that Java will deserialize the in [...] | *httpBinding* (common) | To use a custom HttpBinding to control the mapping between Camel message and HttpClient. | | HttpBinding diff --git a/components/camel-jetty9/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java b/components/camel-jetty9/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java index b72f0c6..10a654b 100644 --- a/components/camel-jetty9/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java +++ b/components/camel-jetty9/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java @@ -31,11 +31,11 @@ import javax.servlet.http.Part; import org.apache.camel.Attachment; import org.apache.camel.Exchange; import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.jetty.MultiPartFilter; import org.apache.camel.http.common.DefaultHttpBinding; import org.apache.camel.http.common.HttpHelper; import org.apache.camel.http.common.HttpMessage; import org.apache.camel.impl.DefaultAttachment; -import org.eclipse.jetty.util.MultiPartInputStreamParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,12 +52,11 @@ final class AttachmentHttpBinding extends DefaultHttpBinding { @Override protected void populateAttachments(HttpServletRequest request, HttpMessage message) { - Object object = request.getAttribute("org.eclipse.jetty.servlet.MultiPartFile.multiPartInputStream"); - if (object instanceof MultiPartInputStreamParser) { - MultiPartInputStreamParser parser = (MultiPartInputStreamParser)object; + Boolean object = (Boolean)request.getAttribute(MultiPartFilter.MULTIPART); + if (object != null && object) { Collection<Part> parts; try { - parts = parser.getParts(); + parts = request.getParts(); for (Part part : parts) { DataSource ds = new PartDataSource(part); Attachment attachment = new DefaultAttachment(ds); @@ -67,6 +66,15 @@ final class AttachmentHttpBinding extends DefaultHttpBinding { } } message.addAttachmentObject(part.getName(), attachment); + String name = part.getSubmittedFileName(); + Object value = message.getAttachment(name); + Map<String, Object> headers = message.getHeaders(); + if (getHeaderFilterStrategy() != null + && !getHeaderFilterStrategy().applyFilterToExternalHeaders(name, value, message.getExchange()) + && name != null) { + HttpHelper.appendHeader(headers, name, value); + } + } } catch (Exception e) { throw new RuntimeCamelException("Cannot populate attachments", e); diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java index aeae20a..bb11f4b 100644 --- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java +++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java @@ -37,7 +37,7 @@ import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; -import org.eclipse.jetty.servlets.MultiPartFilter; + import org.junit.Test; public class MultiPartFormWithCustomFilterTest extends BaseJettyTest {