diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-02 12:05:02 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-02 14:48:42 +0100 |
commit | 61860fd6420a164a75a68e2f643cb30816f7b11d (patch) | |
tree | a8e6a5a857a79ff862e40e1e6d3fb4e754265c2a /container-core/src/main/java/com/yahoo/jdisc | |
parent | 6b5c9652df7bc095bede29f2ba415abfdbdbcd05 (diff) |
Remove Servlet integration from container-core
Diffstat (limited to 'container-core/src/main/java/com/yahoo/jdisc')
29 files changed, 31 insertions, 1699 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/HttpRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/HttpRequest.java index 387290065c9..598a924b327 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/HttpRequest.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/HttpRequest.java @@ -7,7 +7,6 @@ import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpRequest; import com.yahoo.jdisc.service.CurrentContainer; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.util.MultiMap; @@ -31,7 +30,7 @@ import java.util.concurrent.TimeUnit; * @author Anirudha Khanna * @author Einar M R Rosenvinge */ -public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { +public class HttpRequest extends Request { public enum Method { OPTIONS, @@ -141,7 +140,6 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { } /** Returns the remote address, or null if unresolved */ - @Override public String getRemoteHostAddress() { if (remoteAddress instanceof InetSocketAddress) { InetAddress remoteInetAddress = ((InetSocketAddress) remoteAddress).getAddress(); @@ -154,7 +152,6 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { } } - @Override public String getRemoteHostName() { if (remoteAddress instanceof InetSocketAddress) { InetAddress remoteInetAddress = ((InetSocketAddress) remoteAddress).getAddress(); @@ -166,7 +163,6 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { } } - @Override public int getRemotePort() { if (remoteAddress instanceof InetSocketAddress) return ((InetSocketAddress) remoteAddress).getPort(); @@ -202,7 +198,6 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { * @param unit the unit to return the time in * @return the timestamp of when the underlying HTTP channel was connected, or request creation time */ - @Override public long getConnectedAt(TimeUnit unit) { return unit.convert(connectedAt, TimeUnit.MILLISECONDS); } @@ -234,7 +229,6 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { return parameters; } - @Override public void copyHeaders(HeaderFields target) { target.addAll(headers()); } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java index e9ff60ade20..20abb251c74 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java @@ -7,7 +7,6 @@ import com.yahoo.jdisc.Response; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpResponse; import java.util.List; @@ -16,7 +15,7 @@ import java.util.List; * * @author Einar M R Rosenvinge */ -public class HttpResponse extends Response implements ServletOrJdiscHttpResponse { +public class HttpResponse extends Response { private final HeaderFields trailers = new HeaderFields(); private boolean chunkedEncodingEnabled = true; @@ -54,12 +53,10 @@ public class HttpResponse extends Response implements ServletOrJdiscHttpResponse return message; } - @Override public void copyHeaders(HeaderFields target) { target.addAll(headers()); } - @Override public List<Cookie> decodeSetCookieHeader() { return CookieHelper.decodeSetCookieHeader(headers()); } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterRequest.java index a0933484f4f..9b799e3a68f 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterRequest.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterRequest.java @@ -7,7 +7,6 @@ import com.yahoo.jdisc.http.Cookie; import com.yahoo.jdisc.http.HttpHeaders; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.HttpRequest.Version; -import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpRequest; import java.net.InetSocketAddress; import java.net.URI; @@ -37,7 +36,7 @@ public abstract class DiscFilterRequest { protected static final int DEFAULT_HTTP_PORT = 80; protected static final int DEFAULT_HTTPS_PORT = 443; - private final ServletOrJdiscHttpRequest parent; + private final HttpRequest parent; protected final Map<String, List<String>> untreatedParams; private final HeaderFields untreatedHeaders; private List<Cookie> untreatedCookies = null; @@ -45,7 +44,7 @@ public abstract class DiscFilterRequest { private String[] roles = null; private boolean overrideIsUserInRole = false; - public DiscFilterRequest(ServletOrJdiscHttpRequest parent) { + public DiscFilterRequest(HttpRequest parent) { this.parent = parent; // save untreated headers from parent diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterResponse.java index fad0f46402d..c187a2f032f 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterResponse.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/filter/DiscFilterResponse.java @@ -1,6 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter; +import com.yahoo.jdisc.HeaderFields; +import com.yahoo.jdisc.http.Cookie; +import com.yahoo.jdisc.http.HttpResponse; + import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -8,14 +12,6 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; -import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpResponse; - -import com.yahoo.jdisc.HeaderFields; -import com.yahoo.jdisc.http.Cookie; - - -import com.yahoo.jdisc.http.HttpResponse; - /** * This class was made abstract from 5.27. Test cases that need * a concrete instance should create a {@link JdiscFilterResponse}. @@ -24,11 +20,11 @@ import com.yahoo.jdisc.http.HttpResponse; */ public abstract class DiscFilterResponse { - private final ServletOrJdiscHttpResponse parent; + private final HttpResponse parent; private final HeaderFields untreatedHeaders; private final List<Cookie> untreatedCookies; - public DiscFilterResponse(ServletOrJdiscHttpResponse parent) { + public DiscFilterResponse(HttpResponse parent) { this.parent = parent; this.untreatedHeaders = new HeaderFields(); @@ -116,12 +112,7 @@ public abstract class DiscFilterResponse { /** * Return the parent HttpResponse */ - public HttpResponse getParentResponse() { - if (parent instanceof HttpResponse) - return (HttpResponse)parent; - throw new UnsupportedOperationException( - "getParentResponse is not supported for " + parent.getClass().getName()); - } + public HttpResponse getParentResponse() { return parent; } public void addCookie(JDiscCookieWrapper cookie) { if(cookie != null) { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterRequest.java index eaa02680d48..f78c03f7af7 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterRequest.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterRequest.java @@ -3,7 +3,7 @@ package com.yahoo.jdisc.http.filter; import com.yahoo.jdisc.http.HttpHeaders; import com.yahoo.jdisc.http.HttpRequest; -import com.yahoo.jdisc.http.servlet.ServletRequest; +import com.yahoo.jdisc.http.server.jetty.RequestUtils; import java.net.URI; import java.security.Principal; @@ -120,7 +120,7 @@ public class JdiscFilterRequest extends DiscFilterRequest { @Override public List<X509Certificate> getClientCertificateChain() { - return Optional.ofNullable(parent.context().get(ServletRequest.JDISC_REQUEST_X509CERT)) + return Optional.ofNullable(parent.context().get(RequestUtils.JDISC_REQUEST_X509CERT)) .map(X509Certificate[].class::cast) .map(Arrays::asList) .orElse(Collections.emptyList()); diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterResponse.java index ee2e1be3ebf..3b035987c8a 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterResponse.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/filter/JdiscFilterResponse.java @@ -1,15 +1,12 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter; -import com.yahoo.jdisc.HeaderFields; import com.yahoo.jdisc.Response; import com.yahoo.jdisc.http.Cookie; import com.yahoo.jdisc.http.CookieHelper; import com.yahoo.jdisc.http.HttpResponse; -import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpResponse; import java.util.List; -import java.util.Map; /** * JDisc implementation of a filter request. @@ -19,8 +16,7 @@ class JdiscFilterResponse extends DiscFilterResponse { private final Response parent; JdiscFilterResponse(Response parent) { - // A separate adapter is required as DiscFilterResponse will invoke methods from ServletOrJdiscHttpResponse parameter in its constructor - super(parent instanceof HttpResponse ? (HttpResponse)parent : new Adapter(parent)); + super((HttpResponse)parent); this.parent = parent; } @@ -68,17 +64,4 @@ class JdiscFilterResponse extends DiscFilterResponse { CookieHelper.encodeSetCookieHeader(parent.headers(), cookies); } - private static class Adapter implements ServletOrJdiscHttpResponse { - private final Response response; - - Adapter(Response response) { - this.response = response; - } - - @Override public void copyHeaders(HeaderFields target) { target.addAll(response.headers()); } - @Override public int getStatus() { return response.getStatus(); } - @Override public Map<String, Object> context() { return response.context(); } - @Override public List<Cookie> decodeSetCookieHeader() { return CookieHelper.decodeSetCookieHeader(response.headers()); } - } - } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/SecurityFilterInvoker.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/SecurityFilterInvoker.java deleted file mode 100644 index a0b9ec935cb..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/SecurityFilterInvoker.java +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.filter; - -import com.google.common.annotations.Beta; -import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.HttpRequest.Method; -import com.yahoo.jdisc.http.servlet.ServletRequest; - -import com.yahoo.jdisc.http.servlet.ServletResponse; -import com.yahoo.jdisc.http.server.jetty.FilterInvoker; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.URI; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -/** - * Only intended for internal vespa use. - * - * Runs JDisc security filter without using JDisc request/response. - * Only intended to be used in a servlet context, as the error messages are tailored for that. - * - * Assumes that SecurityResponseFilters mutate DiscFilterResponse in the thread they are invoked from. - * - * @author Tony Vaagenes - */ -@Beta -public class SecurityFilterInvoker implements FilterInvoker { - - /** - * Returns the servlet request to be used in any servlets invoked after this. - */ - @Override - public HttpServletRequest invokeRequestFilterChain(RequestFilter requestFilterChain, - URI uri, HttpServletRequest httpRequest, - ResponseHandler responseHandler) { - - SecurityRequestFilterChain securityChain = cast(SecurityRequestFilterChain.class, requestFilterChain). - orElseThrow(SecurityFilterInvoker::newUnsupportedOperationException); - - ServletRequest wrappedRequest = new ServletRequest(httpRequest, uri); - securityChain.filter(new ServletFilterRequest(wrappedRequest), responseHandler); - return wrappedRequest; - } - - @Override - public void invokeResponseFilterChain( - ResponseFilter responseFilterChain, - URI uri, - HttpServletRequest request, - HttpServletResponse response) { - - SecurityResponseFilterChain securityChain = cast(SecurityResponseFilterChain.class, responseFilterChain). - orElseThrow(SecurityFilterInvoker::newUnsupportedOperationException); - - ServletFilterResponse wrappedResponse = new ServletFilterResponse(new ServletResponse(response)); - securityChain.filter(new ServletRequestView(uri, request), wrappedResponse); - } - - private static UnsupportedOperationException newUnsupportedOperationException() { - return new UnsupportedOperationException( - "Filter type not supported. If a request is handled by servlets or jax-rs, then any filters invoked for that request must be security filters."); - } - - private <T> Optional<T> cast(Class<T> securityFilterChainClass, Object filter) { - return (securityFilterChainClass.isInstance(filter))? - Optional.of(securityFilterChainClass.cast(filter)): - Optional.empty(); - } - - private static class ServletRequestView implements RequestView { - private final HttpServletRequest request; - private final URI uri; - - public ServletRequestView(URI uri, HttpServletRequest request) { - this.request = request; - this.uri = uri; - } - - @Override - public Object getAttribute(String name) { - return request.getAttribute(name); - } - - @Override - public List<String> getHeaders(String name) { - return Collections.unmodifiableList(Collections.list(request.getHeaders(name))); - } - - @Override - public Optional<String> getFirstHeader(String name) { - return getHeaders(name).stream().findFirst(); - } - - @Override - public Optional<Method> getMethod() { - return Optional.of(Method.valueOf(request.getMethod())); - } - - @Override - public URI getUri() { - return uri; - } - } - -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterRequest.java deleted file mode 100644 index c27c0e56d30..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterRequest.java +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.filter; - -import com.yahoo.jdisc.http.HttpHeaders; -import com.yahoo.jdisc.http.servlet.ServletRequest; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.security.Principal; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -/** - * Servlet implementation for JDisc filter requests. - */ -class ServletFilterRequest extends DiscFilterRequest { - - private final ServletRequest parent; - - public ServletFilterRequest(ServletRequest parent) { - super(parent); - this.parent = parent; - } - - ServletRequest getServletRequest() { - return parent; - } - - @Deprecated - public void setUri(URI uri) { - parent.setUri(uri); - } - - @Override - public String getMethod() { - return parent.getRequest().getMethod(); - } - - @Override - public void setRemoteAddr(String remoteIpAddress) { - throw new UnsupportedOperationException( - "Setting remote address is not supported for " + this.getClass().getName()); - } - - @Override - public Enumeration<String> getAttributeNames() { - Set<String> names = new HashSet<>(Collections.list(super.getAttributeNames())); - names.addAll(Collections.list(parent.getRequest().getAttributeNames())); - return Collections.enumeration(names); - } - - @Override - public Object getAttribute(String name) { - Object jdiscAttribute = super.getAttribute(name); - return jdiscAttribute != null ? - jdiscAttribute : - parent.getRequest().getAttribute(name); - } - - @Override - public void setAttribute(String name, Object value) { - super.setAttribute(name, value); - parent.getRequest().setAttribute(name, value); - } - - @Override - public boolean containsAttribute(String name) { - return super.containsAttribute(name) - || parent.getRequest().getAttribute(name) != null; - } - - @Override - public void removeAttribute(String name) { - super.removeAttribute(name); - parent.getRequest().removeAttribute(name); - } - - @Override - public String getParameter(String name) { - return parent.getParameter(name); - } - - @Override - public Enumeration<String> getParameterNames() { - return parent.getParameterNames(); - } - - @Override - public void addHeader(String name, String value) { - parent.addHeader(name, value); - } - - @Override - public String getHeader(String name) { - return parent.getHeader(name); - } - - @Override - public Enumeration<String> getHeaderNames() { - return parent.getHeaderNames(); - } - - public List<String> getHeaderNamesAsList() { - return Collections.list(getHeaderNames()); - } - - @Override - public Enumeration<String> getHeaders(String name) { - return parent.getHeaders(name); - } - - @Override - public List<String> getHeadersAsList(String name) { - return Collections.list(getHeaders(name)); - } - - @Override - public void setHeaders(String name, String value) { - parent.setHeaders(name, value); - } - - @Override - public void setHeaders(String name, List<String> values) { - parent.setHeaders(name, values); - } - - @Override - public Principal getUserPrincipal() { - return parent.getUserPrincipal(); - } - - @Override - public void setUserPrincipal(Principal principal) { - parent.setUserPrincipal(principal); - } - - @Override - public List<X509Certificate> getClientCertificateChain() { - return Optional.ofNullable(parent.getRequest().getAttribute(ServletRequest.SERVLET_REQUEST_X509CERT)) - .map(X509Certificate[].class::cast) - .map(Arrays::asList) - .orElse(Collections.emptyList()); - } - - @Override - public void removeHeaders(String name) { - parent.removeHeaders(name); - } - - @Override - public void clearCookies() { - parent.removeHeaders(HttpHeaders.Names.COOKIE); - } - - @Override - public void setCharacterEncoding(String encoding) { - super.setCharacterEncoding(encoding); - try { - parent.setCharacterEncoding(encoding); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Encoding not supported: " + encoding, e); - } - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterResponse.java deleted file mode 100644 index b706e5a7ec6..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/ServletFilterResponse.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.filter; - -import com.google.common.collect.Iterables; -import com.yahoo.jdisc.http.Cookie; -import com.yahoo.jdisc.http.HttpHeaders; -import com.yahoo.jdisc.http.servlet.ServletResponse; - -import javax.servlet.http.HttpServletResponse; -import java.util.Collection; -import java.util.List; - -/** - * Servlet implementation for JDisc filter responses. - */ -class ServletFilterResponse extends DiscFilterResponse { - - private final ServletResponse parent; - - public ServletFilterResponse(ServletResponse parent) { - super(parent); - this.parent = parent; - } - - ServletResponse getServletResponse() { - return parent; - } - - public void setStatus(int status) { - parent.setStatus(status); - } - - @Override - public void setHeader(String name, String value) { - parent.setHeader(name, value); - } - - @Override - public void removeHeaders(String name) { - HttpServletResponse parentResponse = parent.getResponse(); - if (parentResponse instanceof org.eclipse.jetty.server.Response) { - org.eclipse.jetty.server.Response jettyResponse = (org.eclipse.jetty.server.Response)parentResponse; - jettyResponse.getHttpFields().remove(name); - } else { - throw new UnsupportedOperationException( - "Cannot remove headers for response of type " + parentResponse.getClass().getName()); - } - } - - // Why have a setHeaders that takes a single string? - @Override - public void setHeaders(String name, String value) { - parent.setHeader(name, value); - } - - @Override - public void setHeaders(String name, List<String> values) { - for (String value : values) - parent.addHeader(name, value); - } - - @Override - public void addHeader(String name, String value) { - parent.addHeader(name, value); - } - - @Override - public String getHeader(String name) { - Collection<String> headers = parent.getHeaders(name); - return headers.isEmpty() - ? null - : Iterables.getLast(headers); - } - - @Override - public void setCookies(List<Cookie> cookies) { - removeHeaders(HttpHeaders.Names.SET_COOKIE); - List<String> setCookieHeaders = Cookie.toSetCookieHeaders(cookies); - setCookieHeaders.forEach(cookie -> addHeader(HttpHeaders.Names.SET_COOKIE, cookie)); - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java index 2eea7f155ee..b41c80a471c 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java @@ -8,7 +8,6 @@ import com.yahoo.container.logging.RequestLog; import com.yahoo.container.logging.RequestLogEntry; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.servlet.ServletRequest; import org.eclipse.jetty.http2.HTTP2Stream; import org.eclipse.jetty.http2.server.HttpTransportOverHTTP2; import org.eclipse.jetty.server.HttpChannel; @@ -86,10 +85,10 @@ class AccessLogRequestLog extends AbstractLifeCycle implements org.eclipse.jetty addNonNullValue(builder, jdiscRequest.getUserPrincipal(), RequestLogEntry.Builder::userPrincipal); } - String requestFilterId = (String) request.getAttribute(ServletRequest.JDISC_REQUEST_CHAIN); + String requestFilterId = (String) request.getAttribute(RequestUtils.JDISC_REQUEST_CHAIN); addNonNullValue(builder, requestFilterId, (b, chain) -> b.addExtraAttribute("request-chain", chain)); - String responseFilterId = (String) request.getAttribute(ServletRequest.JDISC_RESPONSE_CHAIN); + String responseFilterId = (String) request.getAttribute(RequestUtils.JDISC_RESPONSE_CHAIN); addNonNullValue(builder, responseFilterId, (b, chain) -> b.addExtraAttribute("response-chain", chain)); UUID connectionId = (UUID) request.getAttribute(JettyConnectionLogger.CONNECTION_ID_REQUEST_ATTRIBUTE); @@ -109,7 +108,7 @@ class AccessLogRequestLog extends AbstractLifeCycle implements org.eclipse.jetty builder.addExtraAttribute(header, value); } }); - X509Certificate[] clientCert = (X509Certificate[]) request.getAttribute(ServletRequest.SERVLET_REQUEST_X509CERT); + X509Certificate[] clientCert = (X509Certificate[]) request.getAttribute(RequestUtils.SERVLET_REQUEST_X509CERT); if (clientCert != null && clientCert.length > 0) { builder.sslPrincipal(clientCert[0].getSubjectX500Principal()); } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvoker.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvoker.java deleted file mode 100644 index 3c329bbf13b..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvoker.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import com.google.inject.ImplementedBy; -import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.filter.RequestFilter; -import com.yahoo.jdisc.http.filter.ResponseFilter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.URI; - -/** - * Separate interface since DiscFilterRequest/Response and Security filter chains are not accessible in this bundle - */ -@ImplementedBy(UnsupportedFilterInvoker.class) -public interface FilterInvoker { - HttpServletRequest invokeRequestFilterChain(RequestFilter requestFilterChain, - URI uri, - HttpServletRequest httpRequest, - ResponseHandler responseHandler); - - void invokeResponseFilterChain( - ResponseFilter responseFilterChain, - URI uri, - HttpServletRequest request, - HttpServletResponse response); -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingPrintWriter.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingPrintWriter.java deleted file mode 100644 index 90b12e64a55..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingPrintWriter.java +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.Locale; - -/** - * Invokes the response filter the first time anything is output to the underlying PrintWriter. - * The filter must be invoked before the first output call since this might cause the response - * to be committed, i.e. locked and potentially put on the wire. - * Any changes to the response after it has been committed might be ignored or cause exceptions. - * @author Tony Vaagenes - */ -final class FilterInvokingPrintWriter extends PrintWriter { - private final PrintWriter delegate; - private final OneTimeRunnable filterInvoker; - - public FilterInvokingPrintWriter(PrintWriter delegate, OneTimeRunnable filterInvoker) { - /* The PrintWriter class both - * 1) exposes new methods, the PrintWriter "interface" - * 2) implements PrintWriter and Writer methods that does some extra things before calling down to the writer methods. - * If super was invoked with the delegate PrintWriter, the superclass would behave as a PrintWriter(PrintWriter), - * i.e. the extra things in 2. would be done twice. - * To avoid this, all the methods of PrintWriter are overridden with versions that forward directly to the underlying delegate - * instead of going through super. - * The super class is initialized with a non-functioning writer to catch mistakenly non-overridden methods. - */ - super(new Writer() { - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - throwAssertionError(); - } - - private void throwAssertionError() { - throw new AssertionError(FilterInvokingPrintWriter.class.getName() + " failed to delegate to the underlying writer"); - } - - @Override - public void flush() throws IOException { - throwAssertionError(); - } - - @Override - public void close() throws IOException { - throwAssertionError(); - } - }); - - this.delegate = delegate; - this.filterInvoker = filterInvoker; - } - - @Override - public String toString() { - return getClass().getName() + " (" + super.toString() + ")"; - } - - private void runFilterIfFirstInvocation() { - filterInvoker.runIfFirstInvocation(); - } - - @Override - public void flush() { - runFilterIfFirstInvocation(); - delegate.flush(); - } - - @Override - public void close() { - runFilterIfFirstInvocation(); - delegate.close(); - } - - @Override - public boolean checkError() { - return delegate.checkError(); - } - - @Override - public void write(int c) { - runFilterIfFirstInvocation(); - delegate.write(c); - } - - @Override - public void write(char[] buf, int off, int len) { - runFilterIfFirstInvocation(); - delegate.write(buf, off, len); - } - - @Override - public void write(char[] buf) { - runFilterIfFirstInvocation(); - delegate.write(buf); - } - - @Override - public void write(String s, int off, int len) { - runFilterIfFirstInvocation(); - delegate.write(s, off, len); - } - - @Override - public void write(String s) { - runFilterIfFirstInvocation(); - delegate.write(s); - } - - @Override - public void print(boolean b) { - runFilterIfFirstInvocation(); - delegate.print(b); - } - - @Override - public void print(char c) { - runFilterIfFirstInvocation(); - delegate.print(c); - } - - @Override - public void print(int i) { - runFilterIfFirstInvocation(); - delegate.print(i); - } - - @Override - public void print(long l) { - runFilterIfFirstInvocation(); - delegate.print(l); - } - - @Override - public void print(float f) { - runFilterIfFirstInvocation(); - delegate.print(f); - } - - @Override - public void print(double d) { - runFilterIfFirstInvocation(); - delegate.print(d); - } - - @Override - public void print(char[] s) { - runFilterIfFirstInvocation(); - delegate.print(s); - } - - @Override - public void print(String s) { - runFilterIfFirstInvocation(); - delegate.print(s); - } - - @Override - public void print(Object obj) { - runFilterIfFirstInvocation(); - delegate.print(obj); - } - - @Override - public void println() { - runFilterIfFirstInvocation(); - delegate.println(); - } - - @Override - public void println(boolean x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(char x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(int x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(long x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(float x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(double x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(char[] x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(String x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public void println(Object x) { - runFilterIfFirstInvocation(); - delegate.println(x); - } - - @Override - public PrintWriter printf(String format, Object... args) { - runFilterIfFirstInvocation(); - return delegate.printf(format, args); - } - - @Override - public PrintWriter printf(Locale l, String format, Object... args) { - runFilterIfFirstInvocation(); - return delegate.printf(l, format, args); - } - - @Override - public PrintWriter format(String format, Object... args) { - runFilterIfFirstInvocation(); - return delegate.format(format, args); - } - - @Override - public PrintWriter format(Locale l, String format, Object... args) { - runFilterIfFirstInvocation(); - return delegate.format(l, format, args); - } - - @Override - public PrintWriter append(CharSequence csq) { - runFilterIfFirstInvocation(); - return delegate.append(csq); - } - - @Override - public PrintWriter append(CharSequence csq, int start, int end) { - runFilterIfFirstInvocation(); - return delegate.append(csq, start, end); - } - - @Override - public PrintWriter append(char c) { - runFilterIfFirstInvocation(); - return delegate.append(c); - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingServletOutputStream.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingServletOutputStream.java deleted file mode 100644 index d2be107ef86..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterInvokingServletOutputStream.java +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import java.io.IOException; - -/** - * Invokes the response filter the first time anything is output to the underlying ServletOutputStream. - * The filter must be invoked before the first output call since this might cause the response - * to be committed, i.e. locked and potentially put on the wire. - * Any changes to the response after it has been committed might be ignored or cause exceptions. - * - * @author Tony Vaagenes - */ -class FilterInvokingServletOutputStream extends ServletOutputStream { - private final ServletOutputStream delegate; - private final OneTimeRunnable filterInvoker; - - public FilterInvokingServletOutputStream(ServletOutputStream delegate, OneTimeRunnable filterInvoker) { - this.delegate = delegate; - this.filterInvoker = filterInvoker; - } - - @Override - public boolean isReady() { - return delegate.isReady(); - } - - @Override - public void setWriteListener(WriteListener writeListener) { - delegate.setWriteListener(writeListener); - } - - - private void runFilterIfFirstInvocation() { - filterInvoker.runIfFirstInvocation(); - } - - @Override - public void write(int b) throws IOException { - runFilterIfFirstInvocation(); - delegate.write(b); - } - - - @Override - public void write(byte[] b) throws IOException { - runFilterIfFirstInvocation(); - delegate.write(b); - } - - @Override - public void print(String s) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(s); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - runFilterIfFirstInvocation(); - delegate.write(b, off, len); - } - - @Override - public void print(boolean b) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(b); - } - - @Override - public void flush() throws IOException { - runFilterIfFirstInvocation(); - delegate.flush(); - } - - @Override - public void print(char c) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(c); - } - - @Override - public void close() throws IOException { - runFilterIfFirstInvocation(); - delegate.close(); - } - - @Override - public void print(int i) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(i); - } - - @Override - public void print(long l) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(l); - } - - @Override - public void print(float f) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(f); - } - - @Override - public void print(double d) throws IOException { - runFilterIfFirstInvocation(); - delegate.print(d); - } - - @Override - public void println() throws IOException { - runFilterIfFirstInvocation(); - delegate.println(); - } - - @Override - public void println(String s) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(s); - } - - @Override - public void println(boolean b) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(b); - } - - @Override - public void println(char c) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(c); - } - - @Override - public void println(int i) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(i); - } - - @Override - public void println(long l) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(l); - } - - @Override - public void println(float f) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(f); - } - - @Override - public void println(double d) throws IOException { - runFilterIfFirstInvocation(); - delegate.println(d); - } - - @Override - public String toString() { - return getClass().getCanonicalName() + " (" + delegate.toString() + ")"; - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterResolver.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterResolver.java index 873f336f0c9..32def124131 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterResolver.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterResolver.java @@ -10,7 +10,6 @@ import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; -import com.yahoo.jdisc.http.servlet.ServletRequest; import org.eclipse.jetty.server.Request; import java.net.URI; @@ -40,13 +39,13 @@ class FilterResolver { Optional<String> maybeFilterId = bindings.resolveRequestFilter(jdiscUri, getConnector(request).listenPort()); if (maybeFilterId.isPresent()) { metric.add(MetricDefinitions.FILTERING_REQUEST_HANDLED, 1L, createMetricContext(request, maybeFilterId.get())); - request.setAttribute(ServletRequest.JDISC_REQUEST_CHAIN, maybeFilterId.get()); + request.setAttribute(RequestUtils.JDISC_REQUEST_CHAIN, maybeFilterId.get()); } else if (!strictFiltering) { metric.add(MetricDefinitions.FILTERING_REQUEST_UNHANDLED, 1L, createMetricContext(request, null)); } else { String syntheticFilterId = RejectingRequestFilter.SYNTHETIC_FILTER_CHAIN_ID; metric.add(MetricDefinitions.FILTERING_REQUEST_HANDLED, 1L, createMetricContext(request, syntheticFilterId)); - request.setAttribute(ServletRequest.JDISC_REQUEST_CHAIN, syntheticFilterId); + request.setAttribute(RequestUtils.JDISC_REQUEST_CHAIN, syntheticFilterId); return Optional.of(RejectingRequestFilter.INSTANCE); } return maybeFilterId.map(bindings::getRequestFilter); @@ -56,7 +55,7 @@ class FilterResolver { Optional<String> maybeFilterId = bindings.resolveResponseFilter(jdiscUri, getConnector(request).listenPort()); if (maybeFilterId.isPresent()) { metric.add(MetricDefinitions.FILTERING_RESPONSE_HANDLED, 1L, createMetricContext(request, maybeFilterId.get())); - request.setAttribute(ServletRequest.JDISC_RESPONSE_CHAIN, maybeFilterId.get()); + request.setAttribute(RequestUtils.JDISC_RESPONSE_CHAIN, maybeFilterId.get()); } else { metric.add(MetricDefinitions.FILTERING_RESPONSE_UNHANDLED, 1L, createMetricContext(request, null)); } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestFactory.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestFactory.java index 52c2a83563e..c54fa1cf1b9 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestFactory.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestFactory.java @@ -2,7 +2,6 @@ package com.yahoo.jdisc.http.server.jetty; import com.yahoo.jdisc.http.HttpRequest; -import com.yahoo.jdisc.http.servlet.ServletRequest; import com.yahoo.jdisc.service.CurrentContainer; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.Utf8Appendable; @@ -32,7 +31,7 @@ class HttpRequestFactory { HttpRequest.Version.fromString(servletRequest.getProtocol()), new InetSocketAddress(servletRequest.getRemoteAddr(), servletRequest.getRemotePort()), getConnection((Request) servletRequest).getCreatedTimeStamp()); - httpRequest.context().put(ServletRequest.JDISC_REQUEST_X509CERT, getCertChain(servletRequest)); + httpRequest.context().put(RequestUtils.JDISC_REQUEST_X509CERT, getCertChain(servletRequest)); servletRequest.setAttribute(HttpRequest.class.getName(), httpRequest); return httpRequest; } catch (Utf8Appendable.NotUtf8Exception e) { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java deleted file mode 100644 index 0fd4e8c42fb..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import com.yahoo.container.logging.AccessLogEntry; -import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.filter.RequestFilter; -import org.eclipse.jetty.server.Request; - -import javax.servlet.AsyncContext; -import javax.servlet.AsyncListener; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.URI; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; - -import static com.yahoo.jdisc.http.server.jetty.RequestUtils.getConnector; -import static com.yahoo.yolean.Exceptions.throwUnchecked; - -/** - * Runs JDisc security filters for Servlets - * This component is split in two: - * 1) JDiscFilterInvokerFilter, which uses package private methods to support JDisc APIs - * 2) SecurityFilterInvoker, which is intended for use in a servlet context. - * - * @author Tony Vaagenes - */ -class JDiscFilterInvokerFilter implements Filter { - private final JDiscContext jDiscContext; - private final FilterInvoker filterInvoker; - - public JDiscFilterInvokerFilter(JDiscContext jDiscContext, - FilterInvoker filterInvoker) { - this.jDiscContext = jDiscContext; - this.filterInvoker = filterInvoker; - } - - - @Override - public void init(FilterConfig filterConfig) throws ServletException {} - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpRequest = (HttpServletRequest)request; - HttpServletResponse httpResponse = (HttpServletResponse)response; - - URI uri; - try { - uri = HttpRequestFactory.getUri(httpRequest); - } catch (RequestException e) { - httpResponse.sendError(e.getResponseStatus(), e.getMessage()); - return; - } - - AtomicReference<Boolean> responseReturned = new AtomicReference<>(null); - - HttpServletRequest newRequest = runRequestFilterWithMatchingBinding(responseReturned, uri, httpRequest, httpResponse); - assert newRequest != null; - responseReturned.compareAndSet(null, false); - - if (!responseReturned.get()) { - runChainAndResponseFilters(uri, newRequest, httpResponse, chain); - } - } - - private void runChainAndResponseFilters(URI uri, HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - Optional<OneTimeRunnable> responseFilterInvoker = - jDiscContext.filterResolver.resolveResponseFilter(toJettyRequest(request), uri) - .map(responseFilter -> - new OneTimeRunnable(() -> - filterInvoker.invokeResponseFilterChain(responseFilter, uri, request, response))); - - - HttpServletResponse responseForServlet = responseFilterInvoker - .<HttpServletResponse>map(invoker -> - new FilterInvokingResponseWrapper(response, invoker)) - .orElse(response); - - HttpServletRequest requestForServlet = responseFilterInvoker - .<HttpServletRequest>map(invoker -> - new FilterInvokingRequestWrapper(request, invoker, responseForServlet)) - .orElse(request); - - chain.doFilter(requestForServlet, responseForServlet); - - responseFilterInvoker.ifPresent(invoker -> { - boolean requestHandledSynchronously = !request.isAsyncStarted(); - - if (requestHandledSynchronously) { - invoker.runIfFirstInvocation(); - } - // For async requests, response filters will be invoked on AsyncContext.complete(). - }); - } - - private HttpServletRequest runRequestFilterWithMatchingBinding(AtomicReference<Boolean> responseReturned, URI uri, HttpServletRequest request, HttpServletResponse response) throws IOException { - try { - RequestFilter requestFilter = jDiscContext.filterResolver.resolveRequestFilter(toJettyRequest(request), uri).orElse(null); - if (requestFilter == null) - return request; - - ResponseHandler responseHandler = createResponseHandler(responseReturned, request, response); - return filterInvoker.invokeRequestFilterChain(requestFilter, uri, request, responseHandler); - } catch (Exception e) { - throw new RuntimeException("Failed running request filter chain for uri " + uri, e); - } - } - - private ResponseHandler createResponseHandler(AtomicReference<Boolean> responseReturned, HttpServletRequest httpRequest, HttpServletResponse httpResponse) { - return jdiscResponse -> { - boolean oldValueWasNull = responseReturned.compareAndSet(null, true); - if (!oldValueWasNull) - throw new RuntimeException("Can't return response from filter asynchronously"); - - HttpRequestDispatch requestDispatch = createRequestDispatch(httpRequest, httpResponse); - return requestDispatch.dispatchFilterRequest(jdiscResponse); - }; - } - - private HttpRequestDispatch createRequestDispatch(HttpServletRequest request, HttpServletResponse response) { - try { - final AccessLogEntry accessLogEntry = null; // Not used in this context. - return new HttpRequestDispatch(jDiscContext, - accessLogEntry, - getConnector(toJettyRequest(request)).createRequestMetricContext(request, Map.of()), - request, response); - } catch (IOException e) { - throw throwUnchecked(e); - } - } - - private static Request toJettyRequest(HttpServletRequest request) { - if (request instanceof com.yahoo.jdisc.http.servlet.ServletRequest) { - return (Request) ((com.yahoo.jdisc.http.servlet.ServletRequest)request).getRequest(); - } - return (Request) request; - } - - @Override - public void destroy() {} - - // ServletRequest wrapper that is necessary because we need to wrap AsyncContext. - private static class FilterInvokingRequestWrapper extends HttpServletRequestWrapper { - private final OneTimeRunnable filterInvoker; - private final HttpServletResponse servletResponse; - - public FilterInvokingRequestWrapper( - HttpServletRequest request, - OneTimeRunnable filterInvoker, - HttpServletResponse servletResponse) { - super(request); - this.filterInvoker = filterInvoker; - this.servletResponse = servletResponse; - } - - @Override - public AsyncContext startAsync() { - final AsyncContext asyncContext = super.startAsync(); - return new FilterInvokingAsyncContext(asyncContext, filterInvoker, this, servletResponse); - } - - @Override - public AsyncContext startAsync( - final ServletRequest wrappedRequest, - final ServletResponse wrappedResponse) { - // According to the documentation, the passed request/response parameters here must either - // _be_ or _wrap_ the original request/response objects passed to the servlet - which are - // our wrappers, so no need to wrap again - we can use the user-supplied objects. - final AsyncContext asyncContext = super.startAsync(wrappedRequest, wrappedResponse); - return new FilterInvokingAsyncContext(asyncContext, filterInvoker, this, wrappedResponse); - } - - @Override - public AsyncContext getAsyncContext() { - final AsyncContext asyncContext = super.getAsyncContext(); - return new FilterInvokingAsyncContext(asyncContext, filterInvoker, this, servletResponse); - } - } - - // AsyncContext wrapper that is necessary for two reasons: - // 1) Run response filters when AsyncContext.complete() is called. - // 2) Eliminate paths where application code can get its hands on un-wrapped response object, circumventing - // running of response filters. - private static class FilterInvokingAsyncContext implements AsyncContext { - private final AsyncContext delegate; - private final OneTimeRunnable filterInvoker; - private final ServletRequest servletRequest; - private final ServletResponse servletResponse; - - public FilterInvokingAsyncContext( - AsyncContext delegate, - OneTimeRunnable filterInvoker, - ServletRequest servletRequest, - ServletResponse servletResponse) { - this.delegate = delegate; - this.filterInvoker = filterInvoker; - this.servletRequest = servletRequest; - this.servletResponse = servletResponse; - } - - @Override - public ServletRequest getRequest() { - return servletRequest; - } - - @Override - public ServletResponse getResponse() { - return servletResponse; - } - - @Override - public boolean hasOriginalRequestAndResponse() { - return delegate.hasOriginalRequestAndResponse(); - } - - @Override - public void dispatch() { - delegate.dispatch(); - } - - @Override - public void dispatch(String s) { - delegate.dispatch(s); - } - - @Override - public void dispatch(ServletContext servletContext, String s) { - delegate.dispatch(servletContext, s); - } - - @Override - public void complete() { - // Completing may commit the response, so this is the last chance to run response filters. - filterInvoker.runIfFirstInvocation(); - delegate.complete(); - } - - @Override - public void start(Runnable runnable) { - delegate.start(runnable); - } - - @Override - public void addListener(AsyncListener asyncListener) { - delegate.addListener(asyncListener); - } - - @Override - public void addListener(AsyncListener asyncListener, ServletRequest servletRequest, ServletResponse servletResponse) { - delegate.addListener(asyncListener, servletRequest, servletResponse); - } - - @Override - public <T extends AsyncListener> T createListener(Class<T> aClass) throws ServletException { - return delegate.createListener(aClass); - } - - @Override - public void setTimeout(long l) { - delegate.setTimeout(l); - } - - @Override - public long getTimeout() { - return delegate.getTimeout(); - } - } - - private static class FilterInvokingResponseWrapper extends HttpServletResponseWrapper { - private final OneTimeRunnable filterInvoker; - - public FilterInvokingResponseWrapper(HttpServletResponse response, OneTimeRunnable filterInvoker) { - super(response); - this.filterInvoker = filterInvoker; - } - - @Override - public ServletOutputStream getOutputStream() throws IOException { - ServletOutputStream delegate = super.getOutputStream(); - return new FilterInvokingServletOutputStream(delegate, filterInvoker); - } - - @Override - public PrintWriter getWriter() throws IOException { - PrintWriter delegate = super.getWriter(); - return new FilterInvokingPrintWriter(delegate, filterInvoker); - } - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java index 0e511fd3eaf..79cdb8f67cf 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java @@ -73,7 +73,7 @@ class JDiscServerConnector extends ServerConnector { public Metric.Context createRequestMetricContext(HttpServletRequest request, Map<String, String> extraDimensions) { String method = request.getMethod(); String scheme = request.getScheme(); - boolean clientAuthenticated = request.getAttribute(com.yahoo.jdisc.http.servlet.ServletRequest.SERVLET_REQUEST_X509CERT) != null; + boolean clientAuthenticated = request.getAttribute(RequestUtils.SERVLET_REQUEST_X509CERT) != null; Map<String, Object> dimensions = createConnectorDimensions(listenPort, connectorName); dimensions.put(MetricDefinitions.METHOD_DIMENSION, method); dimensions.put(MetricDefinitions.SCHEME_DIMENSION, scheme); diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java index 3f2a91c60b5..fca34f3bbd7 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java @@ -2,14 +2,12 @@ package com.yahoo.jdisc.http.server.jetty; import com.google.inject.Inject; -import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.container.logging.ConnectionLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.jdisc.Metric; import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.service.AbstractServerProvider; import com.yahoo.jdisc.service.CurrentContainer; import org.eclipse.jetty.http.HttpField; @@ -24,7 +22,6 @@ import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.StatisticsHandler; import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.server.handler.gzip.GzipHttpOutputInterceptor; -import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.log.JavaUtilLog; @@ -32,14 +29,12 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.thread.QueuedThreadPool; import javax.management.remote.JMXServiceURL; -import javax.servlet.DispatcherType; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.BindException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Arrays; -import java.util.EnumSet; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -63,12 +58,9 @@ public class JettyHttpServer extends AbstractServerProvider { public JettyHttpServer(CurrentContainer container, Metric metric, ServerConfig serverConfig, - ServletPathsConfig servletPathsConfig, FilterBindings filterBindings, Janitor janitor, ComponentRegistry<ConnectorFactory> connectorFactories, - ComponentRegistry<ServletHolder> servletHolders, - FilterInvoker filterInvoker, RequestLog requestLog, ConnectionLog connectionLog) { super(container); @@ -98,18 +90,13 @@ public class JettyHttpServer extends AbstractServerProvider { serverConfig); ServletHolder jdiscServlet = new ServletHolder(new JDiscHttpServlet(jDiscContext)); - FilterHolder jDiscFilterInvokerFilter = new FilterHolder(new JDiscFilterInvokerFilter(jDiscContext, filterInvoker)); - List<JDiscServerConnector> connectors = Arrays.stream(server.getConnectors()) .map(JDiscServerConnector.class::cast) .collect(toList()); server.setHandler(getHandlerCollection(serverConfig, - servletPathsConfig, connectors, - jdiscServlet, - servletHolders, - jDiscFilterInvokerFilter)); + jdiscServlet)); this.metricsReporter = new ServerMetricReporter(metric, server); } @@ -150,19 +137,9 @@ public class JettyHttpServer extends AbstractServerProvider { } private HandlerCollection getHandlerCollection(ServerConfig serverConfig, - ServletPathsConfig servletPathsConfig, List<JDiscServerConnector> connectors, - ServletHolder jdiscServlet, - ComponentRegistry<ServletHolder> servletHolders, - FilterHolder jDiscFilterInvokerFilter) { + ServletHolder jdiscServlet) { ServletContextHandler servletContextHandler = createServletContextHandler(); - - servletHolders.allComponentsById().forEach((id, servlet) -> { - String path = getServletPath(servletPathsConfig, id); - servletContextHandler.addServlet(servlet, path); - servletContextHandler.addFilter(jDiscFilterInvokerFilter, path, EnumSet.allOf(DispatcherType.class)); - }); - servletContextHandler.addServlet(jdiscServlet, "/*"); List<ConnectorConfig> connectorConfigs = connectors.stream().map(JDiscServerConnector::connectorConfig).collect(toList()); @@ -191,10 +168,6 @@ public class JettyHttpServer extends AbstractServerProvider { return handlerCollection; } - private static String getServletPath(ServletPathsConfig servletPathsConfig, ComponentId id) { - return "/" + servletPathsConfig.servlets(id.stringValue()).path(); - } - private ServletContextHandler createServletContextHandler() { ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS); servletContextHandler.setContextPath("/"); diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/OneTimeRunnable.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/OneTimeRunnable.java deleted file mode 100644 index 24cc41d009f..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/OneTimeRunnable.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author Tony Vaagenes - */ -public class OneTimeRunnable { - private final Runnable runnable; - private final AtomicBoolean hasRun = new AtomicBoolean(false); - - public OneTimeRunnable(Runnable runnable) { - this.runnable = runnable; - } - - public void runIfFirstInvocation() { - boolean previous = hasRun.getAndSet(true); - if (!previous) { - runnable.run(); - } - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestUtils.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestUtils.java index 1bddd491496..ae18c78a7d3 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestUtils.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestUtils.java @@ -12,6 +12,11 @@ import javax.servlet.http.HttpServletRequest; * @author bjorncs */ public class RequestUtils { + public static final String JDISC_REQUEST_X509CERT = "jdisc.request.X509Certificate"; + public static final String JDISC_REQUEST_CHAIN = "jdisc.request.chain"; + public static final String JDISC_RESPONSE_CHAIN = "jdisc.response.chain"; + public static final String SERVLET_REQUEST_X509CERT = "javax.servlet.request.X509Certificate"; + private RequestUtils() {} public static Connection getConnection(Request request) { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/TlsClientAuthenticationEnforcer.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/TlsClientAuthenticationEnforcer.java index b9293226528..3059f972ce9 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/TlsClientAuthenticationEnforcer.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/TlsClientAuthenticationEnforcer.java @@ -3,7 +3,6 @@ package com.yahoo.jdisc.http.server.jetty; import com.yahoo.jdisc.Response; import com.yahoo.jdisc.http.ConnectorConfig; -import com.yahoo.jdisc.http.servlet.ServletRequest; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.HandlerWrapper; @@ -78,6 +77,6 @@ class TlsClientAuthenticationEnforcer extends HandlerWrapper { } private boolean isClientAuthenticated(HttpServletRequest servletRequest) { - return servletRequest.getAttribute(ServletRequest.SERVLET_REQUEST_X509CERT) != null; + return servletRequest.getAttribute(RequestUtils.SERVLET_REQUEST_X509CERT) != null; } } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/UnsupportedFilterInvoker.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/UnsupportedFilterInvoker.java deleted file mode 100644 index 8d878b64e6f..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/UnsupportedFilterInvoker.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import com.yahoo.jdisc.handler.ResponseHandler; -import com.yahoo.jdisc.http.filter.RequestFilter; -import com.yahoo.jdisc.http.filter.ResponseFilter; - -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.net.URI; - -/** - * @author Tony Vaagenes - */ -public class UnsupportedFilterInvoker implements FilterInvoker { - @Override - public HttpServletRequest invokeRequestFilterChain(RequestFilter requestFilterChain, - URI uri, - HttpServletRequest httpRequest, - ResponseHandler responseHandler) { - throw new UnsupportedOperationException(); - } - - @Override - public void invokeResponseFilterChain( - ResponseFilter responseFilterChain, - URI uri, - HttpServletRequest request, - HttpServletResponse response) { - throw new UnsupportedOperationException(); - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ServletModule.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ServletModule.java deleted file mode 100644 index bb69832d767..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ServletModule.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty.testutils; - -import com.google.inject.Binder; -import com.google.inject.Module; -import com.google.inject.Provides; -import com.yahoo.component.provider.ComponentRegistry; - -import org.eclipse.jetty.servlet.ServletHolder; - -/** - * @author Tony Vaagenes - */ -public class ServletModule implements Module { - - @SuppressWarnings("unused") - @Provides - public ComponentRegistry<ServletHolder> servletHolderComponentRegistry() { - return new ComponentRegistry<>(); - } - - @Override public void configure(Binder binder) { } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java index 99c49527ea5..b0c1e7763ca 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java @@ -92,8 +92,7 @@ public class TestDriver implements AutoCloseable { bind(RequestLog.class).toInstance(new VoidRequestLog()); } }, - new ConnectorFactoryRegistryModule(connectorConfig), - new ServletModule()); + new ConnectorFactoryRegistryModule(connectorConfig)); } public static class Builder { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpRequest.java deleted file mode 100644 index 3990c9a8910..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpRequest.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.servlet; - -import com.yahoo.jdisc.HeaderFields; -import com.yahoo.jdisc.http.Cookie; -import com.yahoo.jdisc.http.HttpRequest; - -import java.net.SocketAddress; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * Common interface for JDisc and servlet http requests. - */ -public interface ServletOrJdiscHttpRequest { - - void copyHeaders(HeaderFields target); - - Map<String, List<String>> parameters(); - - URI getUri(); - - HttpRequest.Version getVersion(); - - String getRemoteHostAddress(); - String getRemoteHostName(); - int getRemotePort(); - - void setRemoteAddress(SocketAddress remoteAddress); - - Map<String, Object> context(); - - List<Cookie> decodeCookieHeader(); - - void encodeCookieHeader(List<Cookie> cookies); - - long getConnectedAt(TimeUnit unit); -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpResponse.java deleted file mode 100644 index a40e257b67d..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletOrJdiscHttpResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.servlet; - -import com.yahoo.jdisc.HeaderFields; -import com.yahoo.jdisc.http.Cookie; - -import java.util.List; -import java.util.Map; - -/** - * Common interface for JDisc and servlet http responses. - */ -public interface ServletOrJdiscHttpResponse { - - public void copyHeaders(HeaderFields target); - - public int getStatus(); - - public Map<String, Object> context(); - - public List<Cookie> decodeSetCookieHeader(); - -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletRequest.java b/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletRequest.java deleted file mode 100644 index 8f17c9dc523..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletRequest.java +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.servlet; - -import com.google.common.collect.ImmutableMap; -import com.yahoo.jdisc.HeaderFields; -import com.yahoo.jdisc.http.Cookie; -import com.yahoo.jdisc.http.HttpHeaders; -import com.yahoo.jdisc.http.HttpRequest; -import org.eclipse.jetty.server.Request; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.URI; -import java.security.Principal; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import static com.yahoo.jdisc.http.server.jetty.RequestUtils.getConnection; - -/** - * Mutable wrapper to use a {@link javax.servlet.http.HttpServletRequest} - * with JDisc security filters. - * <p> - * You might find it tempting to remove e.g. the getParameter... methods, - * but keep in mind that this IS-A servlet request and must provide the - * full api of such a request for use outside the "JDisc filter world". - */ -public class ServletRequest extends HttpServletRequestWrapper implements ServletOrJdiscHttpRequest { - - public static final String JDISC_REQUEST_PRINCIPAL = "jdisc.request.principal"; - public static final String JDISC_REQUEST_X509CERT = "jdisc.request.X509Certificate"; - public static final String JDISC_REQUEST_CHAIN = "jdisc.request.chain"; - public static final String JDISC_RESPONSE_CHAIN = "jdisc.response.chain"; - public static final String SERVLET_REQUEST_X509CERT = "javax.servlet.request.X509Certificate"; - public static final String SERVLET_REQUEST_SSL_SESSION_ID = "javax.servlet.request.ssl_session_id"; - public static final String SERVLET_REQUEST_CIPHER_SUITE = "javax.servlet.request.cipher_suite"; - - private final HttpServletRequest request; - private final HeaderFields headerFields; - private final Set<String> removedHeaders = new HashSet<>(); - private final Map<String, Object> context = new HashMap<>(); - private final Map<String, List<String>> parameters = new HashMap<>(); - private final long connectedAt; - - private URI uri; - private String remoteHostAddress; - private String remoteHostName; - private int remotePort; - - public ServletRequest(HttpServletRequest request, URI uri) { - super(request); - this.request = request; - - this.uri = uri; - - super.getParameterMap().forEach( - (key, values) -> parameters.put(key, Arrays.asList(values))); - - remoteHostAddress = request.getRemoteAddr(); - remoteHostName = request.getRemoteHost(); - remotePort = request.getRemotePort(); - connectedAt = getConnection((Request) request).getCreatedTimeStamp(); - - headerFields = new HeaderFields(); - Enumeration<String> parentHeaders = request.getHeaderNames(); - while (parentHeaders.hasMoreElements()) { - String name = parentHeaders.nextElement(); - Enumeration<String> values = request.getHeaders(name); - while (values.hasMoreElements()) { - headerFields.add(name, values.nextElement()); - } - } - } - - public HttpServletRequest getRequest() { - return request; - } - - @Override - public Map<String, List<String>> parameters() { - return parameters; - } - - /* We cannot just return the parameter map from the request, as the map - * may have been modified by the JDisc filters. */ - @Override - public Map<String, String[]> getParameterMap() { - Map<String, String[]> parameterMap = new HashMap<>(); - parameters().forEach( - (key, values) -> - parameterMap.put(key, values.toArray(new String[values.size()])) - ); - return ImmutableMap.copyOf(parameterMap); - } - - @Override - public String getParameter(String name) { - return parameters().containsKey(name) ? - parameters().get(name).get(0) : - null; - } - - @Override - public Enumeration<String> getParameterNames() { - return Collections.enumeration(parameters.keySet()); - } - - @Override - public String[] getParameterValues(String name) { - List<String> values = parameters().get(name); - return values != null ? - values.toArray(new String[values.size()]) : - null; - } - - @Override - public void copyHeaders(HeaderFields target) { - target.addAll(headerFields); - } - - @Override - public Enumeration<String> getHeaders(String name) { - if (removedHeaders.contains(name)) - return null; - - /* We don't need to merge headerFields and the servlet request's headers - * because setHeaders() replaces the old value. There is no 'addHeader(s)'. */ - List<String> headerFields = this.headerFields.get(name); - return headerFields == null || headerFields.isEmpty() ? - super.getHeaders(name) : - Collections.enumeration(headerFields); - } - - @Override - public String getHeader(String name) { - if (removedHeaders.contains(name)) - return null; - - String headerField = headerFields.getFirst(name); - return headerField != null ? - headerField : - super.getHeader(name); - } - - @Override - public Enumeration<String> getHeaderNames() { - Set<String> names = new HashSet<>(Collections.list(super.getHeaderNames())); - names.addAll(headerFields.keySet()); - names.removeAll(removedHeaders); - return Collections.enumeration(names); - } - - public void addHeader(String name, String value) { - headerFields.add(name, value); - removedHeaders.remove(name); - } - - public void setHeaders(String name, String value) { - headerFields.put(name, value); - removedHeaders.remove(name); - } - - public void setHeaders(String name, List<String> values) { - headerFields.put(name, values); - removedHeaders.remove(name); - } - - public void removeHeaders(String name) { - headerFields.remove(name); - removedHeaders.add(name); - } - - @Override - public URI getUri() { - return uri; - } - - public void setUri(URI uri) { - this.uri = uri; - } - - @Override - public HttpRequest.Version getVersion() { - String protocol = request.getProtocol(); - try { - return HttpRequest.Version.fromString(protocol); - } catch (NullPointerException | IllegalArgumentException e) { - throw new RuntimeException("Servlet request protocol '" + protocol + - "' could not be mapped to a JDisc http version.", e); - } - } - - @Override - public String getRemoteHostAddress() { - return remoteHostAddress; - } - - @Override - public String getRemoteHostName() { - return remoteHostName; - } - - @Override - public int getRemotePort() { - return remotePort; - } - - @Override - public void setRemoteAddress(SocketAddress remoteAddress) { - if (remoteAddress instanceof InetSocketAddress) { - remoteHostAddress = ((InetSocketAddress) remoteAddress).getAddress().getHostAddress(); - remoteHostName = ((InetSocketAddress) remoteAddress).getAddress().getHostName(); - remotePort = ((InetSocketAddress) remoteAddress).getPort(); - } else - throw new RuntimeException("Unknown SocketAddress class: " + remoteHostAddress.getClass().getName()); - - } - - @Override - public Map<String, Object> context() { - return context; - } - - @Override - public javax.servlet.http.Cookie[] getCookies() { - return decodeCookieHeader().stream(). - map(jdiscCookie -> new javax.servlet.http.Cookie(jdiscCookie.getName(), jdiscCookie.getValue())). - toArray(javax.servlet.http.Cookie[]::new); - } - - @Override - public List<Cookie> decodeCookieHeader() { - Enumeration<String> cookies = getHeaders(HttpHeaders.Names.COOKIE); - if (cookies == null) - return Collections.emptyList(); - - List<Cookie> ret = new LinkedList<>(); - while(cookies.hasMoreElements()) - ret.addAll(Cookie.fromCookieHeader(cookies.nextElement())); - - return ret; - } - - @Override - public void encodeCookieHeader(List<Cookie> cookies) { - setHeaders(HttpHeaders.Names.COOKIE, Cookie.toCookieHeader(cookies)); - } - - @Override - public long getConnectedAt(TimeUnit unit) { - return unit.convert(connectedAt, TimeUnit.MILLISECONDS); - } - - @Override - public Principal getUserPrincipal() { - // NOTE: The principal from the underlying servlet request is ignored. JDisc filters are the source-of-truth. - return (Principal) request.getAttribute(JDISC_REQUEST_PRINCIPAL); - } - - public void setUserPrincipal(Principal principal) { - request.setAttribute(JDISC_REQUEST_PRINCIPAL, principal); - } -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletResponse.java deleted file mode 100644 index 44a23c22b4a..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/ServletResponse.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.servlet; - -import com.yahoo.jdisc.HeaderFields; -import com.yahoo.jdisc.http.Cookie; -import com.yahoo.jdisc.http.HttpHeaders; - -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * JDisc wrapper to use a {@link javax.servlet.http.HttpServletResponse} - * with JDisc security filters. - */ -public class ServletResponse extends HttpServletResponseWrapper implements ServletOrJdiscHttpResponse { - - private final HttpServletResponse response; - private final Map<String, Object> context = new HashMap<>(); - - public ServletResponse(HttpServletResponse response) { - super(response); - this.response = response; - } - - public HttpServletResponse getResponse() { - return response; - } - - @Override - public int getStatus() { - return response.getStatus(); - } - - @Override - public Map<String, Object> context() { - return context; - } - - @Override - public void copyHeaders(HeaderFields target) { - response.getHeaderNames().forEach( header -> - target.add(header, new ArrayList<>(response.getHeaders(header))) - ); - } - - @Override - public List<Cookie> decodeSetCookieHeader() { - Collection<String> cookies = getHeaders(HttpHeaders.Names.SET_COOKIE); - if (cookies == null) { - return Collections.emptyList(); - } - List<Cookie> ret = new LinkedList<>(); - for (String cookie : cookies) { - ret.add(Cookie.fromSetCookieHeader(cookie)); - } - return ret; - } - -} diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/package-info.java b/container-core/src/main/java/com/yahoo/jdisc/http/servlet/package-info.java deleted file mode 100644 index 098506aa86f..00000000000 --- a/container-core/src/main/java/com/yahoo/jdisc/http/servlet/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -package com.yahoo.jdisc.http.servlet; - -import com.yahoo.osgi.annotation.ExportPackage; |