X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=blobdiff_plain;f=lib%2Fresp.c;h=52fbd4b12f8eeab0c25621810c8c6292841d1bf8;hp=9d7325bcd0199ba9f01f8653e97ab8d4b3b8b010;hb=65e8a9a08a303b49015ac21c951576f10831415d;hpb=2f43c22d6b0889674abff5e0876799b0e98606c1 diff --git a/lib/resp.c b/lib/resp.c index 9d7325b..52fbd4b 100644 --- a/lib/resp.c +++ b/lib/resp.c @@ -30,10 +30,45 @@ #include #include +static char safechars[128] = { + /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, +}; + +char *urlquote(char *text) +{ + static char *ret = NULL; + struct charbuf buf; + unsigned char c; + + if(ret != NULL) + free(ret); + bufinit(buf); + for(; *text; text++) { + c = *text; + if(!c < 128 && safechars[(int)c]) + bufadd(buf, *text); + else + bprintf(&buf, "%%%02X", (int)c); + } + bufadd(buf, 0); + return(ret = buf.b); +} + char *htmlquote(char *text) { + static char *ret = NULL; struct charbuf buf; + if(ret != NULL) + free(ret); bufinit(buf); for(; *text; text++) { if(*text == '<') @@ -42,25 +77,21 @@ char *htmlquote(char *text) bufcatstr(buf, ">"); else if(*text == '&') bufcatstr(buf, "&"); + else if(*text == '\"') + bufcatstr(buf, """); else bufadd(buf, *text); } bufadd(buf, 0); - return(buf.b); + return(ret = buf.b); } -void simpleerror(int fd, int code, char *msg, char *fmt, ...) +static void simpleerror2v(FILE *out, int code, char *msg, char *fmt, va_list args) { struct charbuf buf; - char *tmp1, *tmp2; - va_list args; - FILE *out; + char *tmp; - va_start(args, fmt); - tmp1 = vsprintf2(fmt, args); - va_end(args); - tmp2 = htmlquote(tmp1); - free(tmp1); + tmp = vsprintf2(fmt, args); bufinit(buf); bufcatstr(buf, "\r\n"); bufcatstr(buf, "\r\n"); @@ -70,24 +101,43 @@ void simpleerror(int fd, int code, char *msg, char *fmt, ...) bufcatstr(buf, "\r\n"); bufcatstr(buf, "\r\n"); bprintf(&buf, "

%s

\r\n", msg); - bprintf(&buf, "

%s

\r\n", tmp2); + bprintf(&buf, "

%s

\r\n", htmlquote(tmp)); bufcatstr(buf, "\r\n"); bufcatstr(buf, "\r\n"); - free(tmp2); - out = fdopen(dup(fd), "w"); fprintf(out, "HTTP/1.1 %i %s\n", code, msg); fprintf(out, "Content-Type: text/html\n"); fprintf(out, "Content-Length: %zi\n", buf.d); fprintf(out, "\n"); fwrite(buf.b, 1, buf.d, out); - fclose(out); buffree(buf); + free(tmp); +} + +void simpleerror2(FILE *out, int code, char *msg, char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + simpleerror2v(out, code, msg, fmt, args); + va_end(args); +} + +void simpleerror(int fd, int code, char *msg, char *fmt, ...) +{ + va_list args; + FILE *out; + + va_start(args, fmt); + out = fdopen(dup(fd), "w"); + simpleerror2v(out, code, msg, fmt, args); + fclose(out); + va_end(args); } void stdredir(struct hthead *req, int fd, int code, char *dst) { FILE *out; - char *sp, *cp, *ep, *path, *url, *adst, *proto, *host; + char *sp, *cp, *ep, *qs, *path, *url, *adst, *proto, *host; sp = strchr(dst, '/'); cp = strchr(dst, ':'); @@ -106,11 +156,14 @@ void stdredir(struct hthead *req, int fd, int code, char *dst) } else { if((*(url = req->url)) == '/') url++; - if((ep = strrchr(url, '/')) != NULL) - ep++; - else - ep = url; - path = sprintf2("%.*s%s", ep - url, url, dst); + if((ep = strchr(url, '?')) == NULL) { + ep = url + strlen(url); + qs = ""; + } else { + qs = ep; + } + for(; (ep > url) && (ep[-1] != '/'); ep--); + path = sprintf2("%.*s%s%s", ep - url, url, dst, qs); } adst = sprintf2("%s://%s/%s", proto, host, path); free(path);