X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fhtparser.c;h=4086f7926eacc01fc17c15c5d4c3cf757ef751f0;hb=9e70ef793ddcf51edc0f6489eb6f70762380afc0;hp=bc8f7fd3a5f7be4fe27509bdf9d29eaa7ef34cd2;hpb=64a9096a7cd4acf3bbf4a7bf4a214f4b5cca7fdc;p=ashd.git diff --git a/src/htparser.c b/src/htparser.c index bc8f7fd..4086f79 100644 --- a/src/htparser.c +++ b/src/htparser.c @@ -127,72 +127,6 @@ out: return(req); } -static struct hthead *parseresp(FILE *in) -{ - struct hthead *req; - int code; - struct charbuf ver, msg; - int c; - - req = NULL; - bufinit(ver); - bufinit(msg); - code = 0; - while(1) { - c = getc(in); - if(c == ' ') { - break; - } else if((c == EOF) || (c < 32) || (c >= 128)) { - goto fail; - } else { - bufadd(ver, c); - if(ver.d >= 128) - goto fail; - } - } - while(1) { - c = getc(in); - if(c == ' ') { - break; - } else if((c == EOF) || (c < '0') || (c > '9')) { - goto fail; - } else { - code = (code * 10) + (c - '0'); - if(code >= 10000) - goto fail; - } - } - while(1) { - c = getc(in); - if(c == 10) { - break; - } else if(c == 13) { - } else if((c == EOF) || (c < 32)) { - goto fail; - } else { - bufadd(msg, c); - if(msg.d >= 512) - goto fail; - } - } - bufadd(msg, 0); - bufadd(ver, 0); - req = mkresp(code, msg.b, ver.b); - if(parseheaders(req, in)) - goto fail; - goto out; - -fail: - if(req != NULL) { - freehthead(req); - req = NULL; - } -out: - buffree(msg); - buffree(ver); - return(req); -} - static off_t passdata(FILE *in, FILE *out, off_t max) { size_t read; @@ -278,6 +212,20 @@ static int canonreq(struct hthead *req) return(0); } +static int http10keep(struct hthead *req, struct hthead *resp) +{ + int fc; + + fc = hasheader(resp, "connection", "close"); + headrmheader(resp, "connection"); + if(!fc && hasheader(req, "connection", "keep-alive")) { + headappheader(resp, "Connection", "Keep-Alive"); + return(1); + } else { + return(0); + } +} + void serve(FILE *in, struct conn *conn) { int pfds[2]; @@ -285,6 +233,7 @@ void serve(FILE *in, struct conn *conn) struct hthead *req, *resp; char *hd; off_t dlen; + int keep; out = NULL; req = resp = NULL; @@ -318,7 +267,7 @@ void serve(FILE *in, struct conn *conn) /* Make sure to send EOF */ shutdown(pfds[1], SHUT_WR); - if((resp = parseresp(out)) == NULL) + if((resp = parseresponse(out)) == NULL) break; replstr(&resp->ver, req->ver); @@ -326,22 +275,25 @@ void serve(FILE *in, struct conn *conn) headappheader(resp, "Server", sprintf3("ashd/%s", VERSION)); if(!strcmp(req->ver, "HTTP/1.0")) { - writeresp(in, resp); - fprintf(in, "\r\n"); if(!strcasecmp(req->method, "head")) { - if(!hasheader(req, "connection", "keep-alive")) - break; + keep = http10keep(req, resp); + writeresp(in, resp); + fprintf(in, "\r\n"); } else if((hd = getheader(resp, "content-length")) != NULL) { + keep = http10keep(req, resp); dlen = atoo(hd); + writeresp(in, resp); + fprintf(in, "\r\n"); if(passdata(out, in, dlen) != dlen) break; - if(!hasheader(req, "connection", "keep-alive")) - break; } else { + headrmheader(resp, "connection"); + writeresp(in, resp); + fprintf(in, "\r\n"); passdata(out, in, -1); break; } - if(hasheader(req, "connection", "close") || hasheader(resp, "connection", "close")) + if(!keep) break; } else if(!strcmp(req->ver, "HTTP/1.1")) { if(!strcasecmp(req->method, "head")) {