title: HTTP CONNECT method with Android
body: <p>I want to extend an existing Android app which sets up a http connection to a remote device which it sends commands to and receives values from.</p>
  
  <p>The feature consists of a tunneled connection via a custom proxy server that has been set up. I have the http header format given which should make the proxy server create and provide a tunnel for my app.</p>
  
  <pre><code>CONNECT &lt;some id&gt;.&lt;target ip&gt;:80 HTTP/1.1
  Host: &lt;proxy ip&gt;:443
  Authorization: basic &lt;base64 encoded auth string&gt;
  
  # Here beginns the payload for the target device. It could be whatever.
  GET / HTTP/1.1
  Host: 127.0.0.1:80</code></pre>
  
  <p>The app uses the Apache HttpClient library to handle it's connections, and I would like to integrate with that. This is not mandatory, however.<br>
  The authorization is standard conform basic auth.</p>
  
  <p>I have trouble implementing this because it is not clear to me how the <code>HttpClient</code> is intended to be used for such behaviour.
  There is no <code>CONNECT</code> method in the library, only <code>GET</code>, <code>POST</code> and so on. I figured this would then be managed by the proxy settings of the <code>HttpClient</code> instance.<br>
  The problem here is that the request line is not standard, since the <code>CONNECT</code> line contains an id which the custom proxy then would parse and interpret.</p>
  
  <p>I now would like to know if there is any intended method to implement this using the Apache HttpClient and what it would look like with this sample data given, or if I have to implement my own method for this. And if so, which interface (there are a few that would sound reasonable to inherit from) it should implement.</p>
  
  <p>Any explanation, snippet or pointer would be appreciated.</p>
  
  <p><strong>UPDATE</strong>:
  I now have a small snippet set up, without Android. Just plain Java and Apache HttpClient. I still think the <code>Host</code> mismatch in the request is a problem, since I can't manage to establish a connection.</p>
  
  <pre><code>final HttpClient httpClient = new DefaultHttpClient();
  
  // Set proxy
  HttpHost proxy = new HttpHost (deviceId + "." + "proxy ip", 443, "https");
  httpClient.getParams().setParameter (ConnRoutePNames.DEFAULT_PROXY, proxy);
  
  final HttpGet httpGet = new HttpGet("http://" + "target device ip");
  httpGet.addHeader ("Authorization", "Basic" + 
      Base64.encodeBase64String((username + ":" + password).getBytes()));
  // Trying to overvrite the host in the header containing the device Id
  httpGet.setHeader("Host", "proxy ip");
  
  System.out.println("Sending request..");
  try {
      final HttpResponse httpResponse = httpClient.execute (httpGet);
      final InputStream inputStream = httpResponse.getEntity ().getContent ();
      final InputStreamReader inputStreamReader = 
          new InputStreamReader(inputStream, "ISO-8859-1");
  
      final BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
  
      final StringBuilder stringBuilder = new StringBuilder ();
      String bufferedStrChunk = null;
  
      while ((bufferedStrChunk = bufferedReader.readLine ()) != null) {
          stringBuilder.append (bufferedStrChunk);
      }
  
      System.out.println("Received String: " + stringBuilder.toString());
  }
  catch (final ClientProtocolException exception) {
      System.out.println("ClientProtocolException");
      exception.printStackTrace();
  }
  catch (final IOException exception) {
      System.out.println("IOException");
      exception.
  }
  </code></pre>
  
  <p>This looks fairly good to me in the way of "it could actually work".
  Anyways, I receive the following log and trace:</p>
  
  <pre><code>Sending request..
  2015/03/03 13:16:16:199 CET [DEBUG] ClientParamsStack - 'http.route.default-proxy': https://"device id"."proxy ip":443
  2015/03/03 13:16:16:207 CET [DEBUG] SingleClientConnManager - Get connection for route HttpRoute[{}-&gt;https://"device id"."proxy ip":443-&gt;http://"target device ip"]
  2015/03/03 13:16:16:549 CET [DEBUG] ClientParamsStack - 'http.tcp.nodelay': true
  2015/03/03 13:16:16:549 CET [DEBUG] ClientParamsStack - 'http.socket.buffer-size': 8192
  2015/03/03 13:16:16:563 CET [DEBUG] DefaultClientConnection - Connection shut down
  2015/03/03 13:16:16:563 CET [DEBUG] SingleClientConnManager - Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@bc6a08
  Exception in thread "main" java.lang.IllegalStateException: Unable to establish route.
  planned = HttpRoute[{}-&gt;https://"device id"."proxy ip":443-&gt;http://"target device ip"]
  current = HttpRoute[{s}-&gt;https://"device id"."proxy ip":443-&gt;http://"target device ip"]
      at org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:672)
      at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:385)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
      at run.main(run.java:71)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
  </code></pre>
  
  <p>Any ideas what goes wrong?</p>
  
  <p><strong>UPDATE</strong>: As stated <a href="https://stackoverflow.com/questions/11347635/apache-httpcomponents-org-apache-http-client-clientprotocolexception">here</a>, this might be due to a bug when redirecting. The fact that the target does redirect tells me, that I do not have reached the correct target, implying that the <code>Host</code> parameter may have not been overwritten.</p>