Description
HttpClient instances constructed through CachingHttpClients use absolute URIs when validating a resource.
I'm constructing a caching HttpClient and requesting a resource that has a Cache-Control allowing for caching. Subsequent requests are served from the cache. On the first attempt to validate it, the absolute URI is passed rather than the relative URI that appeared in the original request.
As with HTTPCLIENT-1447, this absolute URI is forbidden by the current HTTP RFC (RFC 7230, 5.3.1). (The spec also states that this only causes problems for a non-compliant server. I have one of those.)
The example here uses Cache-control: max-age=0 to force immediate validation.
GET /resource HTTP/1.1 Host: localhost:50732 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.3.5 (java 1.5) Accept-Encoding: gzip,deflate Via: 1.1 localhost (Apache-HttpClient/4.3.5 (cache))
HTTP/1.1 200 OK Cache-control: max-age=0 Content-type: text/plain Content-length: 16 Date: Thu, 14 Aug 2014 09:17:46 GMT XXXXXXXXXXXXXXXX
GET http://localhost:50732/resource HTTP/1.1 Host: localhost:50732 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.3.5 (java 1.5) Accept-Encoding: gzip,deflate Via: 1.1 localhost (Apache-HttpClient/4.3.5 (cache))
HTTP/1.1 200 OK Cache-control: max-age=0 Content-type: text/plain Content-length: 16 Date: Thu, 14 Aug 2014 09:17:46 GMT XXXXXXXXXXXXXXXX
The rewriteRequestURI method in ProtocolExec would fix this, but this is added after decorateMainExec adds the caching layer, so the CachingExec's backend, used for validation, doesn't include that processing step.
As a simple fix, renaming decorateMainExec to decorateProtocolExec in CachingHttpClientBuilder ensures that the underlying backend carries out this transformation.
However, this means that the validation requests will also participate in content decoding and cookie handling. A better fix may be to move rewriteRequestURI into MainClientExec.