Hi Eric,
do I understand correctly that you are using apache inbuilt digest
implementation?
and about your issue - wouldn't help "consuming" returned response?
(reading the entity).
Regards,
Pavel
On 10/2/12 1:20 AM, Erik Hennum wrote:
> Hi, Jersey Folk:
>
> We're using Jersey Client 1.13 with Apache Http Client 4.
>
> We've noticed that when doing a PUT of StreamingOutput with Digest
> authentication,
> the connection that receives the initial 401 challenge is never released.
>
> The problem seems to reside in
>
> com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle()
>
> If I add an abort() call immediately before the happy path return on
> line 186
>
> if (r.getStatus() == 401 && !request.isAborted()) {
> request.abort();
> }
>
> that change seems to fix the problem. (Notice the highlighted
> difference between
> the before and after debug streams after my signature.)
>
> That change does pollute handle() with authentication concerns (but then,
> preemptiveBasicAuth also has that issue).
>
> Is there a way to solve this problem without modifying the
> ApacheHttpClient4Handler source (or a better modification to the source)?
>
>
> Thanks in advance,
>
>
> Erik Hennum
>
> BEFORE:
>
> [DEBUG] ThreadSafeClientConnManager - Get connection:
> HttpRoute[{}->http://localhost:8012], timeout = 0
> [DEBUG] ConnPoolByRoute - [HttpRoute[{}->http://localhost:8012]] total
> kept alive: 0, total issued: 0, total allocated: 0 out of 20
> [DEBUG] ConnPoolByRoute - No free connections
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Available capacity: 50 out of 50
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Creating new connection
> [HttpRoute[{}->http://localhost:8012]]
> [DEBUG] DefaultClientConnectionOperator - Connecting to
> localhost/127.0.0.1:8012 <http://127.0.0.1:8012>
> [DEBUG] RequestAddCookies - CookieSpec selected: best-match
> [DEBUG] RequestAuthCache - Auth cache not set in the context
> [DEBUG] DefaultHttpClient - Attempt 1 to execute request
> [DEBUG] DefaultClientConnection - Sending request: PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> Content-Type: application/xml
> [DEBUG] headers - >> Transfer-Encoding: chunked
> [DEBUG] headers - >> Host: localhost:8012
> [DEBUG] headers - >> Connection: Keep-Alive
> 1 * Client out-bound request
> 1 > PUT
> http://localhost:8012/v1/documents?category=content&uri=/test/testWrite1.xml
> 1 > Content-Type: application/xml
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> [DEBUG] DefaultClientConnection - Receiving response: HTTP/1.1 401
> Unauthorized
> [DEBUG] headers - << HTTP/1.1 401 Unauthorized
> [DEBUG] headers - << WWW-Authenticate: Digest realm="public",
> qop="auth", nonce="8d8766cd4a59ec4e42f98661ae2cfb7b",
> opaque="e05d2c24fc33c472"
> [DEBUG] headers - << Content-type: application/xml
> [DEBUG] headers - << Server: MarkLogic
> [DEBUG] headers - << Content-Length: 211
> [DEBUG] headers - << Connection: close
> [DEBUG] DefaultHttpClient - Target requested authentication
> [DEBUG] DefaultTargetAuthenticationHandler - Authentication schemes in
> the order of preference: [negotiate, NTLM, Digest, Basic]
> [DEBUG] DefaultTargetAuthenticationHandler - Challenge for negotiate
> authentication scheme not available
> [DEBUG] DefaultTargetAuthenticationHandler - Challenge for NTLM
> authentication scheme not available
> [DEBUG] DefaultTargetAuthenticationHandler - Digest authentication
> scheme selected
> [DEBUG] DefaultHttpClient - Authorization challenge processed
> [DEBUG] DefaultHttpClient - Authentication scope: DIGEST
> 'public'_at_localhost:8012
> [DEBUG] DefaultHttpClient - Credentials not found
> VVVVVVVVVVVVVVV
> [DEBUG] ThreadSafeClientConnManager - Get connection:
> HttpRoute[{}->http://localhost:8012], timeout = 0
> [DEBUG] ConnPoolByRoute - [HttpRoute[{}->http://localhost:8012]] total
> kept alive: 0, total issued: 1, total allocated: 1 out of 20
> [DEBUG] ConnPoolByRoute - No free connections
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Available capacity: 49 out of 50
> [HttpRoute[{}->http://localhost:8012]][null]
> ^^^^^^^^^^^^^^^^^^^^^^
> [DEBUG] ConnPoolByRoute - Creating new connection
> [HttpRoute[{}->http://localhost:8012]]
> [DEBUG] DefaultClientConnectionOperator - Connecting to
> localhost/127.0.0.1:8012 <http://127.0.0.1:8012>
> [DEBUG] RequestAddCookies - CookieSpec selected: best-match
> [DEBUG] RequestAuthCache - Auth cache not set in the context
> [DEBUG] DefaultHttpClient - Attempt 1 to execute request
> [DEBUG] DefaultClientConnection - Sending request: PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> Content-Type: application/xml
> [DEBUG] headers - >> Authorization: Digest
> username="rest-writer",realm="public",nonce="8d8766cd4a59ec4e42f98661ae2cfb7b",opaque="e05d2c24fc33c472",qop=auth,uri="/v1/documents",cnonce="45eba063",nc=00000001,response="18f8c3417cca89a3bc6e62a40e2743cd"
> [DEBUG] headers - >> Transfer-Encoding: chunked
> [DEBUG] headers - >> Host: localhost:8012
> [DEBUG] headers - >> Connection: Keep-Alive
> 1 * Client out-bound request
> 1 > PUT
> http://localhost:8012/v1/documents?category=content&uri=/test/testWrite1.xml
> 1 > Content-Type: application/xml
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> [DEBUG] DefaultClientConnection - Receiving response: HTTP/1.1 204
> Content Updated
> [DEBUG] headers - << HTTP/1.1 204 Content Updated
> [DEBUG] headers - << Server: MarkLogic
> [DEBUG] headers - << Content-Length: 0
> [DEBUG] headers - << Connection: close
>
>
> AFTER:
>
> [DEBUG] ThreadSafeClientConnManager - Get connection:
> HttpRoute[{}->http://localhost:8012], timeout = 0
> [DEBUG] ConnPoolByRoute - [HttpRoute[{}->http://localhost:8012]] total
> kept alive: 0, total issued: 0, total allocated: 0 out of 20
> [DEBUG] ConnPoolByRoute - No free connections
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Available capacity: 50 out of 50
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Creating new connection
> [HttpRoute[{}->http://localhost:8012]]
> [DEBUG] DefaultClientConnectionOperator - Connecting to
> localhost/127.0.0.1:8012 <http://127.0.0.1:8012>
> [DEBUG] RequestAddCookies - CookieSpec selected: best-match
> [DEBUG] RequestAuthCache - Auth cache not set in the context
> [DEBUG] DefaultHttpClient - Attempt 1 to execute request
> [DEBUG] DefaultClientConnection - Sending request: PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> Content-Type: application/xml
> [DEBUG] headers - >> Transfer-Encoding: chunked
> [DEBUG] headers - >> Host: localhost:8012
> [DEBUG] headers - >> Connection: Keep-Alive
> 1 * Client out-bound request
> 1 > PUT
> http://localhost:8012/v1/documents?category=content&uri=/test/testWrite1.xml
> 1 > Content-Type: application/xml
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> [DEBUG] DefaultClientConnection - Receiving response: HTTP/1.1 401
> Unauthorized
> [DEBUG] headers - << HTTP/1.1 401 Unauthorized
> [DEBUG] headers - << WWW-Authenticate: Digest realm="public",
> qop="auth", nonce="87f4589fadfe84bcd45fa63de82fb78a",
> opaque="d6cc3857b5f552ec"
> [DEBUG] headers - << Content-type: application/xml
> [DEBUG] headers - << Server: MarkLogic
> [DEBUG] headers - << Content-Length: 211
> [DEBUG] headers - << Connection: close
> [DEBUG] DefaultHttpClient - Target requested authentication
> [DEBUG] DefaultTargetAuthenticationHandler - Authentication schemes in
> the order of preference: [negotiate, NTLM, Digest, Basic]
> [DEBUG] DefaultTargetAuthenticationHandler - Challenge for negotiate
> authentication scheme not available
> [DEBUG] DefaultTargetAuthenticationHandler - Challenge for NTLM
> authentication scheme not available
> [DEBUG] DefaultTargetAuthenticationHandler - Digest authentication
> scheme selected
> [DEBUG] DefaultHttpClient - Authorization challenge processed
> [DEBUG] DefaultHttpClient - Authentication scope: DIGEST
> 'public'_at_localhost:8012
> [DEBUG] DefaultHttpClient - Credentials not found
> VVVVVVVVVVVVVVV
> [DEBUG] DefaultClientConnection - Connection shut down
> [DEBUG] ThreadSafeClientConnManager - Released connection is not reusable.
> [DEBUG] ConnPoolByRoute - Releasing connection
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Notifying no-one, there are no waiting threads
> [DEBUG] ThreadSafeClientConnManager - Get connection:
> HttpRoute[{}->http://localhost:8012], timeout = 0
> [DEBUG] ConnPoolByRoute - [HttpRoute[{}->http://localhost:8012]] total
> kept alive: 0, total issued: 0, total allocated: 0 out of 20
> [DEBUG] ConnPoolByRoute - No free connections
> [HttpRoute[{}->http://localhost:8012]][null]
> [DEBUG] ConnPoolByRoute - Available capacity: 50 out of 50
> [HttpRoute[{}->http://localhost:8012]][null]
> ^^^^^^^^^^^^^^^^^^^^^^
> [DEBUG] ConnPoolByRoute - Creating new connection
> [HttpRoute[{}->http://localhost:8012]]
> [DEBUG] DefaultClientConnectionOperator - Connecting to
> localhost/127.0.0.1:8012 <http://127.0.0.1:8012>
> [DEBUG] RequestAddCookies - CookieSpec selected: best-match
> [DEBUG] RequestAuthCache - Auth cache not set in the context
> [DEBUG] DefaultHttpClient - Attempt 1 to execute request
> [DEBUG] DefaultClientConnection - Sending request: PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> PUT
> /v1/documents?category=content&uri=/test/testWrite1.xml HTTP/1.1
> [DEBUG] headers - >> Content-Type: application/xml
> [DEBUG] headers - >> Authorization: Digest
> username="rest-writer",realm="public",nonce="87f4589fadfe84bcd45fa63de82fb78a",opaque="d6cc3857b5f552ec",qop=auth,uri="/v1/documents",cnonce="2ef03f7b",nc=00000001,response="b9724b850a75a38d34e2ef9b51371780"
> [DEBUG] headers - >> Transfer-Encoding: chunked
> [DEBUG] headers - >> Host: localhost:8012
> [DEBUG] headers - >> Connection: Keep-Alive
> 1 * Client out-bound request
> 1 > PUT
> http://localhost:8012/v1/documents?category=content&uri=/test/testWrite1.xml
> 1 > Content-Type: application/xml
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> <?xml version="1.0" encoding="UTF-8"?>
> <root foo="bar" xml:lang="en"><child/>mixed</root>
> [DEBUG] DefaultClientConnection - Receiving response: HTTP/1.1 204
> Content Updated
> [DEBUG] headers - << HTTP/1.1 204 Content Updated
> [DEBUG] headers - << Server: MarkLogic
> [DEBUG] headers - << Content-Length: 0
> [DEBUG] headers - << Connection: close
>