varnish-cache icon indicating copy to clipboard operation
varnish-cache copied to clipboard

On cache Miss of request containing "Range: bytes=0-" response status is 200 (should be 206)

Open imwhocodes opened this issue 1 year ago • 7 comments
trafficstars

Expected Behavior

Given this condition:

  • Client requesting a GET with Range: bytes=0-
  • Resource result in a cache-miss and fetch to backend server
  • Backend respond 200 with Transfer-Encoding: chunked

While streaming from backend the response to the client should be:

  • 206 (Partial Content)
  • Transfer-Encoding: chunked

Current Behavior

Given previous precondition:

While streaming from backend the response is:

  • 200 (OK)
  • Transfer-Encoding: chunked

But when retrieving from cache (correctly):

  • 206 (Partial Content)
  • Content-Length: ...
  • Content-Range: bytes ...

Possible Solution

I tried:

sub vcl_deliver {
    if( 
        resp.is_streaming
            &&
        ( std.tolower(req.http.range) == "bytes=0-" )
            &&
        ( req.http.if-none-match != resp.http.etag )
    ){
        set resp.status = 206;
    }
}

But this seem to break the response (at least on chrome)

Steps to Reproduce (for bugs)

No response

Context

I'm using Varnish as a reverse-proxy/cache in front of an aiohttp (python) server that encode on-demand some videos using ffmpeg, I want to minimize time form request to first frame out so ffmpeg output is piped out while it being processed: ffmpeg ... -f mp4 -movflags frag_keyframe+empty_moov+default_base_moof pipe:

This is why the response from the origin/backend server is Transfer-Encoding: chunked The response is for a <video> html5 tag, 200 would be ok if not that Chrome misbehave (palyback seeking is broken) when not receiving 206 on a Range: bytes=0- request

Log

*   << BeReq    >> 3
-   Begin          bereq 2 fetch
-   VCL_use        boot
-   Timestamp      Start: 1710255589.400947 0.000000 0.000000
-   BereqMethod    GET
-   BereqURL       /<folder>/IMG_7269.MOV?h=320&w=320
-   BereqProtocol  HTTP/1.1
-   BereqHeader    Host: <ip>
-   BereqHeader    User-Agent: PostmanRuntime/7.37.0
-   BereqHeader    Accept: */*
-   BereqHeader    Postman-Token: <token>
-   BereqHeader    X-Forwarded-Host: <host>
-   BereqHeader    X-Forwarded-Server: <host>
-   BereqHeader    X-Forwarded-For: <ip>, <ip>
-   BereqHeader    Via: 1.1 48b10ba18c41 (Varnish/7.4)
-   BereqHeader    Accept-Encoding: gzip
-   BereqHeader    X-Varnish: 3
-   VCL_call       BACKEND_FETCH
-   VCL_return     fetch
-   Timestamp      Fetch: 1710255589.400959 0.000012 0.000012
-   Timestamp      Connected: 1710255589.401053 0.000105 0.000093
-   BackendOpen    31 default <ip> <ip> connect
-   Timestamp      Bereq: 1710255589.401069 0.000121 0.000015
-   BerespProtocol HTTP/1.1
-   BerespStatus   200
-   BerespReason   OK
-   BerespHeader   Etag: "FAEB-2OFl-ldkvZQ==-mp4-2832867"
-   BerespHeader   Last-Modified: Wed, 18 Oct 2023 13:11:49 GMT
-   BerespHeader   Cache-Control: public, must-revalidate, stale-while-revalidate, stale-if-error
-   BerespHeader   Content-Type: video/mp4
-   BerespHeader   Transfer-Encoding: chunked 
-   BerespHeader   Date: Tue, 12 Mar 2024 14:59:49 GMT
-   BerespHeader   Server: Python/3.10 aiohttp/3.9.3
-   Timestamp      Beresp: 1710255589.496585 0.095638 0.095516
-   TTL            RFC 120 10 0 1710255589 1710255589 1710255589 0 0 cacheable
-   VCL_call       BACKEND_RESPONSE
-   TTL            VCL 120 60 0 1710255589 cacheable
-   TTL            VCL 120 60 31536000 1710255589 cacheable
-   VCL_return     deliver
-   Timestamp      Process: 1710255589.496608 0.095660 0.000022
-   Filters
-   Storage        malloc s0
-   Fetch_Body     2 chunked stream
-   BackendClose   31 default recycle
-   Timestamp      BerespBody: 1710255589.742165 0.341217 0.245557
-   Length         795115
-   BereqAcct      392 0 392 310 795115 795425
-   End

*   << Request  >> 2
-   Begin          req 1 rxreq
-   Timestamp      Start: 1710255589.400859 0.000000 0.000000
-   Timestamp      Req: 1710255589.400859 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       <ip> http
-   ReqMethod      GET
-   ReqURL         /<folder>/IMG_7269.MOV?w=320&h=320
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: <ip>
-   ReqHeader      Range: bytes=0-
-   ReqHeader      User-Agent: PostmanRuntime/7.37.0
-   ReqHeader      Accept: */*
-   ReqHeader      Postman-Token: <token>
-   ReqHeader      Accept-Encoding: gzip, deflate, br
-   ReqHeader      X-Forwarded-For: <ip>
-   ReqHeader      X-Forwarded-Host: <ip>
-   ReqHeader      X-Forwarded-Server: <ip>
-   ReqHeader      Connection: close
-   ReqUnset       X-Forwarded-For: <ip>
-   ReqHeader      X-Forwarded-For: <ip>, <ip>
-   ReqHeader      Via: 1.1 48b10ba18c41 (Varnish/7.4)
-   VCL_call       RECV
-   ReqURL         /<folder>/IMG_7269.MOV?h=320&w=320
-   VCL_return     hash
-   ReqUnset       Accept-Encoding: gzip, deflate, br
-   ReqHeader      Accept-Encoding: gzip
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       MISS
-   VCL_return     fetch
-   Link           bereq 3 fetch
-   Timestamp      Fetch: 1710255589.496667 0.095807 0.095807
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespHeader     Etag: "FAEB-2OFl-ldkvZQ==-mp4-2832867"
-   RespHeader     Last-Modified: Wed, 18 Oct 2023 13:11:49 GMT
-   RespHeader     Cache-Control: public, must-revalidate, stale-while-revalidate, stale-if-error
-   RespHeader     Content-Type: video/mp4
-   RespHeader     Date: Tue, 12 Mar 2024 14:59:49 GMT
-   RespHeader     Server: Python/3.10 aiohttp/3.9.3
-   RespHeader     X-Varnish: 2
-   RespHeader     Age: 0
-   RespHeader     Via: 1.1 48b10ba18c41 (Varnish/7.4)
-   RespHeader     Accept-Ranges: bytes
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1710255589.496678 0.095818 0.000011
-   Filters         range
-   RespHeader     Connection: close
-   RespHeader     Transfer-Encoding: chunked
-   Timestamp      Resp: 1710255589.742303 0.341444 0.245625
-   ReqAcct        378 0 378 410 795115 795525
-   End

*   << Session  >> 1
-   Begin          sess 0 HTTP/1
-   SessOpen       <ip> http <ip> 1710255589.400836 28
-   Link           req 2 rxreq
-   SessClose      REQ_CLOSE 0.342
-   End

Varnish Cache version

varnish:latest (varnish-7.4.2 revision cd1d10ab53a6f6115b2b4f3b2a1da94c1f749f80)

Operating system

No response

Source of binary packages used (if any)

https://hub.docker.com/_/varnish

imwhocodes avatar Mar 12 '24 14:03 imwhocodes