Commit e708a88e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move the determination of the existence of and how we will fetch

a body in the beresp up before the vcl_fetch{} call and prepare to
make it possible to modify the value from VCL.

Move the actual code to rfc2616.c along with the default TTL determination.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5477 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent c65cc6f8
......@@ -65,6 +65,7 @@
#include "vsc.h"
#include "vsl.h"
#include "vtypes.h"
/*
* NB: HDR_STATUS is only used in cache_http.c, everybody else uses the
......@@ -250,6 +251,7 @@ struct worker {
struct http *beresp;
struct http *resp;
enum body_status body_status;
unsigned cacheable;
double age;
double entered;
......@@ -737,6 +739,7 @@ unsigned WS_Free(const struct ws *ws);
/* rfc2616.c */
double RFC2616_Ttl(const struct sess *sp);
enum body_status RFC2616_Body(const struct sess *sp);
/* storage_synth.c */
struct vsb *SMS_Makesynth(struct object *obj);
......
......@@ -506,6 +506,8 @@ cnt_fetch(struct sess *sp)
sp->wrk->do_esi = 0;
sp->wrk->grace = NAN;
sp->wrk->body_status = RFC2616_Body(sp);
VCL_fetch_method(sp);
/*
......
......@@ -55,6 +55,7 @@ fetch_straight(struct sess *sp, struct http_conn *htc, const char *b)
unsigned cl, sl;
struct storage *st;
assert(sp->wrk->body_status == BS_LENGTH);
cll = strtoumax(b, NULL, 0);
if (cll == 0)
return (0);
......@@ -100,6 +101,7 @@ fetch_chunked(struct sess *sp, struct http_conn *htc)
char buf[20]; /* XXX: arbitrary */
char *bp, *be;
assert(sp->wrk->body_status == BS_CHUNKED);
be = buf + sizeof buf - 1;
bp = buf;
st = NULL;
......@@ -245,6 +247,7 @@ fetch_eof(struct sess *sp, struct http_conn *htc)
struct storage *st;
unsigned v;
assert(sp->wrk->body_status == BS_EOF);
if (fetchfrag > 0)
WSL(sp->wrk, SLT_Debug, sp->fd,
"Fetch %d byte segments:", fetchfrag);
......@@ -452,12 +455,11 @@ FetchHdr(struct sess *sp)
int
FetchBody(struct sess *sp)
{
struct vbc *vc;
char *b;
int cls;
struct http *hp;
struct storage *st;
int mklen, is_head;
int mklen;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
......@@ -470,63 +472,37 @@ FetchBody(struct sess *sp)
if (sp->obj->objcore != NULL) /* pass has no objcore */
AN(ObjIsBusy(sp->obj));
vc = sp->vbc;
is_head = (strcasecmp(http_GetReq(sp->wrk->bereq), "head") == 0);
/*
* Determine if we have a body or not
* XXX: Missing: RFC2616 sec. 4.4 in re 1xx, 204 & 304 responses
*/
cls = 0;
mklen = 0;
if (is_head) {
sp->wrk->stats.fetch_head++;
} else if (http_GetHdr(hp, H_Content_Length, &b)) {
sp->wrk->stats.fetch_length++;
switch (sp->wrk->body_status) {
case BS_NONE:
break;
case BS_ZERO:
mklen = 1;
break;
case BS_LENGTH:
AN(http_GetHdr(hp, H_Content_Length, &b));
cls = fetch_straight(sp, sp->wrk->htc, b);
mklen = 1;
} else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) {
sp->wrk->stats.fetch_chunked++;
break;
case BS_CHUNKED:
cls = fetch_chunked(sp, sp->wrk->htc);
mklen = 1;
} else if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
sp->wrk->stats.fetch_bad++;
/* XXX: AUGH! */
WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding");
VDI_CloseFd(sp);
return (__LINE__);
} else if (http_HdrIs(hp, H_Connection, "keep-alive")) {
sp->wrk->stats.fetch_zero++;
/*
* If we have Connection: keep-alive, it cannot possibly be
* EOF encoded, and since it is neither length nor chunked
* it must be zero length.
*/
mklen = 1;
} else if (http_HdrIs(hp, H_Connection, "close")) {
sp->wrk->stats.fetch_close++;
/*
* If we have connection closed, it is safe to read what
* comes in any case.
*/
cls = fetch_eof(sp, sp->wrk->htc);
mklen = 1;
} else if (hp->protover < 1.1) {
sp->wrk->stats.fetch_oldhttp++;
/*
* With no Connection header, assume EOF
*/
cls = fetch_eof(sp, sp->wrk->htc);
mklen = 1;
} else {
sp->wrk->stats.fetch_eof++;
/*
* This is what happens when HTTP/1.0 backends claim
* to be HTTP/1.1, assume EOF
*/
break;
case BS_EOF:
cls = fetch_eof(sp, sp->wrk->htc);
mklen = 1;
break;
case BS_ERROR:
VDI_CloseFd(sp);
return (__LINE__);
default:
INCOMPL();
}
if (cls == 0 && http_HdrIs(hp, H_Connection, "close"))
......
......@@ -40,7 +40,7 @@ SVNID("$Id$")
#include <math.h>
#include "cache.h"
#include "vrt.h"
/*--------------------------------------------------------------------
* TTL and Age calculation in Varnish
......@@ -163,3 +163,74 @@ RFC2616_Ttl(const struct sess *sp)
return (ttd);
}
/*--------------------------------------------------------------------
* Body existence and fetch method
* XXX: Missing: RFC2616 sec. 4.4 in re 1xx, 204 & 304 responses
*/
enum body_status
RFC2616_Body(const struct sess *sp)
{
struct http *hp;
char *b;
hp = sp->wrk->beresp1;
if (!strcasecmp(http_GetReq(sp->wrk->bereq), "head")) {
/*
* A HEAD request can never have a body in the reply,
* no matter what the headers might say.
*/
sp->wrk->stats.fetch_head++;
return (BS_NONE);
}
/* If the headers tells us what to do, obey. */
if (http_GetHdr(hp, H_Content_Length, &b)) {
sp->wrk->stats.fetch_length++;
return (BS_LENGTH);
}
if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) {
sp->wrk->stats.fetch_chunked++;
return (BS_CHUNKED);
}
if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
sp->wrk->stats.fetch_bad++;
return (BS_ERROR);
}
if (http_HdrIs(hp, H_Connection, "keep-alive")) {
/*
* Keep alive with neither TE=Chunked or C-Len is impossible.
* We assume a zero length body.
*/
sp->wrk->stats.fetch_zero++;
return (BS_ZERO);
}
if (http_HdrIs(hp, H_Connection, "close")) {
/*
* In this case, it is safe to just read what comes.
*/
sp->wrk->stats.fetch_close++;
return (BS_EOF);
}
if (hp->protover < 1.1) {
/*
* With no Connection header, assume EOF.
*/
sp->wrk->stats.fetch_oldhttp++;
return (BS_EOF);
}
/*
* XXX: Here it should depends on the status code
*/
sp->wrk->stats.fetch_eof++;
return (BS_EOF);
}
/*-
* Copyright (c) 2010 Linpro AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*
* Very special types, widely used, in their own #include to keep
* #include-infection minimal.
*/
enum body_status {
BS_NONE,
BS_ZERO,
BS_ERROR,
BS_CHUNKED,
BS_LENGTH,
BS_EOF
};
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