Hi Simone,
Please consider the following case.
1. Makes two bases, one represents the server, the other represents proxy.
The proxy is using the below ProxyServlet.
public class ProxyServlet extends AsyncProxyServlet {
private static final long serialVersionUID = 7496746677269293638L;
@Override
protected HttpClient createHttpClient() throws ServletException {
ServletConfig config = getServletConfig();
// Setup SSL context for this client.
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true);
HttpClient client = new HttpClient(sslContextFactory);
// Redirects must be proxied as is, not followed.
client.setFollowRedirects(false);
// Must not store cookies, otherwise cookies of different clients will
// mix.
client.setCookieStore(new HttpCookieStore.Empty());
Executor executor;
String value = config.getInitParameter("maxThreads");
if (value == null || "-".equals(value)) {
executor = (Executor) getServletContext()
.getAttribute("org.eclipse.jetty.server.Executor");
if (executor == null)
throw new IllegalStateException("No server executor for proxy");
} else {
QueuedThreadPool qtp = new QueuedThreadPool(
Integer.parseInt(value));
String servletName = config.getServletName();
int dot = servletName.lastIndexOf('.');
if (dot >= 0)
servletName = servletName.substring(dot + 1);
qtp.setName(servletName);
executor = qtp;
}
client.setExecutor(executor);
value = config.getInitParameter("maxConnections");
if (value == null)
value = "256";
client.setMaxConnectionsPerDestination(Integer.parseInt(value));
value = config.getInitParameter("idleTimeout");
if (value == null)
value = "30000";
client.setIdleTimeout(Long.parseLong(value));
value = config.getInitParameter("timeout");
if (value == null)
value = "60000";
setTimeout(Long.parseLong(value));
value = config.getInitParameter("requestBufferSize");
if (value != null)
client.setRequestBufferSize(Integer.parseInt(value));
value = config.getInitParameter("responseBufferSize");
if (value != null)
client.setResponseBufferSize(Integer.parseInt(value));
try {
client.start();
// Content must not be decoded, otherwise the client gets confused.
client.getContentDecoderFactories().clear();
// No protocol handlers, pass everything to the client.
client.getProtocolHandlers().clear();
return client;
} catch (Exception x) {
throw new ServletException(x);
}
}
@Override
protected String rewriteTarget(HttpServletRequest clientRequest) {
String uri = ...;
System.out.println("uri=" + uriParam);
return uri;
}
}
2. Started the server
java -jar /path/to/start.jar jetty.http.port=8000 jetty.ssl.port=8001
...
2016-04-25 11:21:59.801:INFO:oejs.ServerConnector:main: Started ServerConnector@1f554b06{HTTP/1.1,[http/1.1]}{
0.0.0.0:8000}
...
2016-04-25 11:22:00.012:INFO:oejs.ServerConnector:main: Started ServerConnector@105fece7{SSL,[ssl, http/1.1]}{
0.0.0.0:8001}
...
3. Started the proxy
java -jar /path/to/start.jar jetty.http.port=9000 jetty.ssl.port=9001
....
2016-04-25 11:22:08.985:INFO:oejs.ServerConnector:main: Started ServerConnector@31d55d45{HTTP/1.1,[http/1.1]}{
0.0.0.0:9000}
....
2016-04-25 11:22:09.005:INFO:oejs.ServerConnector:main: Started ServerConnector@1a7662bd{SSL,[ssl, http/1.1]}{
0.0.0.0:9001}
....
4. The following is the test class,
public class JettyProxyTest {
// Accesses HTTPS without Proxy
private static void test1() throws Exception, InterruptedException,
TimeoutException, ExecutionException {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(someSSLContext);
HttpClient client = new HttpClient(sslContextFactory);
client.start();
String url = "" href="https://localhost:8001/proxy">https://localhost:8001/proxy";
ContentResponse response = client.newRequest(url).send();
System.out.println(response.getStatus());
client.stop();
}
// Accesses HTTP with Proxy
private static void test2() throws Exception, InterruptedException,
TimeoutException, ExecutionException {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(someSSLContext);
HttpClient client = new HttpClient(sslContextFactory);
client.getProxyConfiguration().getProxies().add(
new HttpProxy(new Origin.Address("localhost", 9000), false));
client.start();
String url = "" href="http://localhost:8000/proxy">http://localhost:8000/proxy";
ContentResponse response = client.newRequest(url).send();
System.out.println(response.getStatus());
client.stop();
}
// Accesses HTTPS with Proxy
private static void test3() throws Exception, InterruptedException,
TimeoutException, ExecutionException {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(someSSLContext);
HttpClient client = new HttpClient(sslContextFactory);
client.getProxyConfiguration().getProxies().add(
new HttpProxy(new Origin.Address("localhost", 9000), false));
client.start();
String url = "" href="https://localhost:8001/proxy">https://localhost:8001/proxy";
ContentResponse response = client.newRequest(url).send();
System.out.println(response.getStatus());
client.stop();
}
public static void main(String[] args) throws Exception {
test1();
test2();
test3();
}
}
The test1 and test2 works well, and test2 throw the below exception:
2016-04-25 11:29:33.232:WARN:oejh.HttpParser:HttpClient@522764626-32: Illegal character 0xA in state=RESPONSE_VERSION for buffer DirectByteBuffer@3805e09d[p=180,l=502,c=16384,r=322]={HTTP/1.1 404 Not ...314)\r\n\r\n<html>\n<<<<head>\n<meta http.../body>\n</html>\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
2016-04-25 11:29:33.234:WARN:oejh.HttpParser:HttpClient@522764626-32: bad HTTP parsed: 400 Illegal character 0xA for HttpReceiverOverHTTP@7d0769f9(rsp=IDLE,failure=null)[HttpParser{s=RESPONSE_VERSION,0 of -1}]
2016-04-25 11:29:33.235:WARN:oejh.HttpParser:HttpClient@522764626-35: Illegal character 0xA in state=RESPONSE_VERSION for buffer DirectByteBuffer@2c56785c[p=180,l=502,c=16384,r=322]={HTTP/1.1 404 Not ...314)\r\n\r\n<html>\n<<<<head>\n<meta http.../body>\n</html>\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
Exception in thread "main" 2016-04-25 11:29:33.236:WARN:oejh.HttpParser:HttpClient@522764626-35: bad HTTP parsed: 400 Illegal character 0xA for HttpReceiverOverHTTP@6954e3b2(rsp=IDLE,failure=null)[HttpParser{s=RESPONSE_VERSION,0 of -1}]
java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: Received HttpResponse[HTTP/1.1 404 Not Found]@26ae132c for HttpRequest[CONNECT localhost:8001 HTTP/1.1]@2869e989
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118)
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101)
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:653)
at JettyProxyTest.test3(JettyProxyTest.java:60)
at JettyProxyTest.main(JettyProxyTest.java:69)
Caused by: org.eclipse.jetty.client.HttpResponseException: Received HttpResponse[HTTP/1.1 404 Not Found]@26ae132c for HttpRequest[CONNECT localhost:8001 HTTP/1.1]@2869e989
at org.eclipse.jetty.client.HttpProxy$HttpProxyClientConnectionFactory$ProxyPromise.lambda$tunnel$1(HttpProxy.java:171)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:185)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:456)
at org.eclipse.jetty.client.HttpReceiver.responseSuccess(HttpReceiver.java:403)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.messageComplete(HttpReceiverOverHTTP.java:268)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1277)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.parse(HttpReceiverOverHTTP.java:158)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:119)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:69)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:90)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:114)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:246)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:156)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
at java.lang.Thread.run(Thread.java:745)
Thanks!