diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportFactory.java b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportFactory.java index 02ecf77180..4b53c3151c 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportFactory.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportFactory.java @@ -48,9 +48,11 @@ public class HttpTransportFactory extends TransportFactory { Map jettyOptions = IntrospectionSupport.extractProperties(options, "jetty."); Map httpOptions = IntrospectionSupport.extractProperties(options, "http."); Map transportOptions = IntrospectionSupport.extractProperties(options, "transport."); + Map wireFormatOptions = IntrospectionSupport.extractProperties(options, "wireFormat."); result.setJettyOptions(jettyOptions); result.setTransportOption(transportOptions); result.setHttpOptions(httpOptions); + result.setWireFormatOptions(wireFormatOptions); return result; } catch (URISyntaxException e) { throw IOExceptionSupport.create(e); diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java index ca3bed806a..370742951a 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java @@ -18,6 +18,7 @@ package org.apache.activemq.transport.http; import java.net.InetSocketAddress; import java.net.URI; +import java.util.HashMap; import java.util.Map; import org.apache.activemq.command.BrokerInfo; @@ -38,6 +39,7 @@ public class HttpTransportServer extends WebTransportServerSupport { private TextWireFormat wireFormat; private final HttpTransportFactory transportFactory; + private Map wireFormatOptions = new HashMap<>(); public HttpTransportServer(URI uri, HttpTransportFactory factory) { super(uri); @@ -93,6 +95,7 @@ public class HttpTransportServer extends WebTransportServerSupport { contextHandler.setAttribute("wireFormat", getWireFormat()); contextHandler.setAttribute("transportFactory", transportFactory); contextHandler.setAttribute("transportOptions", transportOptions); + contextHandler.setAttribute("wireFormatOptions", wireFormatOptions); //AMQ-6182 - disabling trace by default configureTraceMethod((ConstraintSecurityHandler) contextHandler.getSecurityHandler(), @@ -171,6 +174,10 @@ public class HttpTransportServer extends WebTransportServerSupport { super.setTransportOption(transportOptions); } + public void setWireFormatOptions(Map wireFormatOptions) { + this.wireFormatOptions = wireFormatOptions; + } + @Override public boolean isSslServer() { return false; diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTunnelServlet.java b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTunnelServlet.java index e6dc7c9d0e..c061958871 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTunnelServlet.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTunnelServlet.java @@ -60,6 +60,7 @@ public class HttpTunnelServlet extends HttpServlet { private ConcurrentMap clients = new ConcurrentHashMap(); private final long requestTimeout = 30000L; private HashMap transportOptions; + private HashMap wireFormatOptions; @SuppressWarnings("unchecked") @Override @@ -74,6 +75,7 @@ public class HttpTunnelServlet extends HttpServlet { throw new ServletException("No such attribute 'transportFactory' available in the ServletContext"); } transportOptions = (HashMap)getServletContext().getAttribute("transportOptions"); + wireFormatOptions = (HashMap)getServletContext().getAttribute("wireFormatOptions"); wireFormat = (TextWireFormat)getServletContext().getAttribute("wireFormat"); if (wireFormat == null) { wireFormat = createWireFormat(); @@ -118,6 +120,10 @@ public class HttpTunnelServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (wireFormatOptions.get("maxFrameSize") != null && request.getContentLength() > Integer.parseInt(wireFormatOptions.get("maxFrameSize").toString())) { + throw new ServletException("maxFrameSize exceeded"); + } + InputStream stream = request.getInputStream(); String contentType = request.getContentType(); if (contentType != null && contentType.equals("application/x-gzip")) { diff --git a/activemq-http/src/test/java/org/apache/activemq/transport/http/HttpMaxFrameSizeTest.java b/activemq-http/src/test/java/org/apache/activemq/transport/http/HttpMaxFrameSizeTest.java new file mode 100644 index 0000000000..2befaf66e1 --- /dev/null +++ b/activemq-http/src/test/java/org/apache/activemq/transport/http/HttpMaxFrameSizeTest.java @@ -0,0 +1,64 @@ +/** + * 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.activemq.transport.http; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.command.ActiveMQQueue; +import org.apache.commons.lang.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +public class HttpMaxFrameSizeTest { + + protected BrokerService brokerService; + + @Before + public void setup() throws Exception { + brokerService = new BrokerService(); + brokerService.setPersistent(false); + brokerService.setUseJmx(false); + brokerService.deleteAllMessages(); + brokerService.addConnector("http://localhost:8888?wireFormat.maxFrameSize=10"); + brokerService.start(); + brokerService.waitUntilStarted(); + } + + @After + public void teardown() throws Exception { + brokerService.stop(); + } + + @Test(expected = JMSException.class) + public void sendTest() throws Exception { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("http://localhost:8888"); + Connection connection = connectionFactory.createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = session.createProducer(new ActiveMQQueue("test")); + String payload = StringUtils.repeat("*", 2000); + TextMessage textMessage = session.createTextMessage(payload); + producer.send(textMessage); + } + +}