atom feed1 message in org.apache.hc.httpclient-usersRe: Proxy chaining
FromSent OnAttachments
galengtJun 5, 2014 6:01 pm 
Subject:Re: Proxy chaining
From:galengt (
Date:Jun 5, 2014 6:01:33 pm

Hi Ryan and Oleg,

Thanks for this thread, has been very helpful. Like Ryan I have 4.2 locally and have overwritten createTunnelToProxy, but I think I am missing something.

Execution looks like this: DefaultHttpClient client = new DefaultHttpClient(); HttpRoutePlanner routePlanner = new TwoHopRoutePlanner(host, port, host2, port2); client.setRoutePlanner(routePlanner); client.execute(get)

TwoHopRoutePlanner is super simple, implements HttpRoutePlanner and has the override below: @Override public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { HttpHost proxy1 = new HttpHost(this.host1, this.port1); HttpHost proxy2 = new HttpHost(this.host2, this.port2); HttpHost[] proxies = new HttpHost[] {proxy1, proxy2}; return new HttpRoute(target, null, proxies, false, TunnelType.TUNNELLED, LayerType.PLAIN); } }

Here is my attempt at createTunnelToProxy:

protected boolean createTunnelToProxy(HttpRoute route, int hop, HttpContext context) throws HttpException, IOException { //final HttpHost proxy = route.getProxyHost(); final HttpHost target = route.getTargetHost(); HttpResponse response = null; for (int i = 0; i < route.getHopCount(); i++) { final HttpHost proxy = route.getHopTarget(i); if (!this.managedConn.isOpen()) {, context, this.params); }

final HttpRequest connect = createConnectRequest(route, context); connect.setParams(this.params);

// Populate the execution context context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy); context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn); context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);

this.requestExec.preProcess(connect, this.httpProcessor, context);

System.out.println("CONNECT Issued: " + "host:" + proxy.getHostName() + " port: " + proxy.getPort() + " scheme: " + proxy.getSchemeName()); response = this.requestExec.execute(connect, this.managedConn, context);

response.setParams(this.params); this.requestExec.postProcess(response, this.httpProcessor, context);

final int status = response.getStatusLine().getStatusCode(); System.out.println("CONNECT status code: " + status); if (status < 200) { throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine()); } } final int status = response.getStatusLine().getStatusCode(); if (status > 299) {

// Buffer response content final HttpEntity entity = response.getEntity(); if (entity != null) { response.setEntity(new BufferedHttpEntity(entity)); }

this.managedConn.close(); throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response); }

this.managedConn.markReusable(); return false; }

I added a couple printlns in there, here is an example output: CONNECT Issued: host: port: 8080 scheme: http CONNECT status code: 200 CONNECT Issued: host: port: 8080 scheme: http CONNECT status code: 405 CONNECT Issued: port: -1 scheme: http CONNECT status code: 405

The body comes back with an error that includes: "The requested method CONNECT is not allowed for the URL /index.html". I am guessing I missed something in createTunnelToProxy, any help would be appreciated!