Commit 797aec02 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Yet another refinement to the way we store and deal with HTTP headers.

Record a triplet of {start, data, end} for all HTTP data items.

This represents a regrettable uglification of the sourcecode, but
most of it compiles out to constants and the runtime benefits will
be worth it.

Generate H_FOO magic strings for all the headers we know about.
These strings have a length as first char and always ends in ':'.

Also genereate H_FOO format strings in VCL compiler.

Mandate (with assert) that header references happen using H_FOO strings.

Make number of allowed HTTP headers a compile time constant (32)
but make the workspace a run-time variable (4096).

Introduce new SHM tag for dumping aborted HTTP protocol requests.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@531 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ded53d68
......@@ -17,6 +17,19 @@
#define MAX_IOVS 10
#define MAX_HTTP_HDRS 32
#define HTTP_HDR_REQ 0
#define HTTP_HDR_URL 1
#define HTTP_HDR_PROTO 2
#define HTTP_HDR_STATUS 3
#define HTTP_HDR_RESPONSE 4
#define HTTP_HDR_FIRST 5
#define HTTP_START 0
#define HTTP_DATA 1
#define HTTP_END 2
struct event_base;
struct cli;
struct sbuf;
......@@ -46,21 +59,16 @@ struct http {
http_callback_f *callback;
void *arg;
char *s; /* start of buffer */
char *t; /* start of trailing data */
char *v; /* end of valid bytes */
char *e; /* end of buffer */
char *req;
char *url;
char *proto;
char *status;
char *response;
char *s; /* (S)tart of buffer */
char *t; /* start of (T)railing data */
char *v; /* end of (V)alid bytes */
char *f; /* first (F)ree byte */
char *e; /* (E)nd of buffer */
unsigned conds; /* If-* headers present */
unsigned nhdr;
char **hdr;
char *hd[MAX_HTTP_HDRS][HTTP_END + 1];
unsigned nhd;
};
/*--------------------------------------------------------------------*/
......@@ -287,7 +295,8 @@ void HSH_Deref(struct object *o);
void HSH_Init(void);
/* cache_http.c */
void http_Init(struct http *ht, void *space);
void HTTP_Init(void);
void http_Init(struct http *ht, void *space, unsigned len);
int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
int http_GetHdrField(struct http *hp, const char *hdr, const char *field, char **ptr);
int http_GetStatus(struct http *hp);
......@@ -304,6 +313,9 @@ enum http_build {
Build_Reply
};
void http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp);
#define HTTPH(a, b, c, d, e, f, g) extern char b[];
#include "http_headers.h"
#undef HTTPH
/* cache_pass.c */
void PassSession(struct worker *w, struct sess *sp);
......
......@@ -44,7 +44,6 @@ struct vbc_mem {
#define VBC_MEM_MAGIC 0x2fd7af01
struct vbe_conn vbe;
struct http http;
char *http_hdr;
};
/* A backend IP */
......@@ -74,12 +73,7 @@ vbe_new_conn(void)
{
struct vbc_mem *vbcm;
vbcm = calloc(
sizeof *vbcm +
heritage.mem_http_headers * sizeof vbcm->http_hdr +
heritage.mem_http_headerspace +
heritage.mem_workspace,
1);
vbcm = calloc(sizeof *vbcm + heritage.mem_workspace, 1);
if (vbcm == NULL)
return (NULL);
vbcm->magic = VBC_MEM_MAGIC;
......@@ -87,7 +81,7 @@ vbe_new_conn(void)
vbcm->vbe.magic = VBE_CONN_MAGIC;
vbcm->vbe.vbcm = vbcm;
vbcm->vbe.http = &vbcm->http;
http_Init(&vbcm->http, (void *)(vbcm + 1));
http_Init(&vbcm->http, (void *)(vbcm + 1), heritage.mem_workspace);
return (&vbcm->vbe);
}
......
......@@ -87,10 +87,11 @@ cnt_done(struct sess *sp)
assert(sp->obj == NULL);
if (sp->fd < 0) {
/* Allready closed */
} else if (http_GetHdr(sp->http, "Connection", &b) &&
} else if (http_GetHdr(sp->http, H_Connection, &b) &&
!strcmp(b, "close")) {
vca_close_session(sp, "Connection header");
} else if (strcmp(sp->http->proto, "HTTP/1.1")) {
} else if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START],
"HTTP/1.1")) {
vca_close_session(sp, "not HTTP/1.1");
}
VCL_Rel(sp->vcl);
......
......@@ -216,13 +216,13 @@ FetchBody(struct worker *w, struct sess *sp)
vc = sp->vbc;
hp = sp->bkd_http;
if (http_GetHdr(hp, "Last-Modified", &b))
if (http_GetHdr(hp, H_Last_Modified, &b))
sp->obj->last_modified = TIM_parse(b);
http_BuildSbuf(sp->fd, Build_Reply, w->sb, hp);
if (body) {
if (http_GetHdr(hp, "Content-Length", &b))
if (http_GetHdr(hp, H_Content_Length, &b))
cls = fetch_straight(sp, vc->fd, hp, b);
else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked"))
cls = fetch_chunked(sp, vc->fd, hp);
else
cls = fetch_eof(sp, vc->fd, hp);
......@@ -233,7 +233,7 @@ FetchBody(struct worker *w, struct sess *sp)
sp->obj->header = strdup(sbuf_data(w->sb));
VSL_stats->n_header++;
if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close"))
if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close"))
cls = 1;
if (cls)
......
......@@ -46,7 +46,7 @@ HSH_Lookup(struct sess *sp)
struct http *h;
struct objhead *oh;
struct object *o;
char *c;
char *url, *host;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
......@@ -77,8 +77,9 @@ HSH_Lookup(struct sess *sp)
} else
CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
if (!http_GetHdr(h, "Host", &c))
c = h->url;
url = h->hd[HTTP_HDR_URL][HTTP_START];
if (!http_GetHdr(h, H_Host, &host))
host = url;
if (sp->obj != NULL) {
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
o = sp->obj;
......@@ -87,7 +88,7 @@ HSH_Lookup(struct sess *sp)
AZ(pthread_mutex_lock(&oh->mtx));
goto were_back;
}
oh = hash->lookup(h->url, c, w->nobjhead);
oh = hash->lookup(url, host, w->nobjhead);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oh == w->nobjhead)
w->nobjhead = NULL;
......@@ -108,7 +109,7 @@ HSH_Lookup(struct sess *sp)
/* Object banned but not reaped yet */
} else if (o->ttl < sp->t_req) {
/* Object expired */
} else if (BAN_CheckObject(o, h->url)) {
} else if (BAN_CheckObject(o, url)) {
o->ttl = 0;
VSL(SLT_ExpBan, 0, "%u was banned", o->xid);
EXP_TTLchange(o);
......
......@@ -15,19 +15,28 @@
#include "heritage.h"
#include "cache.h"
#define HTTPH(a, b, c, d, e, f, g) char b[] = "*" a ":";
#include "http_headers.h"
#undef HTTPH
#define VSLH(a, b, c, d) \
VSLR((a), (b), (c)->hd[d][HTTP_START], (c)->hd[d][HTTP_END]);
/*--------------------------------------------------------------------*/
void
http_Init(struct http *hp, void *space)
http_Init(struct http *hp, void *space, unsigned len)
{
char *sp = space;
assert(len > 0);
memset(hp, 0, sizeof *hp);
hp->magic = HTTP_MAGIC;
hp->hdr = (void *)sp;
sp += heritage.mem_http_headers * sizeof hp->hdr;
hp->s = sp;
hp->e = hp->s + heritage.mem_http_headerspace;
hp->t = sp;
hp->v = sp;
hp->f = sp;
hp->e = sp + len;
}
/*--------------------------------------------------------------------*/
......@@ -38,19 +47,29 @@ http_GetHdr(struct http *hp, const char *hdr, char **ptr)
unsigned u, l;
char *p;
l = strlen(hdr);
for (u = 0; u < hp->nhdr; u++) {
if (strncasecmp(hdr, hp->hdr[u], l))
l = hdr[0];
assert(l == strlen(hdr + 1));
assert(hdr[l] == ':');
hdr++;
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
assert(hp->hd[u][HTTP_START] != NULL);
assert(hp->hd[u][HTTP_END] != NULL);
if (hp->hd[u][HTTP_END] < hp->hd[u][HTTP_START] + l)
continue;
p = hp->hdr[u];
if (p[l] != ':')
if (hp->hd[u][HTTP_START][l-1] != ':')
continue;
p += l + 1;
while (isspace(*p))
p++;
*ptr = p;
if (strncasecmp(hdr, hp->hd[u][HTTP_START], l))
continue;
if (hp->hd[u][HTTP_DATA] == NULL) {
p = hp->hd[u][HTTP_START] + l;
while (isspace(*p))
p++;
hp->hd[u][HTTP_DATA] = p;
}
*ptr = hp->hd[u][HTTP_DATA];
return (1);
}
*ptr = NULL;
return (0);
}
......@@ -153,7 +172,9 @@ int
http_GetStatus(struct http *hp)
{
return (strtoul(hp->status, NULL /* XXX */, 10));
assert(hp->hd[HTTP_HDR_STATUS][HTTP_START] != NULL);
return (strtoul(hp->hd[HTTP_HDR_STATUS][HTTP_START],
NULL /* XXX */, 10));
}
/*--------------------------------------------------------------------
......@@ -169,11 +190,12 @@ http_dissect_hdrs(struct http *hp, int fd, char *p)
if (*p == '\r')
p++;
hp->nhdr = 0;
hp->nhd = HTTP_HDR_FIRST;
hp->conds = 0;
r = NULL; /* For FlexeLint */
assert(p < hp->v); /* http_header_complete() guarantees this */
for (; p < hp->v; p = r) {
/* XXX: handle continuation lines */
q = strchr(p, '\n');
assert(q != NULL);
r = q + 1;
......@@ -188,17 +210,17 @@ http_dissect_hdrs(struct http *hp, int fd, char *p)
p[2] == '-')
hp->conds = 1;
if (hp->nhdr < heritage.mem_http_headers) {
hp->hdr[hp->nhdr++] = p;
VSLR(SLT_Header, fd, p, q);
if (hp->nhd < MAX_HTTP_HDRS) {
hp->hd[hp->nhd][HTTP_START] = p;
hp->hd[hp->nhd][HTTP_END] = q;
VSLH(SLT_Header, fd, hp, hp->nhd);
hp->nhd++;
} else {
VSL_stats->losthdr++;
VSLR(SLT_LostHeader, fd, p, q);
}
}
assert(hp->t <= hp->v);
if (hp->t != r)
printf("hp->t %p r %p\n", hp->t, r);
assert(hp->t == r);
return (0);
}
......@@ -217,25 +239,27 @@ http_DissectRequest(struct http *hp, int fd)
continue;
/* First, the request type (GET/HEAD etc) */
hp->req = p;
hp->hd[HTTP_HDR_REQ][HTTP_START] = p;
for (; isalpha(*p); p++)
;
VSLR(SLT_Request, fd, hp->req, p);
hp->hd[HTTP_HDR_REQ][HTTP_END] = p;
VSLH(SLT_Request, fd, hp, HTTP_HDR_REQ);
*p++ = '\0';
/* Next find the URI */
while (isspace(*p) && *p != '\n')
p++;
if (*p == '\n') {
VSLR(SLT_Debug, fd, hp->s, hp->v);
VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
return (400);
}
hp->url = p;
hp->hd[HTTP_HDR_URL][HTTP_START] = p;
while (!isspace(*p))
p++;
VSLR(SLT_URL, fd, hp->url, p);
hp->hd[HTTP_HDR_URL][HTTP_END] = p;
VSLH(SLT_URL, fd, hp, HTTP_HDR_URL);
if (*p == '\n') {
VSLR(SLT_Debug, fd, hp->s, hp->v);
VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
return (400);
}
*p++ = '\0';
......@@ -244,19 +268,20 @@ http_DissectRequest(struct http *hp, int fd)
while (isspace(*p) && *p != '\n')
p++;
if (*p == '\n') {
VSLR(SLT_Debug, fd, hp->s, hp->v);
VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
return (400);
}
hp->proto = p;
hp->hd[HTTP_HDR_PROTO][HTTP_START] = p;
while (!isspace(*p))
p++;
VSLR(SLT_Protocol, fd, hp->proto, p);
hp->hd[HTTP_HDR_PROTO][HTTP_END] = p;
VSLH(SLT_Protocol, fd, hp, HTTP_HDR_PROTO);
if (*p != '\n')
*p++ = '\0';
while (isspace(*p) && *p != '\n')
p++;
if (*p != '\n') {
VSLR(SLT_Debug, fd, hp->s, hp->v);
VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
return (400);
}
*p++ = '\0';
......@@ -278,31 +303,35 @@ http_DissectResponse(struct http *hp, int fd)
continue;
/* First, protocol */
hp->proto = p;
hp->hd[HTTP_HDR_PROTO][HTTP_START] = p;
while (!isspace(*p))
p++;
VSLR(SLT_Protocol, fd, hp->proto, p);
hp->hd[HTTP_HDR_PROTO][HTTP_END] = p;
VSLH(SLT_Protocol, fd, hp, HTTP_HDR_PROTO);
*p++ = '\0';
/* Next find the status */
while (isspace(*p))
p++;
hp->status = p;
hp->hd[HTTP_HDR_STATUS][HTTP_START] = p;
while (!isspace(*p))
p++;
VSLR(SLT_Status, fd, hp->status, p);
hp->hd[HTTP_HDR_STATUS][HTTP_END] = p;
VSLH(SLT_Status, fd, hp, HTTP_HDR_STATUS);
*p++ = '\0';
/* Next find the response */
while (isspace(*p))
p++;
hp->response = p;
hp->hd[HTTP_HDR_RESPONSE][HTTP_START] = p;
while (*p != '\n')
p++;
for (q = p; q > hp->response && isspace(q[-1]); q--)
for (q = p; q > hp->hd[HTTP_HDR_RESPONSE][HTTP_START] &&
isspace(q[-1]); q--)
continue;
*q = '\0';
VSLR(SLT_Response, fd, hp->response, q);
hp->hd[HTTP_HDR_RESPONSE][HTTP_END] = q;
VSLH(SLT_Response, fd, hp, HTTP_HDR_RESPONSE);
p++;
return (http_dissect_hdrs(hp, fd, p));
......@@ -360,7 +389,7 @@ http_read_f(int fd, short event, void *arg)
l = hp->e - hp->v;
if (l <= 1) {
VSL(SLT_HttpError, fd, "Received too much");
VSLR(SLT_Debug, fd, hp->s, hp->v);
VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
hp->t = NULL;
ret = 1;
} else {
......@@ -458,55 +487,47 @@ http_supress(const char *hdr, int flag)
void
http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp)
{
unsigned u, sup;
unsigned u, sup, rr;
sbuf_clear(sb);
assert(sb != NULL);
switch (mode) {
case Build_Reply:
sbuf_cat(sb, hp->proto);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->status);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->response);
sup = 2;
break;
case Build_Pipe:
sbuf_cat(sb, hp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->url);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->proto);
sup = 0;
break;
case Build_Pass:
sbuf_cat(sb, hp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->url);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->proto);
sup = 2;
break;
case Build_Fetch:
sbuf_cat(sb, "GET ");
sbuf_cat(sb, hp->url);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->proto);
sup = 1;
break;
case Build_Reply: rr = 0; sup = 2; break;
case Build_Pipe: rr = 1; sup = 0; break;
case Build_Pass: rr = 1; sup = 2; break;
case Build_Fetch: rr = 2; sup = 1; break;
default:
sup = 0; /* for flexelint */
rr = 0; /* for flexelint */
printf("mode = %d\n", mode);
assert(mode == 1 || mode == 2);
assert(__LINE__ == 0);
}
if (rr == 0) {
sbuf_cat(sb, hp->hd[HTTP_HDR_PROTO][HTTP_START]);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->hd[HTTP_HDR_STATUS][HTTP_START]);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->hd[HTTP_HDR_RESPONSE][HTTP_START]);
} else {
if (rr == 2) {
sbuf_cat(sb, "GET ");
} else {
sbuf_cat(sb, hp->hd[HTTP_HDR_REQ][HTTP_START]);
sbuf_cat(sb, " ");
}
sbuf_cat(sb, hp->hd[HTTP_HDR_URL][HTTP_START]);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->hd[HTTP_HDR_PROTO][HTTP_START]);
}
sbuf_cat(sb, "\r\n");
for (u = 0; u < hp->nhdr; u++) {
if (http_supress(hp->hdr[u], sup))
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
if (http_supress(hp->hd[u][HTTP_START], sup))
continue;
if (1)
VSL(SLT_BldHdr, fd, "%s", hp->hdr[u]);
sbuf_cat(sb, hp->hdr[u]);
VSL(SLT_BldHdr, fd, "%s", hp->hd[u][HTTP_START]);
sbuf_cat(sb, hp->hd[u][HTTP_START]);
sbuf_cat(sb, "\r\n");
}
if (mode != Build_Reply) {
......@@ -514,3 +535,11 @@ http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp)
sbuf_finish(sb);
}
}
void
HTTP_Init(void)
{
#define HTTPH(a, b, c, d, e, f, g) b[0] = strlen(b + 1);
#include "http_headers.h"
#undef HTTPH
}
......@@ -105,6 +105,7 @@ child_main(void)
VCL_Init();
VCL_Load(heritage.vcl_file, "boot", NULL);
HTTP_Init();
SES_Init();
VBE_Init();
......
......@@ -152,18 +152,18 @@ PassBody(struct worker *w, struct sess *sp)
sbuf_finish(w->sb);
RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
if (http_GetHdr(hp, "Content-Length", &b))
if (http_GetHdr(hp, H_Content_Length, &b))
cls = pass_straight(sp, vc->fd, hp, b);
else if (http_HdrIs(hp, "Connection", "close"))
else if (http_HdrIs(hp, H_Connection, "close"))
cls = pass_straight(sp, vc->fd, hp, NULL);
else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked"))
cls = pass_chunked(sp, vc->fd, hp);
else {
cls = pass_straight(sp, vc->fd, hp, NULL);
}
RES_Flush(sp);
if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close"))
if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close"))
cls = 1;
if (cls)
......
......@@ -126,7 +126,7 @@ res_do_304(struct sess *sp, char *p)
RES_Write(sp, "Last-Modified: ", -1);
RES_Write(sp, p, -1);
RES_Write(sp, "\r\n", -1);
if (strcmp(sp->http->proto, "HTTP/1.1"))
if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START], "HTTP/1.1"))
RES_Write(sp, "Connection: close\r\n", -1);
sbuf_printf(sb, "X-Varnish: xid %u\r\n", sp->obj->xid);
sbuf_printf(sb, "\r\n");
......@@ -144,7 +144,7 @@ res_do_conds(struct sess *sp)
time_t ims;
if (sp->obj->last_modified > 0 &&
http_GetHdr(sp->http, "If-Modified-Since", &p)) {
http_GetHdr(sp->http, H_If_Modified_Since, &p)) {
ims = TIM_parse(p);
if (ims > sp->t_req) /* [RFC2616 14.25] */
return (0);
......@@ -187,14 +187,14 @@ RES_WriteObj(struct sess *sp)
sp->obj->age + sp->t_req - sp->obj->entered);
sbuf_printf(sb, "Via: 1.1 varnish\r\n");
sbuf_printf(sb, "X-Varnish: xid %u\r\n", sp->obj->xid);
if (strcmp(sp->http->proto, "HTTP/1.1"))
if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START], "HTTP/1.1"))
sbuf_printf(sb, "Connection: close\r\n");
sbuf_printf(sb, "\r\n");
sbuf_finish(sb);
RES_Write(sp, sbuf_data(sb), sbuf_len(sb));
bytes += sbuf_len(sb);
/* XXX: conditional request handling */
if (!strcmp(sp->http->req, "GET")) {
if (!strcmp(sp->http->hd[HTTP_HDR_REQ][HTTP_START], "GET")) {
TAILQ_FOREACH(st, &sp->obj->store, list) {
assert(st->stevedore != NULL);
u += st->len;
......
......@@ -32,7 +32,6 @@ struct sessmem {
struct sess sess;
struct http http;
char *http_hdr;
};
/*--------------------------------------------------------------------*/
......@@ -170,10 +169,7 @@ SES_New(struct sockaddr *addr, unsigned len)
(void)addr; /* XXX */
(void)len; /* XXX */
sm = calloc(
sizeof *sm +
heritage.mem_http_headers * sizeof sm->http_hdr +
heritage.mem_http_headerspace +
heritage.mem_workspace,
sizeof *sm + heritage.mem_workspace,
1);
if (sm == NULL)
return (NULL);
......@@ -182,7 +178,7 @@ SES_New(struct sockaddr *addr, unsigned len)
sm->sess.magic = SESS_MAGIC;
sm->sess.mem = sm;
sm->sess.http = &sm->http;
http_Init(&sm->http, (void *)(sm + 1));
http_Init(&sm->http, (void *)(sm + 1), heritage.mem_workspace);
return (&sm->sess);
}
......
......@@ -56,11 +56,12 @@ VRT_GetHdr(struct sess *sp, const char *n)
char *
VRT_GetReq(struct sess *sp)
{
char *p;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp != NULL);
assert(sp->http != NULL);
return (sp->http->req);
return (sp->http->hd[HTTP_HDR_REQ][HTTP_START]);
}
/*--------------------------------------------------------------------*/
......
......@@ -42,8 +42,6 @@ struct heritage {
unsigned wthread_timeout;
/* Memory allocation hints */
unsigned mem_http_headerspace;
unsigned mem_http_headers;
unsigned mem_workspace;
};
......
......@@ -83,10 +83,10 @@ RFC2616_Ttl(struct http *hp, time_t t_req, time_t t_resp, struct object *obj)
retirement_age = INT_MAX;
u1 = u2 = 0;
if (http_GetHdrField(hp, "Cache-Control", "max-age", &p)) {
if (http_GetHdrField(hp, H_Cache_Control, "max-age", &p)) {
u1 = strtoul(p, NULL, 0);
u2 = 0;
if (http_GetHdr(hp, "Age", &p)) {
if (http_GetHdr(hp, H_Age, &p)) {
u2 = strtoul(p, NULL, 0);
obj->age = u2;
}
......@@ -95,11 +95,11 @@ RFC2616_Ttl(struct http *hp, time_t t_req, time_t t_resp, struct object *obj)
}
h_date = 0;
if (http_GetHdr(hp, "Date", &p))
if (http_GetHdr(hp, H_Date, &p))
h_date = TIM_parse(p);
h_expires = 0;
if (http_GetHdr(hp, "Expires", &p))
if (http_GetHdr(hp, H_Expires, &p))
h_expires = TIM_parse(p);
if (h_date < t_req && h_expires > t_req) {
......
......@@ -543,9 +543,7 @@ main(int argc, char *argv[])
heritage.wthread_min = 1;
heritage.wthread_max = UINT_MAX;
heritage.wthread_timeout = 10;
heritage.mem_http_headerspace= 4096;
heritage.mem_http_headers= 32;
heritage.mem_workspace = 0;
heritage.mem_workspace = 4096;
while ((o = getopt(argc, argv, "b:df:h:p:s:t:w:")) != -1)
switch (o) {
......
......@@ -20,6 +20,7 @@ SLTM(BackendXID)
SLTM(BackendReuse)
SLTM(BackendClose)
SLTM(HttpError)
SLTM(HttpGarbage)
SLTM(ClientAddr)
SLTM(Backend)
SLTM(Request)
......
......@@ -689,7 +689,8 @@ HeaderVar(struct tokenlist *tl __unused, struct token *t, struct var *vh)
p[i] = '\0';
v->name = p;
v->fmt = STRING;
asprintf(&p, "VRT_GetHdr(sp, \"%s\")", v->name + vh->len);
asprintf(&p, "VRT_GetHdr(sp, \"\\%03o%s:\")",
strlen(v->name + vh->len) + 1, v->name + vh->len);
assert(p != NULL);
v->rname = p;
return (v);
......
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