koush/AndroidAsync — pull request #296 by bakks (2014-12-12 23:40:00+00:00)
Title: Fix accepted responses to CONNECT query

Hello @koush!

This pull request improves how responses are handled when using a proxy over HTTPS. The gist is that AndroidAsync sends a `CONNECT` request to initialize the proxy and throws an exception if the response does not return exactly `200`. The spec which defines how to use `CONNECT` ([available here](https://www.ietf.org/rfc/rfc2817.txt)) say the following:

```
5.3 Establishing a Tunnel with CONNECT

Any successful (2xx) response to a CONNECT request indicates that the
proxy has established a connection to the requested host and port,
and has switched to tunneling the current connection to that server
connection.

It may be the case that the proxy itself can only reach the requested
origin server through another proxy. In this case, the first proxy
SHOULD make a CONNECT request of that next proxy, requesting a tunnel
to the authority. A proxy MUST NOT respond with any 2xx status code
unless it has either a direct or tunnel connection established to the
authority.

An origin server which receives a CONNECT request for itself MAY
respond with a 2xx status code to indicate that a connection is
established.

If at any point either one of the peers gets disconnected, any
outstanding data that came from that peer will be passed to the other
one, and after that also the other connection will be terminated by
the proxy. If there is outstanding data to that peer undelivered,
that data will be discarded.
```

The way I read that, it is valid to receive a response code other than `200` and still move forward with the connection. Thus, AndroidAsync is handling this case incorrectly.

We discovered this because we've been receiving feedback from users that our Android app is broken when used on a specific 4G telecom network in Europe (I'll provide more details when we confirm exactly whats happening). Our theory is that this telco returns a non-200 2xx code in response to `CONNECT` requests, thus throwing an exception in AndroidAsync and preventing connection from moving ahead. We're testing out this fix on our forked branch now with users of the telco mentioned above.

Can you confirm our understanding of this issue and either merge the fix or provide one of your own? I would bet that other app developers who use AndroidAsync are also having issues when their apps are used on this telco (its a large network).

Note: We've attempted to re-use existing code for parsing the status code, so we made `RawHeaders` public to do so. Perhaps this isn't the best way, open to suggestions. Happy to provide other details as well.