httpcache icon indicating copy to clipboard operation
httpcache copied to clipboard

Transfer-Encoding: Chunked returns only the first chunk

Open jfesler opened this issue 8 years ago • 3 comments

Thanks for your work with httpcache - no small effort!

I have found that the Transfer-Encoding: chunked behavior is broken. When sending a request through httpcache.NewHandler(httpcche.NewMemoryCache()) with httputil.NewSingleHostReverseProxy, that the cache returns only the first chunk.

Without the cache, httputil.NewSingleHostReverseProxy properly fetches chunked content fine.

An example of chunked output from the web server I'm testing with:

Jasons-MacBook-Pro:gateway-test jfesler$ telnet localhost 4000
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /cached/hello/ HTTP/1.1
Host: localhost:3000

HTTP/1.1 200 OK
Content-Type: text/plain
Date: Tue, 13 Sep 2016 23:45:55 GMT
Transfer-Encoding: chunked

2f
Counter(i=0); time is now 2016-09-13- 16:45:55

2f
Counter(i=1); time is now 2016-09-13- 16:45:56

2f
Counter(i=2); time is now 2016-09-13- 16:45:57

2f
Counter(i=3); time is now 2016-09-13- 16:45:58

2f
Counter(i=4); time is now 2016-09-13- 16:45:59

2f
Counter(i=5); time is now 2016-09-13- 16:46:00

2f
Counter(i=6); time is now 2016-09-13- 16:46:01

2f
Counter(i=7); time is now 2016-09-13- 16:46:02

2f
Counter(i=8); time is now 2016-09-13- 16:46:03

2f
Counter(i=9); time is now 2016-09-13- 16:46:04

0


And with curl, hitting that proxy directly, it works fine as well:

Jasons-MacBook-Pro:gateway-test jfesler$ curl http://localhost:4000/counter/
Counter(i=0); time is now 2016-09-13- 16:52:56
Counter(i=1); time is now 2016-09-13- 16:52:57
Counter(i=2); time is now 2016-09-13- 16:52:58
Counter(i=3); time is now 2016-09-13- 16:52:59
Counter(i=4); time is now 2016-09-13- 16:53:00
Counter(i=5); time is now 2016-09-13- 16:53:01
Counter(i=6); time is now 2016-09-13- 16:53:02
Counter(i=7); time is now 2016-09-13- 16:53:03
Counter(i=8); time is now 2016-09-13- 16:53:04
Counter(i=9); time is now 2016-09-13- 16:53:05

~~On the bright side, the cache at least doesn't serve me the same chunk#1 as a cache hit; it instead calls it a miss and goes to the back end again on the subsequent query.~~

Unfortunately, I can't provide code samples, due to my current choice of employer. Which means I can't offer a PR either :-( For that I truly apologize.

jfesler avatar Sep 14 '16 00:09 jfesler

Thanks for the report, I'll investigate this. I've been trying to get a redesign of the internals of httpcache going, which should address some of these issues.

lox avatar Sep 14 '16 02:09 lox

~~"On the bright side, the cache at least doesn't serve me the same chunk#1 as a cache hit; it instead calls it a miss and goes to the back end again on the subsequent query."~~

Ignore that bit; not relevant. Digging deeper into your code, my response is not giving enough of a reason to be isCacheable.

The chunking issue remains :-)

jfesler avatar Sep 14 '16 16:09 jfesler

Narrowed down a bit more.

Chunked works fine if isCacheable(). Chunked fails if not isCacheable(); instead returns the first chunk, as a miss.

jfesler avatar Sep 14 '16 16:09 jfesler