#include #include #include "httpd.h" #include "httpsrv.h" // htmlquote // escape < as < to avoid cross-site scripting // escape > as > because some browsers "helpfully" insert < when seeing a > // because UTF-7 has other ways to write < // and escape & as & for appearance sake // caller should free static char * hq(char *text) { int textlen = strlen(text), escapedlen = textlen; char *escaped, *s, *w; for(s = text; *s; s++) if(*s=='<' || *s=='>' || *s=='&') escapedlen += 4; escaped = ezalloc(escapedlen+1); for(s = text, w = escaped; *s; s++){ if(*s == '<'){ strcpy(w, "<"); w += 4; }else if(*s == '>'){ strcpy(w, ">"); w += 4; }else if(*s == '&'){ strcpy(w, "&"); w += 5; }else{ *w++ = *s; } } return escaped; } static void hqwrite(Hio *hout, char *s, int n) { char *buf = ezalloc(n+1), *esc; memcpy(buf, s, n); buf[n] = 0; esc = hq(buf); hwrite(hout, esc, strlen(esc)); free(esc); free(buf); } void main(int argc, char **argv) { HConnect *c; Hio *hout, *hin; char *s; c = init(argc, argv); if(hparseheaders(c, 15*60*1000) < 0) exits("failed"); hout = &c->hout; if(c->head.expectother){ hfail(c, HExpectFail, nil); exits("failed"); } if(c->head.expectcont){ hprint(hout, "100 Continue\r\n"); hprint(hout, "\r\n"); hflush(hout); } if(c->req.vermaj){ hokheaders(c); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } hprint(hout, "Echo

Echo

\r\n"); hprint(hout, "You requested a %s, version HTTP/%d.%d on %s", hq(c->req.meth), c->req.vermaj, c->req.vermin, hq(c->req.uri)); if(c->req.search) hprint(hout, " with search string %s", hq(c->req.search)); hprint(hout, ".\n"); hprint(hout, "Your client sent the following headers:

\n");
	hqwrite(hout, (char*)(c->header), c->hstop - c->header);

	if(strcmp(c->req.meth, "POST") == 0){
		hin = hbodypush(&c->hin, c->head.contlen, c->head.transenc);
		if(hin == nil)
			hprint(hout, "

With an invalid or unsupported body length specification.

"); else{ hprint(hout, "with POSTed data:

\n'");
			alarm(15*60*1000);
			for(; s = hreadbuf(hin, hin->pos); hin->pos = hin->stop)
				hqwrite(hout, s, hbuflen(hin, s));
			alarm(0);
			hprint(hout, "'\n
"); } } hprint(hout, "
\n"); hflush(hout); writelog(c, "Reply: 200 echo %ld %ld\n", hout->seek, hout->seek); exits(nil); }