-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
503 Invalid content-range header on partial response with start-end/* #4089
Comments
This function returns the content length and puts range indices in lo and hi arguments. A content length of -1 used to be interpreted as something to ignore, but there is a case where the content length may be unknown. Since we can't represent a zero-length range, because both bounds are inclusive, zero now denotes the lack of content-range header. Unknown range units are treated as errors as they wouldn't pass the busyobj check for the range header, even for pass transactions. The only way to use "extension" range units is to turn http_range_support off. The calling convention for http_GetContentRange() remains otherwise the same, and for good measure http_GetContentLength() received a similar description. Fixes varnishcache#4089
Can you please give #4091 a try? |
Thanks for the quick fix. Testing with #4091, the issue looks partially fixed (no more 503 Invalid content-range header); but I'm seeing a very strange behavior. Varnish is sometimes responding with 416 "Requested Range Not Satisfiable" (just after it logs My cURL (repeated many times): varnishlog (censored) for 206:
varnishlog (censored) for 416:
The varnishlogs are exactly the same (except for stamps and ids), except after the Edit: Managed to enable the Debug logs and got This happens in http_GetRange: if (len <= 0)
return (NULL); // Allow 200 response
if (*lo < 0) {
assert(*hi > 0);
*lo = len - *hi;
if (*lo < 0)
*lo = 0;
*hi = len - 1;
} else if (len >= 0 && (*hi >= len || *hi < 0)) {
*hi = len - 1;
}
if (*lo >= len)
return ("low range beyond object"); In both cases, *lo = 33318; *hi=16769 (at the time of return). However in the 206 case, len = -1, so this returns early, and in the 416 case, len = 16770. Looks like some race condition? Edit: Looks like some race condition because adding a sleep in vcl_deliver makes it 406 almost 100% instead of 10%:
Sadly I still cannot reproduce this in varnishtest. |
@dridi I would think that, with streaming enabled, we would need to add |
This looks harder than I expected given how #4091 is structured. |
Context:
Range: bytes=10-19
.pass
the requestContent-Range: bytes 10-19/*
(andTransfer-Encoding: chunked
, but not sure if that's necessary to reproduce)Expected behavior:
Content-Range: bytes 10-19/*
appears to be correct?)Current behavior:
Invalid content-range header
After delving deeper, this happens in
cache_http.c
athttp_GetContentRange
:lo
gets set to 10,hi
to 19,cl
to -1, as expected; but thenif (*lo >= cl || *hi >= cl) return (-2);
returns -2 and fails the request, because10 >= -1
.varnish-cache/bin/varnishd/cache/cache_http.c
Line 954 in 8f2c364
Not sure I fully understand the function, but should the condition be closer to
if (*hi - *lo < cl) return (-2);
?Here's a MWE VTC. Feel free to reuse.
The text was updated successfully, but these errors were encountered: