HTTPS proxy is not supported
See original GitHub issueWhat kind of issue is this?
-
Question. This issue tracker is not the place for questions. If you want to ask how to do something, or to understand why something isn’t working the way you expect it to, use Stack Overflow. https://stackoverflow.com/questions/tagged/okhttp
-
Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests get fixed. Here’s an example: https://gist.github.com/swankjesse/981fcae102f513eb13ed
-
Feature Request. Start by telling us what problem you’re trying to solve. Often a solution already exists! Don’t send pull requests to implement new features without first getting our support. Sometimes we leave features out on purpose to keep the project small.
Hello, I tried to use okhttp to connect through an https proxy, but I wasn’t able to. Here is a reproduction:
curl --proxy-insecure -x https://myproxy:3129 https://httpbin.org/get
works like a charm, instead:
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder();
final Integer proxyPort = 3129;
final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
okHttpClientBuilder.proxy(proxy);
okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
if (proxyHost.equalsIgnoreCase(s)) {
return true;
}
return OkHostnameVerifier.INSTANCE.verify(s, sslSession);
}
});
okHttpClientBuilder.build().newCall(new Request.Builder().url("https://httpbin.org/get").build()).execute();
fails with the following stacktrace:
Exception in thread "main" java.io.IOException: unexpected end of stream on null
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:205)
at okhttp3.internal.connection.RealConnection.createTunnel(RealConnection.java:323)
at okhttp3.internal.connection.RealConnection.connectTunnel(RealConnection.java:197)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:145)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
at okhttp3.RealCall.execute(RealCall.java:69)
at Test.main(Test.java:34)
Caused by: java.io.EOFException: \n not found: limit=0 content=…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:226)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
... 20 more
I digged a bit into the code and I think that the issue is that here, if the proxy is HTTP, it is used socketFactory
, while there should be an additional check whether the proxy is running HTTPS or not (and if so, sslSocketFactory
should be used instead).
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:36 (8 by maintainers)
Top GitHub Comments
@lordyavin you can connect to an HTTPS origin resource via an HTTP proxy - which is the normal way to do it, the HTTP proxy becomes a dumb TCP/IP tunnel and the TLS handshake happens between the client and the origin server.
This issue is about connecting to both the origin server and the proxy server over HTTPS. So the data stream ends up double encrypted - you have an encrypted stream between the client and the proxy server, and that is tunnelling an encrypted stream between the client and the origin server.
It’s a pretty unusual thing to want to do - all it really additionally protects is the
CONNECT
request from the client to the proxy, so it stops a man in the middle knowing which origin server it is you want to proxy to. TheCONNECT
request could include aProxy-Authorization
header which would be worth protecting.This might lead you in the right direction:
In practice there’s a bunch more work due to features like ALPN and SNI, and having to verify that the proxy server you connect to is the one who’s certificate chain is trusted.