Comments (14)
This is correct, the caching prevents the code from being used on multiple threads. The code is definitely not thread safe. If you are using multiple threads, then you would need to create either a synchronous wrapper(which would probably defeat the purpose), or someone needs to rework the code to be thread safe.
from okhttp-digest.
Is this true if I just use DigestAuthenticator directly? I notice that the authenticate method is synchronized. While not ideal from a performance perspective as it might create a contention point, at least it could mean it is thread-safe. Do you know off-hand whether I should still be concerned if I bypass DispatchingAuthenticator and use DigestAuthenticator directly?
from okhttp-digest.
Looks like I'm getting the same warning and failed requests when I just use DigestAuthenticator directly.
from okhttp-digest.
I think the quick fix would be to synchronize authenticateWithState
in DigestAuthenticator
. Unfortunately I don't have a practical test case where I can easily replicate the problem. If you are willing to provide a unit test, then this would probably be not too hard to fix in a better way.
from okhttp-digest.
BTW, I checked your change in java-client-api and I think that the Dispatcher should be reasonably safe. I dont believe that it causes and problems in a multi threaded environment.
from okhttp-digest.
I added a unit test to demonstrate some issues in a multi-threaded environment. This probably doesn't show all the issues, and I'm not even sure it shows the one I'm encountering. It just takes the existing digest unit tests and runs them multi-threaded. I loosened up a few of the tests so they don't expect nc to be 0000001 when it is likely higher when multi-threaded. That way those tests can pass so we can focus on the ones that fail because of a problem in the core code.
from okhttp-digest.
The test is misleading as you are calling all test methods (which share the same instance variables) at the same time. This is not really a realistic scenario. All this shows is that the tests were not written with concurrency in mind (nor would this be useful). We would need a test that attempts a similar approach as you are using in your production code. However, I am not sure how we can get that to work without having a mockhttpserver in place that responds somewhat reasonably.
Is there a way where we can create a test (at least to analyze the problem better) which simulates your app behaviour? I.e. multithreaded download requests. I do have a server at hand that I could configure and run the tests against.
from okhttp-digest.
I think it's important to note that I'm creating an API that interfaces with a database. So I don't have one production environment, I have an API used in hundreds of production envs. This API could be used in any production env: J2EE app servers, Spring Boot, Hadoop, Storm, Android, etc. The Stress test where I first duplicated the issues is overly complicated to share. You may be right that the interaction of instance variables in the test I shared is distracting in the example I gave. I'll try to find time to create another test.
from okhttp-digest.
Ok, I removed all but the necessary shared instance variables. I believe it makes sense to share the Route and DigestAuthenticator as those are likely to be shared in an application. The DigestAuthenticator, in particular, is the thing we need to support multi-threaded invocation. It will be used by one OkHttpClient instance which will be accessed by many concurrent threads which need to authenticate different users simultaneously. While the OkHttpClient uses an underlying ConnectionPool to support these high-volume multi-threaded requests, I'm thinking that doesn't affect the use of a single DigestAuthenticator.
from okhttp-digest.
Hi, thanks a lot for your work. I see that most of the tests fail because their expectations are no longer met. The expectations dont factor in that the nonce count will change. Therefore, I fear the tests dont really show the problem.
Would it be possible for you to share logs of a configured network level HttpLoggingInterceptor
maybe I can set up a test here that recreates a somewhat similar situation as you are experiencing.
from okhttp-digest.
Ok, you're right. I knew those would distract so I tried to loosen all those match assertions, but it looks like I missed two. I've pushed an update so those won't distract. I believe the following error is not a test bug. In other words, the behavior of DigestAuthenticator is different when run in a multi-threaded env vs single-threaded env. Here's what I'm seeing on STDERR:
Jul 11, 2017 9:26:47 AM okhttp3.internal.platform.Platform log
WARNING: previous digest authentication with same nonce failed, returning null
Test testAuthenticate_withWrongPassword_shouldNotRepeat failed under testMultithreadedAuthenticate:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest$1.run(DigestAuthenticatorTest.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AssertionError:
Expected: is null
but: was <Request{method=GET, url=http://www.google.com/, tag=Request{method=GET, url=http://www.google.com/, tag=null}}>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.Assert.assertThat(Assert.java:923)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest.testAuthenticate_withWrongPassword_shouldNotRepeat(DigestAuthenticatorTest.java:216)
... 8 more
I get similar errors sometimes from testAuthenticate__withProxy__shouldWork and testAuthenticate_withDifferentNonce_shouldNotRetry. I don't always see the "WARNING: previous digest authentication with same nonce failed, returning null" although I was seeing that pretty consistently in the output from my failing stress test.
from okhttp-digest.
In case it helps, here are two examples of when the others fail:
Test testAuthenticate_withDifferentNonce_shouldNotRetry failed under testMultithreadedAuthenticate:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest$1.run(DigestAuthenticatorTest.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AssertionError:
Expected: is null
but: was <Request{method=GET, url=http://www.google.com/, tag=Request{method=GET, url=http://www.google.com/, tag=null}}>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.Assert.assertThat(Assert.java:923)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest.testAuthenticate_withDifferentNonce_shouldNotRetry(DigestAuthenticatorTest.java:241)
... 8 more
Test testAuthenticate__withProxy__shouldWork failed under testMultithreadedAuthenticate:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest$1.run(DigestAuthenticatorTest.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AssertionError:
Expected: a string matching the pattern 'Digest username="user1", realm="myrealm", nonce="NnjGCdMhBQA=8ede771f94b593e46e5d0dd10b68313226c133f4", uri="/", response="[0-9a-f]+", qop=auth, nc=00000001, cnonce="[0-9a-f]+", algorithm=MD5'
but: was "Digest username=\"user1\", realm=\"myrealm\", nonce=\"NnjGCdMhBQA=8ede771f94b593e46e5d0dd10b68313226c133f4\", uri=\"/\", response=\"0222dac12825f93e1697e8cb34cb5ece\", qop=auth, nc=00000002, cnonce=\"0f9866728b5cd1fc\", algorithm=MD5"
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.Assert.assertThat(Assert.java:923)
at com.burgstaller.okhttp.digest.DigestAuthenticatorTest.testAuthenticate__withProxy__shouldWork(DigestAuthenticatorTest.java:98)
... 8 more
from okhttp-digest.
Ok, it appears that the problem lies in the shared "parameters" variable. IIUC, that parameter was intended to be used for caching, but isn't actually since authenticateWithState goes ahead and calls createDigestHeader anyway for every request. I'm not 100% positive about this change, but all the unit tests pass when I run "gradle test". Could you take a look?
from okhttp-digest.
I re-ran my stress tests today with this change in place, and I don't see the issues anymore. So I'm submitting PR #35 for your review.
from okhttp-digest.
Related Issues (20)
- IncompatibleClassChangeError using digest access authentication and latest OkHttp HOT 4
- Explain how to run ProxyAuthenticationManualTest HOT 4
- java.lang.NoSuchMethodError with okhttp 4.3.0 HOT 1
- Error code 401 HOT 5
- Authentication Cache Concurrent Modification Exception HOT 3
- Still getting 401 after Authentication Challenge HOT 8
- Http proxy with digest auth, error when server sends HTTP-301 redirect HOT 2
- How to use UTF-8 in basic and digest access authentication HOT 7
- Failed to resolve: com.burgstaller:okhttp-digest:1.19 HOT 5
- How to use OkHttp 3.12.x which supports API level 9+ in okhttp-digest HOT 3
- Copyright missing HOT 1
- Jcenter closing in May HOT 5
- Latest 1.x version is not in Maven Central HOT 2
- How can I Set Realm and Client Nonce in ADVANCED of Authorization Digest Auth HOT 3
- Send initial request with authentication header HOT 6
- java.lang.NoSuchFieldError HOT 17
- After putting app idle for some time it gives 401 issue for authorised request HOT 6
- Authentication fails if the site being accessed during proxy setup is HTTPS and digest authentication is used. HOT 4
- Are the `com.burgstaller:okhttp-digest` artifacts hosted on any public repo? HOT 5
- org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is **java.lang.IncompatibleClassChangeError**: Expected static method okhttp3.internal.http.RequestLine.requestPath(Lokhttp3/HttpUrl;)Ljava/lang/String; HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from okhttp-digest.