Created
March 19, 2019 01:03
-
-
Save magicsih/cd9fa8b96e58fa7a8f977c82ad7a8d5f to your computer and use it in GitHub Desktop.
HttpProxyServer with Jetty 9.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CustomProxyServlet extends ProxyServlet { | |
private final Map<String, FilterableHost> filterMap; | |
public CustomProxyServlet() { | |
this.filterMap = new HashMap<>(); | |
} | |
public CustomProxyServlet referHostFilterByUrl(String fromUrl, String toUrl) { | |
if(filterMap.containsKey(fromUrl)) { | |
filterMap.put(toUrl, filterMap.get(fromUrl)); | |
return this; | |
} else { | |
throw new IllegalStateException("can't find " + fromUrl + " in filterMap. you should put hostFilter for " + fromUrl + " first"); | |
} | |
} | |
public CustomProxyServlet addHostFilter(String url, FilterableHost filter) { | |
if(filterMap.containsKey(url) == false) { | |
filterMap.put(url, filter); | |
return this; | |
} else{ | |
throw new IllegalStateException("host url " + url + " already exists"); | |
} | |
} | |
@Override | |
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { | |
URL url = new URL(request.getRequestURL().toString()); // Extract host from URL | |
if(filterMap.containsKey(url.getHost())) { | |
final FilterableHost filterableHost = filterMap.get(url.getHost()); | |
if(filterableHost.canHandle(url)) { | |
final AsyncContext asyncContext = request.startAsync(); | |
// We do not timeout the continuation, but the proxy request | |
asyncContext.setTimeout(0); | |
filterableHost.process(request, response); | |
asyncContext.complete(); | |
} | |
} else { | |
super.service(request, response); | |
} | |
} | |
@Override | |
protected Response.Listener newProxyResponseListener(HttpServletRequest request, HttpServletResponse response) | |
{ | |
return new CustomProxyServletProxyResponseListener(request, response); | |
} | |
protected class CustomProxyServletProxyResponseListener extends Response.Listener.Adapter | |
{ | |
private final HttpServletRequest request; | |
private final HttpServletResponse response; | |
protected CustomProxyServletProxyResponseListener(HttpServletRequest request, HttpServletResponse response) | |
{ | |
this.request = request; | |
this.response = response; | |
} | |
@Override | |
public void onBegin(Response proxyResponse) | |
{ | |
response.setStatus(proxyResponse.getStatus()); | |
} | |
@Override | |
public void onHeaders(Response proxyResponse) | |
{ | |
onServerResponseHeaders(request, response, proxyResponse); | |
} | |
@Override | |
public void onContent(final Response proxyResponse, ByteBuffer content, final Callback callback) | |
{ | |
byte[] buffer; | |
int offset; | |
int length = content.remaining(); | |
if (content.hasArray()) | |
{ | |
buffer = content.array(); | |
offset = content.arrayOffset(); | |
} | |
else | |
{ | |
buffer = new byte[length]; | |
content.get(buffer); | |
offset = 0; | |
} | |
onResponseContent(request, response, proxyResponse, buffer, offset, length, new Callback.Nested(callback) | |
{ | |
@Override | |
public void failed(Throwable x) | |
{ | |
super.failed(x); | |
proxyResponse.abort(x); | |
} | |
}); | |
} | |
@Override | |
public void onComplete(Result result) | |
{ | |
if (result.isSucceeded()) | |
onProxyResponseSuccess(request, response, result.getResponse()); | |
else | |
onProxyResponseFailure(request, response, result.getResponse(), result.getFailure()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DefaultFilterableHost implements FilterableHost { | |
@Override | |
public boolean canHandle(URL url) { | |
return url.getPath().endsWith("/somepath"); | |
} | |
@Override | |
public void process(HttpServletRequest request, HttpServletResponse response) { | |
response.setStatus(HttpStatus.OK_200); | |
response.addHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.KEEP_ALIVE.asString()); | |
response.addHeader(HttpHeader.TRANSFER_ENCODING.asString(), HttpHeaderValue.CHUNKED.asString()); | |
response.getOutputStream().write("some your revised response"); | |
return response; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface FilterableHost { | |
boolean canHandle(URL url); | |
void process(final HttpServletRequest request, final HttpServletResponse response); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Server server = new Server(); | |
ServerConnector connector = new ServerConnector(server); | |
connector.setPort(8080); | |
server.addConnector(connector); | |
ConnectHandler proxy = new ConnectHandler(); | |
server.setHandler(proxy); | |
CustomProxyServlet customProxyServlet = new CustomProxyServlet(); | |
customProxyServlet.addHostFilter("maybe.somewhere.com", new DefaultFilterableHost()).referHostFilterByUrl("maybe.somewhere.com", "mightbe.somewhere.com"); | |
// Setup proxy servlet | |
ServletContextHandler context = new ServletContextHandler(proxy, "/", ServletContextHandler.SESSIONS); | |
ServletHolder proxyServlet = new ServletHolder(customProxyServlet); | |
proxyServlet.setInitParameter("maxThreads", "10"); | |
context.addServlet(proxyServlet, "/*"); | |
server.start(); | |
server.join(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment