caddyserver / cache-handler

Distributed HTTP caching module for Caddy
Apache License 2.0
264 stars 21 forks source link

http2 error occurred when upstream response body is empty #104

Closed imlonghao closed 5 days ago

imlonghao commented 2 weeks ago

Hello,

Today, I'm trying to configure caddy with cache, hoping to caching some files from upstream. So I ended up in this repo.

I noticed http2 error will occur when upstream response body is empty.

> GET / HTTP/2
> Host: cache.esd.cc:8443
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 404
< alt-svc: h3=":443"; ma=2592000
< cache-control:
< cache-status: Souin; fwd=uri-miss; detail=UPSTREAM-ERROR-OR-EMPTY-RESPONSE; key=GET-https-cache.esd.cc:8443-/
* Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: []
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Connection #0 to host cache.esd.cc left intact
curl: (92) Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: []

Meanwhile, here is the response from the upstream directly.

> GET / HTTP/2
> Host: dev.esd.cc
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 404
< alt-svc: h3=":443"; ma=2592000
< server: Caddy
< content-length: 0
< date: Mon, 30 Sep 2024 15:35:44 GMT
<
* Connection #0 to host dev.esd.cc left intact

To reproduce, you may use the following Docker container and caddy config.

Dockerfile

FROM caddy:2.8.4-builder AS builder
RUN xcaddy build --with github.com/caddyserver/cache-handler

FROM caddy:2.8.4
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

Caddyfile

{
    cache
}

https://cache.esd.cc {
    cache
    tls internal
    reverse_proxy https://dev.esd.cc {
        header_up Host dev.esd.cc
    }
}

https://nocache.esd.cc {
    tls internal
        reverse_proxy https://dev.esd.cc {
        header_up Host dev.esd.cc
    }
}

In this case, https://cache.esd.cc only works in http1.1, https://nocache.esd.cc works in both http1.1 and http2.

By the way, is it normal that cache-control has empty header value?

Thanks.

darkweak commented 5 days ago

Hey @imlonghao thank you so much for your contribution, I hope we can merge it today or tomorrow.

garraflavatra commented 2 days ago

Stumbled upon this issue while debugging a redirect which didn't work in Safari. Thanks for fixing it!

A workaround for the time until the fix is released is to remove the problematic header entirely: header -Content-Length. It might be a bit too aggressive, but it does the job :)