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

Add "rxchunk" primitive

parent 2eae6679
......@@ -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 },
......
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