diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java index cfa7a6607c5..124637560ee 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java @@ -22,11 +22,11 @@ import java.net.URI; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Request; @@ -104,7 +104,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent } @Override - protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) + protected void sendProxyRequest(HttpServletRequest request, HttpServletResponse proxyResponse, Request proxyRequest) { proxyRequest.attribute(REMOTE_ADDR_ATTRIBUTE, request.getRemoteAddr()); proxyRequest.attribute(REMOTE_PORT_ATTRIBUTE, String.valueOf(request.getRemotePort())); @@ -157,7 +157,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent proxyRequest.header(HttpHeader.COOKIE, builder.toString()); } - super.customizeProxyRequest(proxyRequest, request); + super.sendProxyRequest(request, proxyResponse, proxyRequest); } protected void customizeFastCGIHeaders(Request proxyRequest, HttpFields fastCGIHeaders) diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java index 079229fb008..a5923c7470d 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java @@ -19,13 +19,11 @@ package org.eclipse.jetty.fcgi.server.proxy; import java.io.IOException; -import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Collection; import java.util.Random; import java.util.concurrent.TimeUnit; - import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -85,9 +83,9 @@ public class FastCGIProxyServletTest FastCGIProxyServlet fcgiServlet = new FastCGIProxyServlet() { @Override - protected URI rewriteURI(HttpServletRequest request) + protected String rewriteTarget(HttpServletRequest request) { - return URI.create("http://localhost:" + fcgiConnector.getLocalPort() + servletPath + request.getServletPath()); + return "http://localhost:" + fcgiConnector.getLocalPort() + servletPath + request.getServletPath(); } }; ServletHolder fcgiServletHolder = new ServletHolder(fcgiServlet); diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java index dae7f03fe36..60b777a6e9d 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java @@ -19,10 +19,8 @@ package org.eclipse.jetty.proxy; import java.io.IOException; -import java.net.URI; import java.nio.ByteBuffer; import java.nio.channels.WritePendingException; - import javax.servlet.ReadListener; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -39,22 +37,27 @@ import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; +/** + *
Proxy servlet based on Servlet 3.1 async I/O.
+ * + * @see AsyncMiddleManServlet + */ public class AsyncProxyServlet extends ProxyServlet { private static final String WRITE_LISTENER_ATTRIBUTE = AsyncProxyServlet.class.getName() + ".writeListener"; @Override - protected ContentProvider proxyRequestContent(Request proxyRequest, HttpServletRequest request) throws IOException + protected ContentProvider proxyRequestContent(HttpServletRequest request, HttpServletResponse response, Request proxyRequest) throws IOException { ServletInputStream input = request.getInputStream(); DeferredContentProvider provider = new DeferredContentProvider(); - input.setReadListener(newReadListener(proxyRequest, request, provider)); + input.setReadListener(newReadListener(request, response, proxyRequest, provider)); return provider; } - protected ReadListener newReadListener(Request proxyRequest, HttpServletRequest request, DeferredContentProvider provider) + protected ReadListener newReadListener(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, DeferredContentProvider provider) { - return new StreamReader(proxyRequest, request, provider); + return new StreamReader(request, response, proxyRequest, provider); } @Override @@ -108,23 +111,25 @@ public class AsyncProxyServlet extends ProxyServlet } @Override - protected URI rewriteURI(HttpServletRequest request) + protected String rewriteTarget(HttpServletRequest clientRequest) { - return delegate.rewriteURI(request); + return delegate.rewriteTarget(clientRequest); } } protected class StreamReader extends IteratingCallback implements ReadListener { private final byte[] buffer = new byte[getHttpClient().getRequestBufferSize()]; - private final Request proxyRequest; private final HttpServletRequest request; + private final HttpServletResponse response; + private final Request proxyRequest; private final DeferredContentProvider provider; - protected StreamReader(Request proxyRequest, HttpServletRequest request, DeferredContentProvider provider) + protected StreamReader(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, DeferredContentProvider provider) { - this.proxyRequest = proxyRequest; this.request = request; + this.response = response; + this.proxyRequest = proxyRequest; this.provider = provider; } @@ -145,7 +150,7 @@ public class AsyncProxyServlet extends ProxyServlet @Override public void onError(Throwable t) { - onClientRequestFailure(proxyRequest, request, t); + onClientRequestFailure(request, proxyRequest, response, t); } @Override @@ -165,7 +170,7 @@ public class AsyncProxyServlet extends ProxyServlet { if (_log.isDebugEnabled()) _log.debug("{} proxying content to upstream: {} bytes", requestId, read); - onRequestContent(proxyRequest, request, provider, buffer, 0, read, this); + onRequestContent(request, proxyRequest, provider, buffer, 0, read, this); return Action.SCHEDULED; } } @@ -184,7 +189,7 @@ public class AsyncProxyServlet extends ProxyServlet } } - protected void onRequestContent(Request proxyRequest, HttpServletRequest request, DeferredContentProvider provider, byte[] buffer, int offset, int length, Callback callback) + protected void onRequestContent(HttpServletRequest request, Request proxyRequest, DeferredContentProvider provider, byte[] buffer, int offset, int length, Callback callback) { provider.offer(ByteBuffer.wrap(buffer, offset, length), callback); } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java index f1a664c8bad..5332a49d0da 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java @@ -26,12 +26,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; - import javax.servlet.ServletException; import javax.servlet.UnavailableException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.util.URIUtil; public class BalancerServlet extends ProxyServlet @@ -130,7 +130,7 @@ public class BalancerServlet extends ProxyServlet } @Override - protected URI rewriteURI(HttpServletRequest request) + protected String rewriteTarget(HttpServletRequest request) { BalancerMember balancerMember = selectBalancerMember(request); if (_log.isDebugEnabled()) @@ -139,7 +139,7 @@ public class BalancerServlet extends ProxyServlet String query = request.getQueryString(); if (query != null) path += "?" + query; - return URI.create(balancerMember.getProxyTo() + "/" + path).normalize(); + return URI.create(balancerMember.getProxyTo() + "/" + path).normalize().toString(); } private BalancerMember selectBalancerMember(HttpServletRequest request) @@ -215,7 +215,7 @@ public class BalancerServlet extends ProxyServlet } @Override - protected String filterResponseHeader(HttpServletRequest request, String headerName, String headerValue) + protected String filterServerResponseHeader(HttpServletRequest request, Response serverResponse, String headerName, String headerValue) { if (_proxyPassReverse && REVERSE_PROXY_HEADERS.contains(headerName)) { diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java index de1c244379e..4c5c8187362 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java @@ -23,7 +23,6 @@ import java.io.InputStream; import java.net.URI; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; - import javax.servlet.AsyncContext; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; @@ -42,25 +41,21 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.util.Callback; /** - * Asynchronous ProxyServlet. - * - * Forwards requests to another server either as a standard web reverse proxy - * (as defined by RFC2616) or as a transparent reverse proxy. - * - * To facilitate JMX monitoring, the {@link HttpClient} instance is set as context attribute, - * prefixed with the servlet's name and exposed by the mechanism provided by - * {@link ServletContext#setAttribute(String, Object)}. - * - * The following init parameters may be used to configure the servlet: + *Proxy servlet based on Servlet 3.0 asynchronous request/response.
+ *Forwards requests to another server either as a standard web reverse proxy + * (as defined by RFC2616) or as a transparent reverse proxy.
+ *To facilitate JMX monitoring, the {@link HttpClient} instance is set as + * context attribute, prefixed with the servlet's name and exposed by the + * mechanism provided by {@link ServletContext#setAttribute(String, Object)}.
+ *The following init parameters may be used to configure the servlet:
*In addition, see {@link #createHttpClient()} for init parameters used to configure + * the {@link HttpClient} instance.
* * @see ConnectHandler */ @@ -71,7 +66,7 @@ public class ProxyServlet extends AbstractProxyServlet { final int requestId = getRequestId(request); - URI rewrittenURI = rewriteURI(request); + String rewrittenTarget = rewriteTarget(request); if (_log.isDebugEnabled()) { @@ -79,20 +74,20 @@ public class ProxyServlet extends AbstractProxyServlet if (request.getQueryString() != null) uri.append("?").append(request.getQueryString()); if (_log.isDebugEnabled()) - _log.debug("{} rewriting: {} -> {}", requestId, uri, rewrittenURI); + _log.debug("{} rewriting: {} -> {}", requestId, uri, rewrittenTarget); } - if (rewrittenURI == null) + if (rewrittenTarget == null) { - onRewriteFailed(request, response); + onProxyRewriteFailed(request, response); return; } - final Request proxyRequest = getHttpClient().newRequest(rewrittenURI) + final Request proxyRequest = getHttpClient().newRequest(rewrittenTarget) .method(request.getMethod()) .version(HttpVersion.fromString(request.getProtocol())); - copyHeaders(request, proxyRequest); + copyRequestHeaders(request, proxyRequest); addProxyHeaders(request, proxyRequest); @@ -102,25 +97,14 @@ public class ProxyServlet extends AbstractProxyServlet proxyRequest.timeout(getTimeout(), TimeUnit.MILLISECONDS); if (hasContent(request)) - proxyRequest.content(proxyRequestContent(proxyRequest, request)); - - customizeProxyRequest(proxyRequest, request); + proxyRequest.content(proxyRequestContent(request, response, proxyRequest)); sendProxyRequest(request, response, proxyRequest); } - /** - * @deprecated use {@link #copyRequestHeaders(HttpServletRequest, Request)} instead - */ - @Deprecated - protected void copyHeaders(HttpServletRequest clientRequest, Request proxyRequest) + protected ContentProvider proxyRequestContent(HttpServletRequest request, HttpServletResponse response, Request proxyRequest) throws IOException { - copyRequestHeaders(clientRequest, proxyRequest); - } - - protected ContentProvider proxyRequestContent(final Request proxyRequest, final HttpServletRequest request) throws IOException - { - return new ProxyInputStreamContentProvider(proxyRequest, request, request.getInputStream()); + return new ProxyInputStreamContentProvider(request, response, proxyRequest, request.getInputStream()); } protected Response.Listener newProxyResponseListener(HttpServletRequest request, HttpServletResponse response) @@ -128,38 +112,6 @@ public class ProxyServlet extends AbstractProxyServlet return new ProxyResponseListener(request, response); } - protected void onClientRequestFailure(Request proxyRequest, HttpServletRequest request, Throwable failure) - { - if (_log.isDebugEnabled()) - _log.debug(getRequestId(request) + " client request failure", failure); - proxyRequest.abort(failure); - } - - /** - * @deprecated use {@link #onProxyRewriteFailed(HttpServletRequest, HttpServletResponse)} - */ - @Deprecated - protected void onRewriteFailed(HttpServletRequest request, HttpServletResponse response) throws IOException - { - onProxyRewriteFailed(request, response); - } - - /** - * @deprecated use {@link #onServerResponseHeaders(HttpServletRequest, HttpServletResponse, Response)} - */ - @Deprecated - protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse) - { - onServerResponseHeaders(request, response, proxyResponse); - } - - // TODO: remove in Jetty 9.3, only here for backward compatibility. - @Override - protected String filterServerResponseHeader(HttpServletRequest clientRequest, Response serverResponse, String headerName, String headerValue) - { - return filterResponseHeader(clientRequest, headerName, headerValue); - } - protected void onResponseContent(HttpServletRequest request, HttpServletResponse response, Response proxyResponse, byte[] buffer, int offset, int length, Callback callback) { try @@ -175,59 +127,6 @@ public class ProxyServlet extends AbstractProxyServlet } } - /** - * @deprecated Use {@link #onProxyResponseSuccess(HttpServletRequest, HttpServletResponse, Response)} - */ - @Deprecated - protected void onResponseSuccess(HttpServletRequest request, HttpServletResponse response, Response proxyResponse) - { - onProxyResponseSuccess(request, response, proxyResponse); - } - - /** - * @deprecated Use {@link #onProxyResponseFailure(HttpServletRequest, HttpServletResponse, Response, Throwable)} - */ - @Deprecated - protected void onResponseFailure(HttpServletRequest request, HttpServletResponse response, Response proxyResponse, Throwable failure) - { - onProxyResponseFailure(request, response, proxyResponse, failure); - } - - /** - * @deprecated use {@link #rewriteTarget(HttpServletRequest)} - */ - @Deprecated - protected URI rewriteURI(HttpServletRequest request) - { - String newTarget = rewriteTarget(request); - return newTarget == null ? null : URI.create(newTarget); - } - - /** - * @deprecated use {@link #sendProxyRequest(HttpServletRequest, HttpServletResponse, Request)} - */ - @Deprecated - protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) - { - } - - /** - * Extension point for remote server response header filtering. - * The default implementation returns the header value as is. - * If null is returned, this header won't be forwarded back to the client. - * - * @param headerName the header name - * @param headerValue the header value - * @param request the request to proxy - * @return filteredHeaderValue the new header value - * @deprecated use {@link #filterServerResponseHeader(HttpServletRequest, Response, String, String)} instead - */ - @Deprecated - protected String filterResponseHeader(HttpServletRequest request, String headerName, String headerValue) - { - return headerValue; - } - /** * This convenience extension to {@link ProxyServlet} configures the servlet as a transparent proxy. * This servlet is configured with the following init parameters: @@ -251,9 +150,9 @@ public class ProxyServlet extends AbstractProxyServlet } @Override - protected URI rewriteURI(HttpServletRequest request) + protected String rewriteTarget(HttpServletRequest request) { - return delegate.rewriteURI(request); + return delegate.rewriteTarget(request); } } @@ -290,7 +189,7 @@ public class ProxyServlet extends AbstractProxyServlet proxyServlet._log.debug(config.getServletName() + " @ " + _prefix + " to " + _proxyTo); } - protected URI rewriteURI(HttpServletRequest request) + protected String rewriteTarget(HttpServletRequest request) { String path = request.getRequestURI(); if (!path.startsWith(_prefix)) @@ -311,7 +210,7 @@ public class ProxyServlet extends AbstractProxyServlet if (!proxyServlet.validateDestination(rewrittenURI.getHost(), rewrittenURI.getPort())) return null; - return rewrittenURI; + return rewrittenURI.toString(); } } @@ -335,7 +234,7 @@ public class ProxyServlet extends AbstractProxyServlet @Override public void onHeaders(Response proxyResponse) { - onResponseHeaders(request, response, proxyResponse); + onServerResponseHeaders(request, response, proxyResponse); } @Override @@ -377,9 +276,9 @@ public class ProxyServlet extends AbstractProxyServlet public void onComplete(Result result) { if (result.isSucceeded()) - onResponseSuccess(request, response, result.getResponse()); + onProxyResponseSuccess(request, response, result.getResponse()); else - onResponseFailure(request, response, result.getResponse(), result.getFailure()); + onProxyResponseFailure(request, response, result.getResponse(), result.getFailure()); if (_log.isDebugEnabled()) _log.debug("{} proxying complete", getRequestId(request)); } @@ -387,14 +286,16 @@ public class ProxyServlet extends AbstractProxyServlet protected class ProxyInputStreamContentProvider extends InputStreamContentProvider { + private final HttpServletResponse response; private final Request proxyRequest; private final HttpServletRequest request; - protected ProxyInputStreamContentProvider(Request proxyRequest, HttpServletRequest request, InputStream input) + protected ProxyInputStreamContentProvider(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, InputStream input) { super(input); - this.proxyRequest = proxyRequest; this.request = request; + this.response = response; + this.proxyRequest = proxyRequest; } @Override @@ -408,10 +309,10 @@ public class ProxyServlet extends AbstractProxyServlet { if (_log.isDebugEnabled()) _log.debug("{} proxying content to upstream: {} bytes", getRequestId(request), length); - return onRequestContent(proxyRequest, request, buffer, offset, length); + return onRequestContent(request, proxyRequest, buffer, offset, length); } - protected ByteBuffer onRequestContent(Request proxyRequest, final HttpServletRequest request, byte[] buffer, int offset, int length) + protected ByteBuffer onRequestContent(HttpServletRequest request, Request proxyRequest, byte[] buffer, int offset, int length) { return super.onRead(buffer, offset, length); } @@ -419,7 +320,7 @@ public class ProxyServlet extends AbstractProxyServlet @Override protected void onReadFailure(Throwable failure) { - onClientRequestFailure(proxyRequest, request, failure); + onClientRequestFailure(request, proxyRequest, response, failure); } } } diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java index cd0f0edabf0..2af96671d4a 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java @@ -30,7 +30,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -263,7 +262,7 @@ public class ProxyServletFailureTest proxyServlet = new AsyncProxyServlet() { @Override - protected ContentProvider proxyRequestContent(Request proxyRequest, HttpServletRequest request) throws IOException + protected ContentProvider proxyRequestContent(HttpServletRequest request, HttpServletResponse response, Request proxyRequest) throws IOException { return new DeferredContentProvider() { @@ -282,7 +281,7 @@ public class ProxyServletFailureTest proxyServlet = new ProxyServlet() { @Override - protected ContentProvider proxyRequestContent(Request proxyRequest, HttpServletRequest request) throws IOException + protected ContentProvider proxyRequestContent(HttpServletRequest request, HttpServletResponse response, Request proxyRequest) throws IOException { return new BytesContentProvider(content) { @@ -412,9 +411,4 @@ public class ProxyServletFailureTest ((StdErrLog)Log.getLogger(ServletHandler.class)).setHideStacks(false); } } - - private interface Function