From e7bdd59acaca36a9a2dea95716abf454e35cf127 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Mon, 25 Apr 2016 15:09:22 +0200 Subject: [PATCH] lib: Added bufio variants of parseresponse/parseheaders/writeresp. --- lib/req.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/req.h | 5 +++ 2 files changed, 147 insertions(+) diff --git a/lib/req.c b/lib/req.c index ed5aeba..074e7df 100644 --- a/lib/req.c +++ b/lib/req.c @@ -32,6 +32,7 @@ #include #include #include +#include struct hthead *mkreq(char *method, char *url, char *ver) { @@ -164,6 +165,68 @@ fail: return(-1); } +int parseheadersb(struct hthead *head, struct bufio *in) +{ + int c, state; + struct charbuf name, val; + size_t tsz; + + bufinit(name); + bufinit(val); + state = 0; + tsz = 0; + while(1) { + c = biogetc(in); + if(++tsz >= 65536) + goto fail; + again: + if(state == 0) { + if(c == '\r') { + } else if(c == '\n') { + break; + } else if(c == EOF) { + goto fail; + } else { + state = 1; + goto again; + } + } else if(state == 1) { + if(c == ':') { + trim(&name); + bufadd(name, 0); + state = 2; + } else if(c == '\r') { + } else if(c == '\n') { + goto fail; + } else if(c == EOF) { + goto fail; + } else { + bufadd(name, c); + } + } else if(state == 2) { + if(c == '\r') { + } else if(c == '\n') { + trim(&val); + bufadd(val, 0); + headappheader(head, name.b, val.b); + buffree(name); + buffree(val); + state = 0; + } else if(c == EOF) { + goto fail; + } else { + bufadd(val, c); + } + } + } + return(0); + +fail: + buffree(name); + buffree(val); + return(-1); +} + struct hthead *parseresponse(FILE *in) { struct hthead *req; @@ -230,6 +293,72 @@ out: return(req); } +struct hthead *parseresponseb(struct bufio *in) +{ + struct hthead *req; + int code; + struct charbuf ver, msg; + int c; + + req = NULL; + bufinit(ver); + bufinit(msg); + code = 0; + while(1) { + c = biogetc(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 = biogetc(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 = biogetc(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(parseheadersb(req, in)) + goto fail; + goto out; + +fail: + if(req != NULL) { + freehthead(req); + req = NULL; + } +out: + buffree(msg); + buffree(ver); + return(req); +} + void replrest(struct hthead *head, char *rest) { char *tmp; @@ -290,6 +419,19 @@ int writeresp(FILE *out, struct hthead *resp) return(0); } +int writerespb(struct bufio *out, struct hthead *resp) +{ + int i; + + if(bioprintf(out, "%s %i %s\r\n", resp->ver, resp->code, resp->msg) < 0) + return(-1); + for(i = 0; i < resp->noheaders; i++) { + if(bioprintf(out, "%s: %s\r\n", resp->headers[i][0], resp->headers[i][1]) < 0) + return(-1); + } + return(0); +} + int sendreq2(int sock, struct hthead *req, int fd, int flags) { int ret, i; diff --git a/lib/req.h b/lib/req.h index 054d3c1..9ae60ab 100644 --- a/lib/req.h +++ b/lib/req.h @@ -3,6 +3,8 @@ #include +struct bufio; + struct hthead { char *method, *url, *ver, *msg; int code; @@ -23,8 +25,11 @@ int sendreq(int sock, struct hthead *req, int fd); int recvreq(int sock, struct hthead **reqp); void replrest(struct hthead *head, char *rest); int parseheaders(struct hthead *head, FILE *in); +int parseheadersb(struct hthead *head, struct bufio *in); struct hthead *parseresponse(FILE *in); +struct hthead *parseresponseb(struct bufio *in); int writeresp(FILE *out, struct hthead *resp); +int writerespb(struct bufio *out, struct hthead *resp); char *unquoteurl(char *in); #endif -- 2.11.0