diff options
author | Simone Bordet | 2015-04-21 10:16:10 +0000 |
---|---|---|
committer | Simone Bordet | 2015-04-21 10:16:10 +0000 |
commit | f73f2c22e3647c5a753a35d944f8608a9964fe2b (patch) | |
tree | b00785d2c9074f69d2c8266338100ac5124979a5 | |
parent | aa3c881eec519f5d9da7d85a910427b72fb9ad7b (diff) | |
download | org.eclipse.jetty.project-f73f2c22e3647c5a753a35d944f8608a9964fe2b.tar.gz org.eclipse.jetty.project-f73f2c22e3647c5a753a35d944f8608a9964fe2b.tar.xz org.eclipse.jetty.project-f73f2c22e3647c5a753a35d944f8608a9964fe2b.zip |
Moved TransparentDelegate to AbstractProxyServlet.
Added AsyncMiddleManServlet.Transparent.
4 files changed, 105 insertions, 71 deletions
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java index f908ca898f..944e3c2c03 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.proxy; import java.io.IOException; import java.net.InetAddress; +import java.net.URI; import java.net.UnknownHostException; import java.util.Collections; import java.util.Enumeration; @@ -32,6 +33,7 @@ import java.util.concurrent.TimeoutException; import javax.servlet.AsyncContext; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -610,4 +612,73 @@ public abstract class AbstractProxyServlet extends HttpServlet { return System.identityHashCode(clientRequest); } + + /** + * <p>Utility class that implement transparent proxy functionalities.</p> + * <p>Configuration parameters:</p> + * <ul> + * <li>{@code proxyTo} - a mandatory URI like http://host:80/context to which the request is proxied.</li> + * <li>{@code prefix} - an optional URI prefix that is stripped from the start of the forwarded URI.</li> + * </ul> + * <p>For example, if a request is received at "/foo/bar", the {@code proxyTo} parameter is + * "http://host:80/context" and the {@code prefix} parameter is "/foo", then the request would + * be proxied to "http://host:80/context/bar". + */ + protected static class TransparentDelegate + { + private final ProxyServlet proxyServlet; + private String _proxyTo; + private String _prefix; + + protected TransparentDelegate(ProxyServlet proxyServlet) + { + this.proxyServlet = proxyServlet; + } + + protected void init(ServletConfig config) throws ServletException + { + _proxyTo = config.getInitParameter("proxyTo"); + if (_proxyTo == null) + throw new UnavailableException("Init parameter 'proxyTo' is required."); + + String prefix = config.getInitParameter("prefix"); + if (prefix != null) + { + if (!prefix.startsWith("/")) + throw new UnavailableException("Init parameter 'prefix' must start with a '/'."); + _prefix = prefix; + } + + // Adjust prefix value to account for context path + String contextPath = config.getServletContext().getContextPath(); + _prefix = _prefix == null ? contextPath : (contextPath + _prefix); + + if (proxyServlet._log.isDebugEnabled()) + proxyServlet._log.debug(config.getServletName() + " @ " + _prefix + " to " + _proxyTo); + } + + protected String rewriteTarget(HttpServletRequest request) + { + String path = request.getRequestURI(); + if (!path.startsWith(_prefix)) + return null; + + StringBuilder uri = new StringBuilder(_proxyTo); + if (_proxyTo.endsWith("/")) + uri.setLength(uri.length() - 1); + String rest = path.substring(_prefix.length()); + if (!rest.startsWith("/")) + uri.append("/"); + uri.append(rest); + String query = request.getQueryString(); + if (query != null) + uri.append("?").append(query); + URI rewrittenURI = URI.create(uri.toString()).normalize(); + + if (!proxyServlet.validateDestination(rewrittenURI.getHost(), rewrittenURI.getPort())) + return null; + + return rewrittenURI.toString(); + } + } } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java index d8e0030a14..daad2fdb78 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java @@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit; import java.util.zip.GZIPOutputStream; import javax.servlet.AsyncContext; import javax.servlet.ReadListener; +import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; @@ -193,6 +194,29 @@ public class AsyncMiddleManServlet extends AbstractProxyServlet ((Destroyable)serverTransformer).destroy(); } + /** + * <p>Convenience extension of {@link AsyncMiddleManServlet} that offers transparent proxy functionalities.</p> + * + * @see TransparentDelegate + */ + public static class Transparent extends ProxyServlet + { + private final TransparentDelegate delegate = new TransparentDelegate(this); + + @Override + public void init(ServletConfig config) throws ServletException + { + super.init(config); + delegate.init(config); + } + + @Override + protected String rewriteTarget(HttpServletRequest request) + { + return delegate.rewriteTarget(request); + } + } + protected class ProxyReader extends IteratingCallback implements ReadListener { private final byte[] buffer = new byte[getHttpClient().getRequestBufferSize()]; @@ -745,5 +769,4 @@ public class AsyncMiddleManServlet extends AbstractProxyServlet return ByteBuffer.wrap(gzipBytes); } } - } 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 3e77b4f93e..e3f83b128e 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 @@ -95,6 +95,11 @@ public class AsyncProxyServlet extends ProxyServlet return new StreamWriter(request, proxyResponse); } + /** + * <p>Convenience extension of {@link AsyncProxyServlet} that offers transparent proxy functionalities.</p> + * + * @see TransparentDelegate + */ public static class Transparent extends AsyncProxyServlet { private final TransparentDelegate delegate = new TransparentDelegate(this); @@ -109,7 +114,7 @@ public class AsyncProxyServlet extends ProxyServlet @Override protected URI rewriteURI(HttpServletRequest request) { - return delegate.rewriteURI(request); + return URI.create(delegate.rewriteTarget(request)); } } 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 8df98cd255..bb30d8a361 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 @@ -27,7 +27,6 @@ import javax.servlet.AsyncContext; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; -import javax.servlet.UnavailableException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -228,15 +227,9 @@ public class ProxyServlet extends AbstractProxyServlet } /** - * This convenience extension to {@link ProxyServlet} configures the servlet as a transparent proxy. - * This servlet is configured with the following init parameters: - * <ul> - * <li>proxyTo - a mandatory URI like http://host:80/context to which the request is proxied.</li> - * <li>prefix - an optional URI prefix that is stripped from the start of the forwarded URI.</li> - * </ul> - * <p/> - * For example, if a request is received at "/foo/bar", the 'proxyTo' parameter is "http://host:80/context" - * and the 'prefix' parameter is "/foo", then the request would be proxied to "http://host:80/context/bar". + * <p>Convenience extension of {@link ProxyServlet} that offers transparent proxy functionalities.</p> + * + * @see TransparentDelegate */ public static class Transparent extends ProxyServlet { @@ -252,65 +245,7 @@ public class ProxyServlet extends AbstractProxyServlet @Override protected URI rewriteURI(HttpServletRequest request) { - return delegate.rewriteURI(request); - } - } - - protected static class TransparentDelegate - { - private final ProxyServlet proxyServlet; - private String _proxyTo; - private String _prefix; - - protected TransparentDelegate(ProxyServlet proxyServlet) - { - this.proxyServlet = proxyServlet; - } - - protected void init(ServletConfig config) throws ServletException - { - _proxyTo = config.getInitParameter("proxyTo"); - if (_proxyTo == null) - throw new UnavailableException("Init parameter 'proxyTo' is required."); - - String prefix = config.getInitParameter("prefix"); - if (prefix != null) - { - if (!prefix.startsWith("/")) - throw new UnavailableException("Init parameter 'prefix' must start with a '/'."); - _prefix = prefix; - } - - // Adjust prefix value to account for context path - String contextPath = config.getServletContext().getContextPath(); - _prefix = _prefix == null ? contextPath : (contextPath + _prefix); - - if (proxyServlet._log.isDebugEnabled()) - proxyServlet._log.debug(config.getServletName() + " @ " + _prefix + " to " + _proxyTo); - } - - protected URI rewriteURI(HttpServletRequest request) - { - String path = request.getRequestURI(); - if (!path.startsWith(_prefix)) - return null; - - StringBuilder uri = new StringBuilder(_proxyTo); - if (_proxyTo.endsWith("/")) - uri.setLength(uri.length() - 1); - String rest = path.substring(_prefix.length()); - if (!rest.startsWith("/")) - uri.append("/"); - uri.append(rest); - String query = request.getQueryString(); - if (query != null) - uri.append("?").append(query); - URI rewrittenURI = URI.create(uri.toString()).normalize(); - - if (!proxyServlet.validateDestination(rewrittenURI.getHost(), rewrittenURI.getPort())) - return null; - - return rewrittenURI; + return URI.create(delegate.rewriteTarget(request)); } } |