Commit 31c4e1b4 authored by Dag Erling Smørgrav's avatar Dag Erling Smørgrav

Rewrite pass_chunked().

git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@785 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 5f181d03
...@@ -61,8 +61,7 @@ static int ...@@ -61,8 +61,7 @@ static int
pass_chunked(struct sess *sp, int fd, struct http *hp) pass_chunked(struct sess *sp, int fd, struct http *hp)
{ {
int i, j; int i, j;
char *b, *q, *e; char *p, *q;
char *p;
unsigned u; unsigned u;
char buf[PASS_BUFSIZ]; char buf[PASS_BUFSIZ];
char *bp, *be; char *bp, *be;
...@@ -76,62 +75,64 @@ pass_chunked(struct sess *sp, int fd, struct http *hp) ...@@ -76,62 +75,64 @@ pass_chunked(struct sess *sp, int fd, struct http *hp)
p = buf; p = buf;
while (1) { while (1) {
i = http_Read(hp, fd, bp, be - bp); i = http_Read(hp, fd, bp, be - bp);
i = read(fd, bp, be - bp); assert(i >= 0);
assert(i > 0); if (i == 0 && p == bp)
break;
bp += i; bp += i;
/* buffer valid from p to bp */ /* buffer valid from p to bp */
assert(bp >= p);
/* chunk starts with f("%x\r\n", len) */
u = strtoul(p, &q, 16); u = strtoul(p, &q, 16);
if (q == NULL || (*q != '\n' && *q != '\r')) { while (q && q < bp && *q == ' ')
INCOMPL(); /* shouldn't happen - but sometimes it does */
/* XXX: move bp to buf start, get more */ q++;
if (q == NULL || q > bp - 2 /* want \r\n in same buffer */) {
/* short - move to start of buffer and extend */
memmove(buf, p, bp - p);
bp -= p - buf;
p = buf;
continue;
} }
if (*q == '\r') assert(*q == '\r');
q++; q++;
assert(*q == '\n'); assert(*q == '\n');
q++; q++;
if (u == 0)
break;
/* we just received the final zero-length chunk */
if (u == 0) {
sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, q - p); sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, q - p);
break;
}
/* include chunk header */
u += q - p;
p = q; /* include trailing \r\n with chunk */
u += 2;
while (u > 0) { for (;;) {
j = u; j = u;
if (bp == p) {
bp = p = buf;
break;
}
if (bp - p < j) if (bp - p < j)
j = bp - p; j = bp - p;
sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, j); sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, j);
WRK_Flush(sp->wrk);
p += j; p += j;
u -= j; u -= j;
} assert(u >= 0);
while (u > 0) { if (u == 0)
if (http_GetTail(hp, u, &b, &e)) {
j = e - b;
sp->wrk->acct.bodybytes +=
WRK_Write(sp->wrk, q, j);
u -= j;
} else
break; break;
} p = bp = buf;
if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
while (u > 0) {
j = u; j = u;
if (j > sizeof buf) if (j > be - bp)
j = sizeof buf; j = be - bp;
i = read(fd, buf, j); i = http_Read(hp, fd, bp, j);
assert(i > 0); assert(i > 0);
sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, buf, i); bp += i;
u -= i;
if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
} }
} }
if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
return (0); return (0);
} }
...@@ -155,6 +156,9 @@ PassBody(struct sess *sp) ...@@ -155,6 +156,9 @@ PassBody(struct sess *sp)
http_CopyResp(sp->fd, sp->http, vc->http); http_CopyResp(sp->fd, sp->http, vc->http);
http_FilterHeader(sp->fd, sp->http, vc->http, HTTPH_A_PASS); http_FilterHeader(sp->fd, sp->http, vc->http, HTTPH_A_PASS);
http_PrintfHeader(sp->fd, sp->http, "X-Varnish: %u", sp->xid); http_PrintfHeader(sp->fd, sp->http, "X-Varnish: %u", sp->xid);
/* XXX */
if (http_HdrIs(vc->http, H_Transfer_Encoding, "chunked"))
http_PrintfHeader(sp->fd, sp->http, "Transfer-Encoding: chunked");
WRK_Reset(sp->wrk, &sp->fd); WRK_Reset(sp->wrk, &sp->fd);
sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1); sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
......
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