And here's a minimal version without renames or removing Accept-Ranges from !200 responses.
On Sun, Dec 7, 2014 at 6:19 PM, Federico Schwindt <[email protected]> wrote: > Hi, > > Someone at the SF summit mentioned this so here's a patch for handling not > satisfiable ranges (error code 416) and fixing some corner cases. > I took the liberty of renaming some variables to follow the spec more > closely. > I've also changed V1D_Deliver() to only add Accept-Ranges for 200 > responses. I believe this makes more sense and it's what another web server > does but I'm fine either way. > Tests updated. > > Comments? OKs? >
From ae04614996c4ef37f507043a969ce2c889193e2e Mon Sep 17 00:00:00 2001 From: "Federico G. Schwindt" <[email protected]> Date: Mon, 8 Dec 2014 09:30:09 +0000 Subject: [PATCH] Improve Range handling Add support for 416 and fix some corner cases. --- bin/varnishd/cache/cache_range.c | 28 ++++++++------- bin/varnishtest/tests/c00034.vtc | 76 ++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c index 2ba4587..be29ece 100644 --- a/bin/varnishd/cache/cache_range.c +++ b/bin/varnishd/cache/cache_range.c @@ -98,14 +98,12 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r) else len = ObjGetLen(req->wrk, req->objcore); - if (strncmp(r, "bytes=", 6)) + if (strncasecmp(r, "bytes=", 6)) return; r += 6; /* The low end of range */ has_low = low = 0; - if (!vct_isdigit(*r) && *r != '-') - return; while (vct_isdigit(*r)) { has_low = 1; low *= 10; @@ -113,9 +111,6 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r) r++; } - if (low >= len) - return; - if (*r != '-') return; r++; @@ -128,22 +123,31 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r) high += *r - '0'; r++; } + if (high < low) + return; if (!has_low) { low = len - high; if (low < 0) low = 0; high = len - 1; - } - } else + } else if (high >= len) + high = len - 1; + } else if (has_low) high = len - 1; - if (*r != '\0') + else return; - if (high >= len) - high = len - 1; + if (*r != '\0') + return; - if (low > high) + if (low >= len) { + http_PrintfHeader(req->resp, "Content-Range: bytes */%jd", + (intmax_t)len); + http_Unset(req->resp, H_Content_Length); + http_PutResponse(req->resp, "HTTP/1.1", 416, NULL); + req->wantbody = 0; return; + } http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", (intmax_t)low, (intmax_t)high, (intmax_t)len); diff --git a/bin/varnishtest/tests/c00034.vtc b/bin/varnishtest/tests/c00034.vtc index 23910de..eb5b975 100644 --- a/bin/varnishtest/tests/c00034.vtc +++ b/bin/varnishtest/tests/c00034.vtc @@ -5,13 +5,11 @@ server s1 { txresp -bodylen 100 } -start -varnish v1 -vcl+backend { - +varnish v1 -arg "-p http_range_support=off" -vcl+backend { sub vcl_backend_response { set beresp.do_stream = false; } } -start -varnish v1 -cliok "param.set http_range_support off" client c1 { txreq -hdr "Range: bytes=0-9" @@ -45,61 +43,71 @@ client c1 { expect resp.status == 200 expect resp.bodylen == 100 + txreq -hdr "Range: bytes=-" + rxresp + expect resp.status == 200 + expect resp.bodylen == 100 + + txreq -hdr "Range: bytes=5-2" + rxresp + expect resp.status == 200 + expect resp.bodylen == 100 } -run -varnish v1 -expect s_resp_bodybytes == 500 +varnish v1 -expect s_resp_bodybytes == 700 client c1 { - - txreq -hdr "Range: bytes=0-9" + txreq -hdr "Range: bytes=-0" rxresp - expect resp.status == 206 - expect resp.bodylen == 10 + expect resp.status == 416 + expect resp.bodylen == 0 + expect resp.http.content-range == "bytes */100" - txreq -hdr "Range: bytes=10-19" + txreq -hdr "Range: bytes=100-" rxresp - expect resp.status == 206 - expect resp.bodylen == 10 + expect resp.status == 416 + expect resp.bodylen == 0 + expect resp.http.content-range == "bytes */100" +} -run - txreq -hdr "Range: bytes=90-" - rxresp - expect resp.status == 206 - expect resp.bodylen == 10 +varnish v1 -expect s_resp_bodybytes == 700 - txreq -hdr "Range: bytes=-9" +client c1 { + txreq -hdr "Range: bytes=0-49" rxresp expect resp.status == 206 - expect resp.bodylen == 9 + expect resp.http.content-length == 50 + expect resp.http.content-range == "bytes 0-49/100" - txreq -hdr "Range: bytes=-" + txreq -hdr "Range: bytes=50-99" rxresp expect resp.status == 206 - expect resp.bodylen == 100 - - txreq -hdr "Range: bytes=102-102" - rxresp - expect resp.status == 200 - expect resp.bodylen == 100 + expect resp.http.content-length == 50 + expect resp.http.content-range == "bytes 50-99/100" - txreq -hdr "Range: bytes=99-" + txreq -hdr "Range: bytes=-50" rxresp expect resp.status == 206 - expect resp.bodylen == 1 + expect resp.http.content-length == 50 + expect resp.http.content-range == "bytes 50-99/100" - txreq -hdr "Range: bytes=99-70" + txreq -hdr "Range: bytes=50-" rxresp - expect resp.status == 200 - expect resp.bodylen == 100 + expect resp.status == 206 + expect resp.http.content-length == 50 + expect resp.http.content-range == "bytes 50-99/100" - txreq -hdr "Range: bytes=-" + txreq -hdr "Range: bytes=0-0" rxresp expect resp.status == 206 - expect resp.bodylen == 100 + expect resp.http.content-length == 1 + expect resp.http.content-range == "bytes 0-0/100" - txreq -hdr "Range: bytes=-101" + txreq -hdr "Range: bytes=-2000" rxresp expect resp.status == 206 - expect resp.bodylen == 100 + expect resp.http.content-length == 100 + expect resp.http.content-range == "bytes 0-99/100" } -run -varnish v1 -expect s_resp_bodybytes == 1040 +varnish v1 -expect s_resp_bodybytes == 1001 -- 2.1.3
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
