lox / httpcache

An RFC7234 compliant golang http.Handler for caching HTTP responses
MIT License
264 stars 28 forks source link

Some content appears to cause panic #30

Open d-smith opened 8 years ago

d-smith commented 8 years ago

I've seen the following panic occur on retrieving context via the proxy, both in my own used of httpcache and via the cli sample (with modified listener port, e.g. 5000 instead of 80).

2016/08/11 14:16:55 [::1] "GET http://127.0.0.1:4000/notifications/recent HTTP/1.1" (OK) 32768 SKIP 131.157149ms

>> GET /notifications/recent HTTP/1.1
>> Host: localhost:8080
>> Accept: */*
>> User-Agent: curl/7.43.0

2016/08/11 14:16:56 GET /notifications/recent not in shared cache
2016/08/11 14:16:56 passing request upstream
2016/08/11 14:16:56 upstream responded headers in 129.992328ms
2016/08/11 14:16:56 resource is uncacheable

<< HTTP/1.1 200 OK
<< Cache-Control: no-store
<< Content-Type: application/atom+xml
<< Date: Thu, 11 Aug 2016 21:16:56 GMT
<< X-Cache: SKIP

2016/08/11 14:16:56 [::1] "GET http://127.0.0.1:4000/notifications/recent HTTP/1.1" (OK) 32768 SKIP 130.166404ms
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x1e231b]

goroutine 25 [running]:
panic(0x365f80, 0xc82000e0c0)
    /usr/local/go/src/runtime/panic.go:481 +0x3e6
bufio.(*Writer).Write(0xc82006a7c0, 0xc820190000, 0x59d9, 0x8000, 0x0, 0x0, 0x0)
    /usr/local/go/src/bufio/bufio.go:594 +0xcb
net/http.(*response).write(0xc82018e000, 0x59d9, 0xc820190000, 0x59d9, 0x8000, 0x0, 0x0, 0xc82012e301, 0x0, 0x0)
    /usr/local/go/src/net/http/server.go:1237 +0x1bf
net/http.(*response).Write(0xc82018e000, 0xc820190000, 0x59d9, 0x8000, 0x0, 0x0, 0x0)
    /usr/local/go/src/net/http/server.go:1209 +0x64
github.com/lox/httpcache/httplog.(*responseWriter).Write(0xc8200da210, 0xc820190000, 0x59d9, 0x8000, 0x59d9, 0x0, 0x0)
    /Users/a045103/goeventstore/src/github.com/lox/httpcache/httplog/log.go:38 +0xcb
github.com/lox/httpcache.(*responseStreamer).Write(0xc820071920, 0xc820190000, 0x59d9, 0x8000, 0x59d9, 0x0, 0x0)
    /Users/a045103/goeventstore/src/github.com/lox/httpcache/handler.go:558 +0x9b
io.copyBuffer(0x6bb128, 0xc820071920, 0x6bb150, 0xc82012e4c0, 0xc820190000, 0x8000, 0x8000, 0x8000, 0x0, 0x0)
    /usr/local/go/src/io/io.go:382 +0x2c9
io.CopyBuffer(0x6bb128, 0xc820071920, 0x6bb150, 0xc82012e4c0, 0x0, 0x0, 0x0, 0xc82006c8f8, 0x0, 0x0)
    /usr/local/go/src/io/io.go:361 +0xe1
net/http/httputil.(*ReverseProxy).copyResponse(0xc82006a4c0, 0x6bb128, 0xc820071920, 0x6bb150, 0xc82012e4c0)
    /usr/local/go/src/net/http/httputil/reverseproxy.go:265 +0x299
net/http/httputil.(*ReverseProxy).ServeHTTP(0xc82006a4c0, 0x1309ee0, 0xc820071920, 0xc8200ec2a0)
    /usr/local/go/src/net/http/httputil/reverseproxy.go:242 +0xe2a
github.com/lox/httpcache.(*Handler).passUpstream.func1(0xc820070fc0, 0xc820071920, 0xc82018e0d0)
    /Users/a045103/goeventstore/src/github.com/lox/httpcache/handler.go:254 +0x7c
created by github.com/lox/httpcache.(*Handler).passUpstream
    /Users/a045103/goeventstore/src/github.com/lox/httpcache/handler.go:256 +0x330
exit status 2

I cannot pin down exactly what it is about the content that is causing the crash. The same server runs without error for a long time, but then certain pages being served through the cache cause it to panic almost everytime (sometimes the first fetch works).

Note the content causing the crash is not cacheable - the Cache-Control header is set to no-store.

I've attached a sample that crashes the proxy. Note that I can retrieve the content directly via curl or in a browser without error.

curl.out.zip

Environment information:

go version
go version go1.6.2 darwin/amd64

go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH=""
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
dmitshur commented 8 years ago

As a general observation, this library (and any other solving this task) is a great fit for fuzzing with go-fuzz, it could find this issue and others like it.