This is an automated email from the ASF dual-hosted git repository. ffang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new abb5c41 [CAMEL-14105]avoid using deprecated org.eclipse.jetty.util.MultiPartInputStreamParser abb5c41 is described below commit abb5c41802bc51d0641875989215387136b6e110 Author: Freeman Fang <freeman.f...@gmail.com> AuthorDate: Wed Oct 23 11:20:47 2019 -0400 [CAMEL-14105]avoid using deprecated org.eclipse.jetty.util.MultiPartInputStreamParser --- .../camel/component/jetty/JettyHttpComponent.java | 14 ++++- .../camel/component/jetty/JettyHttpEndpoint.java | 4 +- .../camel/component/jetty/MultiPartFilter.java | 66 ++++++++++++++++++++++ .../camel-jetty/src/main/docs/jetty-component.adoc | 2 +- .../component/jetty9/AttachmentHttpBinding.java | 18 ++++-- .../jetty/MultiPartFormWithCustomFilterTest.java | 2 +- .../dsl/JettyHttpEndpointBuilder9Factory.java | 4 +- 7 files changed, 98 insertions(+), 12 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 bf892aa..22c2c85 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; @@ -73,6 +74,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; @@ -85,7 +88,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; @@ -1250,9 +1252,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 c7f5f01..9036de4 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 @@ -38,7 +38,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", @@ -166,7 +166,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..64c181f --- /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-jetty/src/main/docs/jetty-component.adoc b/components/camel-jetty/src/main/docs/jetty-component.adoc index 3a380e9..30fea60 100644 --- a/components/camel-jetty/src/main/docs/jetty-component.adoc +++ b/components/camel-jetty/src/main/docs/jetty-component.adoc @@ -134,7 +134,7 @@ with the following path and query parameters: | *continuationTimeout* (consumer) | Allows to set a timeout in millis when using Jetty as consumer (server). By default Jetty uses 30000. You can use a value of = 0 to never expire. If a timeout occurs then the request will be expired and Jetty will return back a http error 503 to the client. This option is only in use when using Jetty with the Asynchronous Routing Engine. | 30000 | Long | *enableCORS* (consumer) | If the option is true, Jetty server will setup the CrossOriginFilter which supports the CORS out of box. | false | boolean | *enableJmx* (consumer) | If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX support for more details. | false | boolean -| *enableMultipartFilter* (consumer) | 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* (consumer) | 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 | *httpMethodRestrict* (consumer) | Used to only allow consuming if the HttpMethod matches, such as GET/POST/PUT etc. Multiple methods can be specified separated by comma. | | String | *matchOnUriPrefix* (consumer) | Whether or not the consumer should try to find a target consumer by matching the URI prefix if no exact match is found. | false | boolean | *muteException* (consumer) | If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace. | false | boolean diff --git a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java index 36bacdf..f65e4c5 100644 --- a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java +++ b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty9/AttachmentHttpBinding.java @@ -33,10 +33,10 @@ import org.apache.camel.RuntimeCamelException; import org.apache.camel.attachment.Attachment; import org.apache.camel.attachment.AttachmentMessage; import org.apache.camel.attachment.DefaultAttachment; +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.eclipse.jetty.util.MultiPartInputStreamParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,12 +53,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); @@ -69,6 +68,15 @@ final class AttachmentHttpBinding extends DefaultHttpBinding { } AttachmentMessage am = message.getExchange().getMessage(AttachmentMessage.class); am.addAttachmentObject(part.getName(), attachment); + String name = part.getSubmittedFileName(); + Object value = am.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-jetty/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java index d050b11..806ef46 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/MultiPartFormWithCustomFilterTest.java +++ b/components/camel-jetty/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 { diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/JettyHttpEndpointBuilder9Factory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/JettyHttpEndpointBuilder9Factory.java index af7ac26..071f459 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/JettyHttpEndpointBuilder9Factory.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/JettyHttpEndpointBuilder9Factory.java @@ -148,7 +148,7 @@ public interface JettyHttpEndpointBuilder9Factory { return this; } /** - * Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled + * 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. * @@ -162,7 +162,7 @@ public interface JettyHttpEndpointBuilder9Factory { return this; } /** - * Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled + * 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. *