okhttp3 Version: 3.10.0
Device/Android Version:
vivo 1719;Android 7.1.2,level 25
Redmi Note 3;Android 8.1.0,level 27
SM-G570Y;Android 7.0,level 24
Crash Report:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.net.Proxy$Type java.net.Proxy.type()' on a null object reference
okhttp3.internal.http.RetryAndFollowUpInterceptor.okhttp3.Request followUpRequest(okhttp3.Response,okhttp3.Route)(SourceFile:282)
okhttp3.internal.http.RetryAndFollowUpInterceptor.okhttp3.Response intercept(okhttp3.Interceptor$Chain)(SourceFile:158)
okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request,okhttp3.internal.connection.StreamAllocation,okhttp3.internal.http.HttpCodec,okhttp3.internal.connection.RealConnection)(SourceFile:147)
okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request)(SourceFile:121)
okhttp3.RealCall.okhttp3.Response getResponseWithInterceptorChain()(SourceFile:200)
okhttp3.RealCall$AsyncCall.void execute()(SourceFile:147)
okhttp3.internal.NamedRunnable.void run()(SourceFile:32)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
java.lang.Thread.run(Thread.java:818)
the case almost is same like #3809,but I wonder why it returns null Proxy(eg below code shown) and how do solve it?
code fo resulting in crash.
private Request followUpRequest(Response userResponse, Route route) throws IOException {
.............
switch (responseCode) {
case HTTP_PROXY_AUTH:
Proxy selectedProxy = route != null
? route.proxy()
: client.proxy();
if (selectedProxy.type() != Proxy.Type.HTTP) {
throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
}
return client.proxyAuthenticator().authenticate(route, userResponse);
........
}
I meet this bug
I'm seeing this error too when registering a ProxySelector (e.g. builder.proxySelector(myProxySelector);). Registering a single proxy works fine.
Also #4191 is a duplicate
I think I'm also getting this. specifically, I'm getting an NPE when the selectedProxy is null (implying that route is not null but route.proxy() is, or client.proxy() is null)
The obvious fix is to
if (selectedProxy == null || selectedProxy.type() != Proxy.Type.HTTP)
but I can't work out how to write a test that triggers this, so I haven't made a pull-request.
The tests I found that fail if I cause this to exception every time are
OkUrlFactoryTest.originServerSends407()
URLConnectionTest.allAttributesSetInProxyAuthenticationCallbacks()
But I can't work out how to make either of them fail in a good way.
It might be nice to be more specific in OkUrlFactoryTest.originServerSends407() -
@Test public void originServerSends407() {
server.enqueue(new MockResponse().setResponseCode(407));
HttpURLConnection conn = factory.open(server.url("/").url());
try {
conn.getResponseCode();
fail();
} catch (IOException expected) {
assertTrue(expected.toString(), expected instanceof ProtocolException);
assertEquals(expected.getMessage(), "Received HTTP_PROXY_AUTH (407) code while not using proxy");
}
}
I was finally able to reproduce the error with a unit test. I think this is a kind of race condition, because I had to run the same request multiple times to trigger the bug, and it happens not always at the same iteration (especially when I stopped with breakpoints). Maybe something related to connection pooling?
The test consist in doing multiple requests with an HTTP proxy having basic auth:
https://github.com/henryju/okhttp/commit/4a523e05ae90f32744ab10b6ac80bec931b3055a
When not debugging, it always fails at the second iteration.
I believe this is now fixed.
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.net.Proxy$Type java.net.Proxy.type()' on a null object reference
at okhttp3.internal.http.RetryAndFollowUpInterceptor.followUpRequest(RetryAndFollowUpInterceptor.java:286)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:160)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:156)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
with 3.12.1. Is this going to be backported?
@mueller-ma can do.
https://github.com/square/okhttp/issues/4726
Most helpful comment
I meet this bug