[master] cf7c641 Add "rxchunk" primitive
Poul-Henning Kamp
phk at varnish-cache.org
Mon Apr 11 12:50:17 CEST 2011
commit cf7c641fe61f53b11ca3f15f517d99965f0511f9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Apr 11 10:29:18 2011 +0000
Add "rxchunk" primitive
diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c
index 74cf65f..3e0fbab 100644
--- a/bin/varnishtest/vtc_http.c
+++ b/bin/varnishtest/vtc_http.c
@@ -69,6 +69,7 @@ struct http {
char *body;
unsigned bodyl;
char bodylen[20];
+ char chunklen[20];
char *req[MAX_HDR];
char *resp[MAX_HDR];
@@ -191,6 +192,8 @@ cmd_var_resolve(struct http *hp, char *spec)
return(hp->resp[1]);
if (!strcmp(spec, "resp.msg"))
return(hp->resp[2]);
+ if (!strcmp(spec, "resp.chunklen"))
+ return(hp->chunklen);
if (!strcmp(spec, "resp.bodylen"))
return(hp->bodylen);
if (!memcmp(spec, "req.http.", 9)) {
@@ -371,6 +374,47 @@ http_rxchar(struct http *hp, int n)
assert(i > 0);
}
+static int
+http_rxchunk(struct http *hp)
+{
+ char *q;
+ int l, i;
+
+ l = hp->prxbuf;
+ do
+ http_rxchar(hp, 1);
+ while (hp->rxbuf[hp->prxbuf - 1] != '\n');
+ vtc_dump(hp->vl, 4, "len", hp->rxbuf + l, -1);
+ i = strtoul(hp->rxbuf + l, &q, 16);
+ bprintf(hp->chunklen, "%d", i);
+ if ((q == hp->rxbuf + l) ||
+ (*q != '\0' && !vct_islws(*q))) {
+ vtc_log(hp->vl, 0, "chunked fail %02x @ %d",
+ *q, q - (hp->rxbuf + l));
+ }
+ assert(q != hp->rxbuf + l);
+ assert(*q == '\0' || vct_islws(*q));
+ hp->prxbuf = l;
+ if (i > 0) {
+ http_rxchar(hp, i);
+ vtc_dump(hp->vl, 4, "chunk",
+ hp->rxbuf + l, i);
+ }
+ l = hp->prxbuf;
+ http_rxchar(hp, 2);
+ if(!vct_iscrlf(hp->rxbuf[l]))
+ vtc_log(hp->vl, 0,
+ "Wrong chunk tail[0] = %02x",
+ hp->rxbuf[l] & 0xff);
+ if(!vct_iscrlf(hp->rxbuf[l + 1]))
+ vtc_log(hp->vl, 0,
+ "Wrong chunk tail[1] = %02x",
+ hp->rxbuf[l + 1] & 0xff);
+ hp->prxbuf = l;
+ hp->rxbuf[l] = '\0';
+ return (i);
+}
+
/**********************************************************************
* Swallow a HTTP message body
*/
@@ -378,15 +422,13 @@ http_rxchar(struct http *hp, int n)
static void
http_swallow_body(struct http *hp, char * const *hh, int body)
{
- char *p, *q;
+ char *p;
int i, l, ll;
-
ll = 0;
p = http_find_header(hh, "content-length");
if (p != NULL) {
l = strtoul(p, NULL, 0);
- hp->body = hp->rxbuf + hp->prxbuf;
http_rxchar(hp, l);
vtc_dump(hp->vl, 4, "body", hp->body, l);
hp->bodyl = l;
@@ -395,44 +437,10 @@ http_swallow_body(struct http *hp, char * const *hh, int body)
}
p = http_find_header(hh, "transfer-encoding");
if (p != NULL && !strcmp(p, "chunked")) {
- hp->body = hp->rxbuf + hp->prxbuf;
- while (1) {
- l = hp->prxbuf;
- do
- http_rxchar(hp, 1);
- while (hp->rxbuf[hp->prxbuf - 1] != '\n');
- vtc_dump(hp->vl, 4, "len", hp->rxbuf + l, -1);
- i = strtoul(hp->rxbuf + l, &q, 16);
- if ((q == hp->rxbuf + l) ||
- (*q != '\0' && !vct_islws(*q))) {
- vtc_log(hp->vl, 0, "chunked fail %02x @ %d",
- *q, q - (hp->rxbuf + l));
- }
- assert(q != hp->rxbuf + l);
- assert(*q == '\0' || vct_islws(*q));
- hp->prxbuf = l;
- if (i > 0) {
- ll += i;
- http_rxchar(hp, i);
- vtc_dump(hp->vl, 4, "chunk",
- hp->rxbuf + l, i);
- }
- l = hp->prxbuf;
- http_rxchar(hp, 2);
- if(!vct_iscrlf(hp->rxbuf[l]))
- vtc_log(hp->vl, 0,
- "Wrong chunk tail[0] = %02x",
- hp->rxbuf[l] & 0xff);
- if(!vct_iscrlf(hp->rxbuf[l + 1]))
- vtc_log(hp->vl, 0,
- "Wrong chunk tail[1] = %02x",
- hp->rxbuf[l + 1] & 0xff);
- hp->prxbuf = l;
- hp->rxbuf[l] = '\0';
- if (i == 0)
- break;
- }
+ while (http_rxchunk(hp) != 0)
+ continue;
vtc_dump(hp->vl, 4, "body", hp->body, ll);
+ ll = hp->rxbuf + hp->prxbuf - hp->body;
hp->bodyl = ll;
sprintf(hp->bodylen, "%d", ll);
return;
@@ -505,8 +513,9 @@ cmd_http_rxresp(CMD_ARGS)
"Unknown http rxresp spec: %s\n", *av);
http_rxhdr(hp);
http_splitheader(hp, 0);
+ hp->body = hp->rxbuf + hp->prxbuf;
if (!has_obj)
- ;
+ return;
else if (!strcmp(hp->resp[1], "200"))
http_swallow_body(hp, hp->resp, 1);
else
@@ -787,6 +796,26 @@ cmd_http_rxbody(CMD_ARGS)
vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen);
}
+static void
+cmd_http_rxchunk(CMD_ARGS)
+{
+ struct http *hp;
+ int ll, i;
+
+ (void)cmd;
+ (void)vl;
+ CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
+ ONLY_CLIENT(hp, av);
+
+ i = http_rxchunk(hp);
+ if (i == 0) {
+ ll = hp->rxbuf + hp->prxbuf - hp->body;
+ hp->bodyl = ll;
+ sprintf(hp->bodylen, "%d", ll);
+ vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen);
+ }
+}
+
/**********************************************************************
* Transmit a request
*/
@@ -1043,6 +1072,7 @@ static const struct cmds http_cmds[] = {
{ "rxreq", cmd_http_rxreq },
{ "rxhdrs", cmd_http_rxhdrs },
+ { "rxchunk", cmd_http_rxchunk },
{ "rxbody", cmd_http_rxbody },
{ "txresp", cmd_http_txresp },
More information about the varnish-commit
mailing list