diff options
author | Morten Tokle <mortent@verizonmedia.com> | 2021-04-21 13:36:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-21 13:36:54 +0200 |
commit | 1ceda20ba0f1ca59b0c629a793b933a8ddb47895 (patch) | |
tree | 50163f22fe648bfd7aadcef90b47fc95a072d57b | |
parent | bfe3c862c433371248b160154d406939b6912355 (diff) | |
parent | f36017d3f2709e2fa3e555269a4116482129ee2e (diff) |
Merge pull request #17512 from vespa-engine/mortent/filtering-spec-delegate
Get request handler spec through delegate
9 files changed, 137 insertions, 10 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java index 842ab75a312..5b628d73ab8 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLoggingRequestHandler.java @@ -6,6 +6,7 @@ import com.yahoo.container.logging.AccessLogEntry; import com.yahoo.jdisc.Request; import com.yahoo.jdisc.handler.AbstractRequestHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.HttpRequest; @@ -23,7 +24,7 @@ import java.util.Optional; * * @author bakksjo */ -public class AccessLoggingRequestHandler extends AbstractRequestHandler { +public class AccessLoggingRequestHandler extends AbstractRequestHandler implements DelegatedRequestHandler { public static final String CONTEXT_KEY_ACCESS_LOG_ENTRY = AccessLoggingRequestHandler.class.getName() + "_access-log-entry"; @@ -56,4 +57,8 @@ public class AccessLoggingRequestHandler extends AbstractRequestHandler { } + @Override + public RequestHandler getDelegate() { + return delegate; + } } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java index 27d122bcaa2..43acbb9b096 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java @@ -10,6 +10,7 @@ import com.yahoo.jdisc.handler.AbstractRequestHandler; import com.yahoo.jdisc.handler.BindingNotFoundException; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.RequestDeniedException; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; @@ -19,6 +20,7 @@ import com.yahoo.jdisc.http.filter.ResponseFilter; import java.nio.ByteBuffer; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -67,10 +69,8 @@ class FilteringRequestHandler extends AbstractRequestHandler { throw new BindingNotFoundException(request.getUri()); } - if (resolvedRequestHandler instanceof HttpRequestHandler) { - RequestHandlerSpec requestHandlerSpec = ((HttpRequestHandler) resolvedRequestHandler).requestHandlerSpec(); - request.context().put(RequestHandlerSpec.ATTRIBUTE_NAME, requestHandlerSpec); - } + getRequestHandlerSpec(resolvedRequestHandler) + .ifPresent(requestHandlerSpec -> request.context().put(RequestHandlerSpec.ATTRIBUTE_NAME, requestHandlerSpec)); RequestHandler requestHandler = new ReferenceCountingRequestHandler(resolvedRequestHandler); @@ -96,6 +96,18 @@ class FilteringRequestHandler extends AbstractRequestHandler { return contentChannel; } + private Optional<RequestHandlerSpec> getRequestHandlerSpec(RequestHandler resolvedRequestHandler) { + RequestHandler delegate = resolvedRequestHandler; + if (delegate instanceof DelegatedRequestHandler) { + delegate = ((DelegatedRequestHandler) delegate).getDelegateRecursive(); + } + if(delegate instanceof HttpRequestHandler) { + return Optional.ofNullable(((HttpRequestHandler) delegate).requestHandlerSpec()); + } else { + return Optional.empty(); + } + } + private static class FilteringResponseHandler implements ResponseHandler { private final ResponseHandler delegate; diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FormPostRequestHandler.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FormPostRequestHandler.java index 38f84438526..57fb32f89f0 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FormPostRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FormPostRequestHandler.java @@ -7,6 +7,7 @@ import com.yahoo.jdisc.ResourceReference; import com.yahoo.jdisc.handler.AbstractRequestHandler; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.HttpRequest; @@ -38,7 +39,7 @@ import static com.yahoo.jdisc.http.server.jetty.CompletionHandlerUtils.NOOP_COMP * @author bakksjo * $Id$ */ -class FormPostRequestHandler extends AbstractRequestHandler implements ContentChannel { +class FormPostRequestHandler extends AbstractRequestHandler implements ContentChannel, DelegatedRequestHandler { private final ByteArrayOutputStream accumulatedRequestContent = new ByteArrayOutputStream(); private final RequestHandler delegateHandler; @@ -185,4 +186,9 @@ class FormPostRequestHandler extends AbstractRequestHandler implements ContentCh } } } + + @Override + public RequestHandler getDelegate() { + return delegateHandler; + } } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ReferenceCountingRequestHandler.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ReferenceCountingRequestHandler.java index f2bf5b56d5c..71cca62ce9c 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ReferenceCountingRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ReferenceCountingRequestHandler.java @@ -7,6 +7,7 @@ import com.yahoo.jdisc.Response; import com.yahoo.jdisc.SharedResource; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.NullContent; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; @@ -26,7 +27,7 @@ import java.util.logging.Logger; * @author bakksjo */ @SuppressWarnings("try") -class ReferenceCountingRequestHandler implements RequestHandler { +class ReferenceCountingRequestHandler implements DelegatedRequestHandler { private static final Logger log = Logger.getLogger(ReferenceCountingRequestHandler.class.getName()); @@ -79,6 +80,11 @@ class ReferenceCountingRequestHandler implements RequestHandler { return delegate.toString(); } + @Override + public RequestHandler getDelegate() { + return delegate; + } + private static class ReferenceCountingResponseHandler implements ResponseHandler { final SharedResource request; diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java index e117ef7f723..01337dcc65d 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java @@ -3,6 +3,8 @@ package com.yahoo.jdisc.http.server.jetty; import com.google.inject.AbstractModule; import com.google.inject.util.Modules; +import com.yahoo.container.jdisc.HttpRequestHandler; +import com.yahoo.container.jdisc.RequestHandlerSpec; import com.yahoo.container.logging.ConnectionLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.jdisc.AbstractResource; @@ -12,6 +14,8 @@ import com.yahoo.jdisc.Response; import com.yahoo.jdisc.handler.AbstractRequestHandler; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; +import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseDispatch; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.ConnectorConfig; @@ -25,6 +29,8 @@ import com.yahoo.jdisc.http.filter.ResponseHeaderFilter; import com.yahoo.jdisc.http.filter.chain.RequestFilterChain; import com.yahoo.jdisc.http.filter.chain.ResponseFilterChain; import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; +import org.assertj.core.api.Assertions; +import org.bouncycastle.cert.ocsp.Req; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -530,6 +536,36 @@ public class FilterTestCase { assertThat(testDriver.close(), is(true)); } + @Test + public void requireThatRequestHandlerSpecIsAvailableThroughDelegate() throws IOException, InterruptedException { + MyRequestHandler requestHandler = new MyHttpRequestHandler(); + MyDelegatedHandler delegateHandler1 = new MyDelegatedHandler(requestHandler); + MyDelegatedHandler delegateHandler2 = new MyDelegatedHandler(delegateHandler1); + requestHandlerSpecTest(delegateHandler2); + } + + @Test + public void requireThatRequestHandlerSpecIsAvailable() throws IOException, InterruptedException { + MyRequestHandler requestHandler = new MyHttpRequestHandler(); + requestHandlerSpecTest(requestHandler); + } + + private void requestHandlerSpecTest(MyRequestHandler requestHandler) throws IOException, InterruptedException { + RequestFilter filter = mock(RequestFilter.class); + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", filter) + .addRequestFilterBinding("my-request-filter", "http://*/filtered/*") + .build(); + + TestDriver testDriver = newDriver(requestHandler, filterBindings, new MetricConsumerMock(), true); + + testDriver.client().get("/filtered/") + .expectStatusCode(is(Response.Status.OK)); + ArgumentCaptor<HttpRequest> requestArgumentCaptor = ArgumentCaptor.forClass(HttpRequest.class); + verify(filter).filter(requestArgumentCaptor.capture(), any(ResponseHandler.class)); + Assertions.assertThat(requestArgumentCaptor.getValue().context()).containsKey(RequestHandlerSpec.ATTRIBUTE_NAME); + } + private static TestDriver newDriver(MyRequestHandler requestHandler, FilterBindings filterBindings) { return newDriver(requestHandler, filterBindings, new MetricConsumerMock(), false); } @@ -664,4 +700,33 @@ public class FilterTestCase { channel.close(null); } } + + private static class MyDelegatedHandler extends MyRequestHandler implements DelegatedRequestHandler { + + private final RequestHandler delegate; + + public MyDelegatedHandler(RequestHandler delegate) { + this.delegate = delegate; + } + + @Override + public RequestHandler getDelegate() { + return delegate; + } + @Override + public ContentChannel handleRequest(Request request, ResponseHandler handler) { + return delegate.handleRequest(request, handler); + } + @Override + public void handleTimeout(Request request, ResponseHandler handler) { + delegate.handleTimeout(request, handler); + } + } + + private static class MyHttpRequestHandler extends MyRequestHandler implements HttpRequestHandler { + @Override + public RequestHandlerSpec requestHandlerSpec() { + return RequestHandlerSpec.DEFAULT_INSTANCE; + } + } } diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/ProxyRequestHandler.java b/jdisc_core/src/main/java/com/yahoo/jdisc/ProxyRequestHandler.java index f3fa6740fbd..6e385535e40 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/ProxyRequestHandler.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/ProxyRequestHandler.java @@ -3,6 +3,7 @@ package com.yahoo.jdisc; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.NullContent; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; @@ -16,7 +17,7 @@ import java.util.logging.Logger; /** * @author bakksjo */ -class ProxyRequestHandler implements RequestHandler { +class ProxyRequestHandler implements DelegatedRequestHandler { private static final CompletionHandler IGNORED_COMPLETION = new IgnoredCompletion(); private static final Logger log = Logger.getLogger(ProxyRequestHandler.class.getName()); @@ -71,6 +72,11 @@ class ProxyRequestHandler implements RequestHandler { return delegate.toString(); } + @Override + public RequestHandler getDelegate() { + return delegate; + } + private static class ProxyResponseHandler implements ResponseHandler { final SharedResource request; diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerSnapshot.java b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerSnapshot.java index 1a3f7068024..7b72e95ac09 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerSnapshot.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerSnapshot.java @@ -9,6 +9,7 @@ import com.yahoo.jdisc.ResourceReference; import com.yahoo.jdisc.application.BindingMatch; import com.yahoo.jdisc.application.BindingSet; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.NullContent; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; @@ -71,7 +72,7 @@ class ContainerSnapshot extends AbstractResource implements Container { return timeoutMgr.timer().currentTimeMillis(); } - private static class NullContentRequestHandler implements RequestHandler { + private static class NullContentRequestHandler implements DelegatedRequestHandler { final RequestHandler delegate; @@ -108,5 +109,10 @@ class ContainerSnapshot extends AbstractResource implements Container { public String toString() { return delegate.toString(); } + + @Override + public RequestHandler getDelegate() { + return delegate; + } } } diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/core/TimeoutManagerImpl.java b/jdisc_core/src/main/java/com/yahoo/jdisc/core/TimeoutManagerImpl.java index 43cddaea803..a6d6e32df06 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/core/TimeoutManagerImpl.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/core/TimeoutManagerImpl.java @@ -9,6 +9,7 @@ import com.yahoo.jdisc.TimeoutManager; import com.yahoo.jdisc.Timer; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.DelegatedRequestHandler; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; @@ -106,7 +107,7 @@ public class TimeoutManagerImpl { } } - private class ManagedRequestHandler implements RequestHandler { + private class ManagedRequestHandler implements DelegatedRequestHandler { final RequestHandler delegate; @@ -152,6 +153,11 @@ public class TimeoutManagerImpl { public String toString() { return delegate.toString(); } + + @Override + public RequestHandler getDelegate() { + return delegate; + } } private class TimeoutHandler implements ResponseHandler, TimeoutManager { diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/DelegatedRequestHandler.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/DelegatedRequestHandler.java new file mode 100644 index 00000000000..540fe03accf --- /dev/null +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/DelegatedRequestHandler.java @@ -0,0 +1,15 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package com.yahoo.jdisc.handler; + +public interface DelegatedRequestHandler extends RequestHandler { + RequestHandler getDelegate(); + + default RequestHandler getDelegateRecursive() { + RequestHandler delegate = getDelegate(); + while(delegate instanceof DelegatedRequestHandler) { + delegate = ((DelegatedRequestHandler) delegate).getDelegate(); + } + return delegate; + } +} |