Updated Branches: refs/heads/flume-1.5 251478f2e -> ffa9fae30
FLUME-2312. Add utility for adorning HTTP contexts in Jetty (Hari Shreedharan via Jarek Jarcec Cecho) Project: http://git-wip-us.apache.org/repos/asf/flume/repo Commit: http://git-wip-us.apache.org/repos/asf/flume/commit/ffa9fae3 Tree: http://git-wip-us.apache.org/repos/asf/flume/tree/ffa9fae3 Diff: http://git-wip-us.apache.org/repos/asf/flume/diff/ffa9fae3 Branch: refs/heads/flume-1.5 Commit: ffa9fae3045908b304dbe13dfa5526b40e667ae4 Parents: 251478f Author: Jarek Jarcec Cecho <[email protected]> Authored: Wed Feb 5 18:02:12 2014 -0800 Committer: Jarek Jarcec Cecho <[email protected]> Committed: Wed Feb 5 18:08:59 2014 -0800 ---------------------------------------------------------------------- .../instrumentation/http/HTTPMetricsServer.java | 7 +++ .../apache/flume/source/http/HTTPSource.java | 2 + .../flume/tools/HTTPServerConstraintUtil.java | 62 ++++++++++++++++++++ .../http/TestHTTPMetricsServer.java | 31 ++++++++++ .../flume/source/http/TestHTTPSource.java | 20 +++++++ 5 files changed, 122 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flume/blob/ffa9fae3/flume-ng-core/src/main/java/org/apache/flume/instrumentation/http/HTTPMetricsServer.java ---------------------------------------------------------------------- diff --git a/flume-ng-core/src/main/java/org/apache/flume/instrumentation/http/HTTPMetricsServer.java b/flume-ng-core/src/main/java/org/apache/flume/instrumentation/http/HTTPMetricsServer.java index 2c2c6f3..7c0afb0 100644 --- a/flume-ng-core/src/main/java/org/apache/flume/instrumentation/http/HTTPMetricsServer.java +++ b/flume-ng-core/src/main/java/org/apache/flume/instrumentation/http/HTTPMetricsServer.java @@ -108,6 +108,13 @@ public class HTTPMetricsServer implements MonitorService { //If we want to use any other url for something else, we should make sure //that for metrics only /metrics is used to prevent backward //compatibility issues. + if(request.getMethod().equalsIgnoreCase("TRACE") || request.getMethod() + .equalsIgnoreCase("OPTIONS")) { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + response.flushBuffer(); + ((Request) request).setHandled(true); + return; + } if (target.equals("/")) { response.setContentType("text/html;charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); http://git-wip-us.apache.org/repos/asf/flume/blob/ffa9fae3/flume-ng-core/src/main/java/org/apache/flume/source/http/HTTPSource.java ---------------------------------------------------------------------- diff --git a/flume-ng-core/src/main/java/org/apache/flume/source/http/HTTPSource.java b/flume-ng-core/src/main/java/org/apache/flume/source/http/HTTPSource.java index 48c6492..115b34f 100644 --- a/flume-ng-core/src/main/java/org/apache/flume/source/http/HTTPSource.java +++ b/flume-ng-core/src/main/java/org/apache/flume/source/http/HTTPSource.java @@ -26,6 +26,7 @@ import org.apache.flume.EventDrivenSource; import org.apache.flume.conf.Configurable; import org.apache.flume.instrumentation.SourceCounter; import org.apache.flume.source.AbstractSource; +import org.apache.flume.tools.HTTPServerConstraintUtil; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Server; import org.mortbay.jetty.nio.SelectChannelConnector; @@ -190,6 +191,7 @@ public class HTTPSource extends AbstractSource implements new org.mortbay.jetty.servlet.Context( srv, "/", org.mortbay.jetty.servlet.Context.SESSIONS); root.addServlet(new ServletHolder(new FlumeHTTPServlet()), "/"); + HTTPServerConstraintUtil.enforceConstraints(root); srv.start(); Preconditions.checkArgument(srv.getHandler().equals(root)); } catch (Exception ex) { http://git-wip-us.apache.org/repos/asf/flume/blob/ffa9fae3/flume-ng-core/src/main/java/org/apache/flume/tools/HTTPServerConstraintUtil.java ---------------------------------------------------------------------- diff --git a/flume-ng-core/src/main/java/org/apache/flume/tools/HTTPServerConstraintUtil.java b/flume-ng-core/src/main/java/org/apache/flume/tools/HTTPServerConstraintUtil.java new file mode 100644 index 0000000..479cfc4 --- /dev/null +++ b/flume-ng-core/src/main/java/org/apache/flume/tools/HTTPServerConstraintUtil.java @@ -0,0 +1,62 @@ +/* + * 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.flume.tools; + +import org.mortbay.jetty.security.Constraint; +import org.mortbay.jetty.security.ConstraintMapping; +import org.mortbay.jetty.security.SecurityHandler; +import org.mortbay.jetty.servlet.Context; + +// Most of the code in this class is copied from HBASE-10473 + +/** + * Utility class to impose constraints on Jetty HTTP servers + */ + +public class HTTPServerConstraintUtil { + + private HTTPServerConstraintUtil() { + + } + + /** + * Impose constraints on the {@linkplain org.mortbay.jetty.servlet.Context} + * passed in. + * @param ctx - {@linkplain org.mortbay.jetty.servlet.Context} to impose + * constraints on. + */ + public static void enforceConstraints(Context ctx) { + Constraint c = new Constraint(); + c.setAuthenticate(true); + + ConstraintMapping cmt = new ConstraintMapping(); + cmt.setConstraint(c); + cmt.setMethod("TRACE"); + cmt.setPathSpec("/*"); + + ConstraintMapping cmo = new ConstraintMapping(); + cmo.setConstraint(c); + cmo.setMethod("OPTIONS"); + cmo.setPathSpec("/*"); + + SecurityHandler sh = new SecurityHandler(); + sh.setConstraintMappings(new ConstraintMapping[]{cmt, cmo}); + ctx.addHandler(sh); + } +} http://git-wip-us.apache.org/repos/asf/flume/blob/ffa9fae3/flume-ng-core/src/test/java/org/apache/flume/instrumentation/http/TestHTTPMetricsServer.java ---------------------------------------------------------------------- diff --git a/flume-ng-core/src/test/java/org/apache/flume/instrumentation/http/TestHTTPMetricsServer.java b/flume-ng-core/src/test/java/org/apache/flume/instrumentation/http/TestHTTPMetricsServer.java index a2a1c30..eb2d02d 100644 --- a/flume-ng-core/src/test/java/org/apache/flume/instrumentation/http/TestHTTPMetricsServer.java +++ b/flume-ng-core/src/test/java/org/apache/flume/instrumentation/http/TestHTTPMetricsServer.java @@ -38,6 +38,8 @@ import org.apache.flume.instrumentation.util.JMXTestUtils; import org.junit.Assert; import org.junit.Test; +import javax.servlet.http.HttpServletResponse; + /** * */ @@ -127,4 +129,33 @@ public class TestHTTPMetricsServer { srv.stop(); System.out.println(String.valueOf(port) + "test success!"); } + + @Test + public void testTrace() throws Exception { + doTestForbiddenMethods(4543,"TRACE"); + } + @Test + public void testOptions() throws Exception { + doTestForbiddenMethods(4432,"OPTIONS"); + } + + public void doTestForbiddenMethods(int port, String method) + throws Exception { + MonitorService srv = new HTTPMetricsServer(); + Context context = new Context(); + if (port > 1024) { + context.put(HTTPMetricsServer.CONFIG_PORT, String.valueOf(port)); + } else { + port = HTTPMetricsServer.DEFAULT_PORT; + } + srv.configure(context); + srv.start(); + Thread.sleep(1000); + URL url = new URL("http://0.0.0.0:" + String.valueOf(port) + "/metrics"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod(method); + Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, + conn.getResponseCode()); + srv.stop(); + } } http://git-wip-us.apache.org/repos/asf/flume/blob/ffa9fae3/flume-ng-core/src/test/java/org/apache/flume/source/http/TestHTTPSource.java ---------------------------------------------------------------------- diff --git a/flume-ng-core/src/test/java/org/apache/flume/source/http/TestHTTPSource.java b/flume-ng-core/src/test/java/org/apache/flume/source/http/TestHTTPSource.java index ab8ec09..5b07a6e 100644 --- a/flume-ng-core/src/test/java/org/apache/flume/source/http/TestHTTPSource.java +++ b/flume-ng-core/src/test/java/org/apache/flume/source/http/TestHTTPSource.java @@ -29,7 +29,10 @@ import org.apache.flume.channel.ReplicatingChannelSelector; import org.apache.flume.conf.Configurables; import org.apache.flume.event.JSONEvent; import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.methods.HttpTrace; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; @@ -166,6 +169,23 @@ public class TestHTTPSource { } @Test + public void testTrace() throws Exception { + doTestForbidden(new HttpTrace("http://0.0.0.0:" + selectedPort)); + } + + @Test + public void testOptions() throws Exception { + doTestForbidden(new HttpOptions("http://0.0.0.0:" + selectedPort)); + } + + + private void doTestForbidden(HttpRequestBase request) throws Exception { + HttpResponse response = httpClient.execute(request); + Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatusLine().getStatusCode()); + } + + @Test public void testSimpleUTF16() throws IOException, InterruptedException { StringEntity input = new StringEntity("[{\"headers\":{\"a\": \"b\"},\"body\": \"random_body\"},"
