Commit 092ab4d9 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Get closer to req->resp_len meaning "bytes to actually send, if known"

parent dc4e7479
......@@ -985,7 +985,7 @@ size_t V1L_Write(const struct worker *w, const void *ptr, ssize_t len);
task_func_t VPX_Proto_Sess;
/* cache_range.c [VRG] */
void VRG_dorange(struct req *req, const struct busyobj *bo, const char *r);
void VRG_dorange(struct req *req, const char *r);
/* cache_req.c */
struct req *Req_New(const struct worker *, struct sess *);
......
......@@ -86,7 +86,7 @@ vrg_range_bytes(struct req *req, enum vdp_action act, void **priv,
/*--------------------------------------------------------------------*/
static int
vrg_dorange(struct req *req, ssize_t len, const char *r)
vrg_dorange(struct req *req, const char *r)
{
ssize_t low, high, has_low, has_high, t;
struct vrg_priv *vrg_priv;
......@@ -127,16 +127,16 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
return (__LINE__);
if (!has_low) {
if (len < 0)
if (req->resp_len < 0)
return (0); // Allow 200 response
if (high == 0)
return (__LINE__);
low = len - high;
low = req->resp_len - high;
if (low < 0)
low = 0;
high = len - 1;
} else if (len >= 0 && (high >= len || !has_high))
high = len - 1;
high = req->resp_len - 1;
} else if (req->resp_len >= 0 && (high >= req->resp_len || !has_high))
high = req->resp_len - 1;
else if (!has_high)
return (0); // Allow 200 response
/*
......@@ -149,12 +149,12 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
if (high < low)
return (__LINE__);
if (len >= 0 && low >= len)
if (req->resp_len >= 0 && low >= req->resp_len)
return (__LINE__);
if (len >= 0)
if (req->resp_len >= 0)
http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
(intmax_t)low, (intmax_t)high, (intmax_t)len);
(intmax_t)low, (intmax_t)high, (intmax_t)req->resp_len);
else
http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/*",
(intmax_t)low, (intmax_t)high);
......@@ -172,9 +172,8 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
}
void
VRG_dorange(struct req *req, const struct busyobj *bo, const char *r)
VRG_dorange(struct req *req, const char *r)
{
ssize_t len;
int i;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
......@@ -182,19 +181,17 @@ VRG_dorange(struct req *req, const struct busyobj *bo, const char *r)
assert(http_IsStatus(req->resp, 200));
/* We must snapshot the length if we're streaming from the backend */
if (bo != NULL)
len = http_GetContentLength(bo->beresp);
else
len = ObjGetLen(req->wrk, req->objcore);
i = vrg_dorange(req, len, r);
i = vrg_dorange(req, r);
if (i) {
VSLb(req->vsl, SLT_Debug, "RANGE_FAIL line %d", i);
http_Unset(req->resp, H_Content_Length);
if (bo == NULL)
if (req->resp_len >= 0)
http_PrintfHeader(req->resp,
"Content-Range: bytes */%jd", (intmax_t)len);
"Content-Range: bytes */%jd",
(intmax_t)req->resp_len);
http_PutResponse(req->resp, "HTTP/1.1", 416, NULL);
req->resp_len = -1;
req->wantbody = 0;
}
}
......@@ -70,7 +70,10 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
req->res_mode = 0;
req->resp_len = -2;
if (bo != NULL)
req->resp_len = http_GetContentLength(bo->beresp);
else
req->resp_len = ObjGetLen(req->wrk, req->objcore);
/*
* Determine ESI status first. Not dependent on wantbody, because
......@@ -90,6 +93,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
if (req->res_mode & RES_ESI) {
RFC2616_Weaken_Etag(req->resp);
req->resp_len = -1;
VDP_push(req, VDP_ESI, NULL, 0);
} else if (http_IsStatus(req->resp, 304)) {
http_Unset(req->resp, H_Content_Length);
......@@ -109,11 +113,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
VDP_push(req, VDP_gunzip, NULL, 1);
}
if (req->res_mode & RES_ESI) {
/* Gunzip could have added back a C-L */
http_Unset(req->resp, H_Content_Length);
if (req->res_mode & RES_ESI)
assert(req->resp_len < 0);
}
/*
* Range comes after the others and pushes on bottom because it
......@@ -122,17 +123,22 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) {
http_SetHeader(req->resp, "Accept-Ranges: bytes");
if (req->wantbody && http_GetHdr(req->http, H_Range, &r))
VRG_dorange(req, bo, r);
VRG_dorange(req, r);
}
if (req->resp_len >= -1 && req->wantbody)
if ((req->objcore->flags & OC_F_PRIVATE) &&
!strcasecmp(http_GetMethod(req->http0), "HEAD")) {
/* HEAD+pass is allowed to send the C-L through unmolested. */
} else {
http_Unset(req->resp, H_Content_Length);
if (req->resp_len >= 0 && req->wantbody)
http_PrintfHeader(req->resp,
"Content-Length: %jd", req->resp_len);
if (req->resp_len >= 0 && !http_IsStatus(req->resp, 304))
http_PrintfHeader(req->resp,
"Content-Length: %jd", req->resp_len);
}
if (http_GetHdr(req->resp, H_Content_Length, NULL))
req->res_mode |= RES_LEN;
else if (req->wantbody) {
if (req->http->protover == 11) {
req->res_mode |= RES_CHUNKED;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment