I am using HttpURLConnection
along the lines of the following:
String strURL = "https://example.herokuapp.com";
Bitmap bmImage = null;
HttpURLConnection connection = null;
InputStream in = null;
showMessage(context.getString(R.string.message_preparing));
try {
int timeoutMS = 15000;
URL url = new URL(strURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setConnectTimeout(timeoutMS);
connection.setReadTimeout(timeoutMS);
connection.connect();
in = connection.getInputStream();
BitmapFactory.Options options = new BitmapFactory.Options();
bmImage = BitmapFactory.decodeStream(in, null, options);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bmImage;
This works just fine, with the url defined by strURL
returning a bmp image, and this being decoded ready for use by the above code.
But for one user in particular, although the code works fine to fetch the bmp image, at the server (a node.js server at heroku) it is apparent that a CONNECT
request is also being sent by their device. That request is rejected with a 503 response automatically, so it's not a problem as such, and the bmp is still sent to their device, but I'd like to know why those CONNECT
requests are being sent at all, and how to stop them. Surely there should be nothing but GET
requests?
I've tried this solution to what appears to be a similar problem, but it makes no difference for me.
Note that strURL
is to an https server, and I'm using HttpURLConnection
(not Https
) -- not sure if there is any significance in that.
I'm also not 100% sure the CONNECT
requests derive from the above calls, but they certainly happen around the same time as a GET
request that delivers the bmp. Maybe it could be generated by the OS somehow, outside of my code? Not sure.
In case it helps, an example log message from heroku, in response to one of the CONNECT
requests, is as follows:
Oct 27 14:14:25 example heroku/router: at=error code=H13 desc="Connection closed without response" method=CONNECT path="example.herokuapp.com:443" host=example.herokuapp.com request_id=353e623x-dec4-42x5-bcfb-452add02ecef fwd="111.22.333.4" dyno=web.1 connect=0ms service=1ms status=503 bytes=0
EDIT: it may also be of relevance that the device concerned actually makes two independent GET requests within a short time of each other (completely separate and legitimate requests), but there is only ever a single CONNECT request apparent (around the same time as the pair of GET requests). So it's not as if there is a CONNECT for each GET.
A URLConnection with support for HTTP-specific features. See the spec for details. Each HttpURLConnection instance is used to make a single request but the underlying network connection to the HTTP server may be transparently shared by other instances.
To answer your question, calling disconnect on the connection will disconnect the connection.
HttpsURLConnection extends HttpURLConnection with support for https-specific features. A URLConnection with support for HTTP-specific features.
The CONNECT
method can preface a request to an HTTP server (either a proxy server or an origin server), and it basically means:
"By the way, old chap, you wouldn't mind relaying this stuff I say 'verbatim' to the host/port I happen to mention, would you? No need to actually pay attention to what I'm saying, really."
Usually this would be an instruction to a proxy, to 'get out of the way', and let the requestor (which could be the user-agent OR another proxy) to talk directly to the upstream server.
It's a nice facility to have if there is an otherwise-uncooperative (perhaps outdated) proxy between you and an origin server. It's also handy if you're a hacker and would like a mis-configured origin server to blithely facilitate your entry into the internal network.
However, unless you have perfect knowledge of the network and 'know' that the is only ONE proxy in your path, you'll need to 'stack' the CONNECT header until you get a refusal.
For example:
CONNECT site.example.com 80 HTTP/1.1
CONNECT site.example.com 80 HTTP/1.1
GET /foo HTTP/1.1
Host: site.example.com
.... will either get you through 2 interfering, good-for-nothing, upstream proxies; OR get you through just the 1 that's actually there, and earn you a 503 from the origin-server ... whereupon you'll have to repeat your request with ONE FEWER CONNECT
preface-methods.
So that would account for the behaviour seen so far.
However, what isn't clear is WHO is ADDING THE CONNECT
PREFACE?! And why don't they like proxies?
It could be:
HttpUrlConnection
or HttpsUrlConnection
(used automatically by openConnection()
if the URL has an https://
scheme);CONNECT
is for)The full content of the CONNECT
method, and the source IP for the packet would be interesting. I'm betting on #2 though, and predict that you won't see the CONNECT
if you accessed the site via a http://
URL.
There is nothing which you can do about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With