int hnotfound(HConnect *c) { int r; r = preq(c); if(r < 0) return r; return hfail(c, HNotFound, c->req.uri); }
static int preq(HConnect *c) { if(hparseheaders(c, 0) < 0) return -1; if(strcmp(c->req.meth, "GET") != 0 && strcmp(c->req.meth, "HEAD") != 0) return hunallowed(c, "GET, HEAD"); if(c->head.expectother || c->head.expectcont) return hfail(c, HExpectFail, nil); return 0; }
void main(int argc, char **argv) { fmtinstall('H', httpfmt); fmtinstall('U', hurlfmt); fmtinstall('M', dirmodefmt); aio = Bopen("/sys/lib/webls.allowed", OREAD); dio = Bopen("/sys/lib/webls.denied", OREAD); if(argc == 2){ hinit(&houtb, 1, Hwrite); hout = &houtb; dols(argv[1]); exits(nil); } close(2); connect = init(argc, argv); hout = &connect->hout; vermaj = connect->req.vermaj; if(hparseheaders(connect, HSTIMEOUT) < 0) exits("failed"); if(strcmp(connect->req.meth, "GET") != 0 && strcmp(connect->req.meth, "HEAD") != 0){ hunallowed(connect, "GET, HEAD"); exits("not allowed"); } if(connect->head.expectother || connect->head.expectcont){ hfail(connect, HExpectFail, nil); exits("failed"); } bind("/usr/web", "/", MREPL); if(connect->req.search != nil) dosearch(connect->req.search); else error("Bad argument", "<p>Need a search argument</p>"); hflush(hout); writelog(connect, "200 webls %ld %ld\n", hout->seek, hout->seek); exits(nil); }
void main(int argc, char **argv) { fmtinstall('H', httpfmt); fmtinstall('U', hurlfmt); if(argc == 2){ hinit(&houtb, 1, Hwrite); hout = &houtb; doconvert(argv[1], 0); exits(nil); } close(2); connect = init(argc, argv); hout = &connect->hout; if(hparseheaders(connect, HSTIMEOUT) < 0) exits("failed"); if(strcmp(connect->req.meth, "GET") != 0 && strcmp(connect->req.meth, "HEAD") != 0){ hunallowed(connect, "GET, HEAD"); exits("not allowed"); } if(connect->head.expectother || connect->head.expectcont){ hfail(connect, HExpectFail, nil); exits("failed"); } bind("/usr/web/sys/man", "/sys/man", MREPL); if(connect->req.search != nil) dosearch(connect->req.vermaj, connect->req.search); else doconvert(connect->req.uri, connect->req.vermaj); hflush(hout); writelog(connect, "200 man2html %ld %ld\n", hout->seek, hout->seek); exits(nil); }
/* * parse the next request line * returns: * 1 ok * 0 eof * -1 error */ int hparsereq(HConnect *c, int timeout) { Strings ss; char *vs, *v, *search, *uri, *origuri, *extra; if(c->bin != nil){ hfail(c, HInternal); return -1; } /* * serve requests until a magic request. * later requests have to come quickly. * only works for http/1.1 or later. */ if(timeout) alarm(timeout); if(hgethead(c, 0) < 0) return -1; if(timeout) alarm(0); c->reqtime = time(nil); c->req.meth = getword(c); if(c->req.meth == nil){ hfail(c, HSyntax); return -1; } uri = getword(c); if(uri == nil || strlen(uri) == 0){ hfail(c, HSyntax); return -1; } v = getword(c); if(v == nil){ if(strcmp(c->req.meth, "GET") != 0){ hfail(c, HUnimp, c->req.meth); return -1; } c->req.vermaj = 0; c->req.vermin = 9; }else{ vs = v; if(strncmp(vs, "HTTP/", 5) != 0){ hfail(c, HUnkVers, vs); return -1; } vs += 5; c->req.vermaj = strtoul(vs, &vs, 10); if(*vs != '.' || c->req.vermaj != 1){ hfail(c, HUnkVers, vs); return -1; } vs++; c->req.vermin = strtoul(vs, &vs, 10); if(*vs != '\0'){ hfail(c, HUnkVers, vs); return -1; } extra = getword(c); if(extra != nil){ hfail(c, HSyntax); return -1; } } /* * the fragment is not supposed to be sent * strip it 'cause some clients send it */ origuri = uri; uri = strchr(origuri, '#'); if(uri != nil) *uri = 0; /* * http/1.1 requires the server to accept absolute * or relative uri's. convert to relative with an absolute path */ if(http11(c)){ ss = parseuri(c, origuri); uri = ss.s1; c->req.urihost = ss.s2; if(uri == nil){ hfail(c, HBadReq, uri); return -1; } origuri = uri; } /* * munge uri for search, protection, and magic */ ss = stripsearch(origuri); origuri = ss.s1; search = ss.s2; uri = hurlunesc(c, origuri); uri = abspath(c, uri, "/"); if(uri == nil || uri[0] == '\0'){ hfail(c, HNotFound, "no object specified"); return -1; } c->req.uri = uri; c->req.search = search; if(search) c->req.searchpairs = hparsequery(c, hstrdup(c, search)); return 1; }
void main(int argc, char **argv) { HConnect *c; Dir *dir; Hio *hin, *hout; char *s, *t, *fn; int n, nfn, datafd, htmlfd; c = init(argc, argv); if(dangerous(c->req.uri)){ hfail(c, HSyntax); exits("failed"); } if(hparseheaders(c, HSTIMEOUT) < 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); } s = nil; if(strcmp(c->req.meth, "POST") == 0){ hin = hbodypush(&c->hin, c->head.contlen, c->head.transenc); if(hin != nil){ alarm(HSTIMEOUT); s = hreadbuf(hin, hin->pos); alarm(0); } if(s == nil){ hfail(c, HBadReq, nil); exits("failed"); } t = strchr(s, '\n'); if(t != nil) *t = '\0'; }else if(strcmp(c->req.meth, "GET") != 0 && strcmp(c->req.meth, "HEAD") != 0){ hunallowed(c, "GET, HEAD, PUT"); exits("unallowed"); }else s = c->req.search; if(s == nil){ hfail(c, HNoData, "save"); exits("failed"); } if(strlen(s) > MaxLog) s[MaxLog] = '\0'; n = snprint(c->xferbuf, HBufSize, "at %ld %s\n", time(0), s); nfn = strlen(c->req.uri) + 64; fn = halloc(c, nfn); /* * open file descriptors & write log line */ snprint(fn, nfn, "/usr/web/save/%s.html", c->req.uri); htmlfd = open(fn, OREAD); if(htmlfd < 0 || (dir = dirfstat(htmlfd)) == nil){ hfail(c, HNotFound, c->req.uri); exits("failed"); return; } snprint(fn, nfn, "/usr/web/save/%s.data", c->req.uri); datafd = openLocked(fn, OWRITE); if(datafd < 0){ errstr(c->xferbuf, sizeof c->xferbuf); if(strstr(c->xferbuf, "locked") != nil) hfail(c, HTempFail, c->req.uri); else hfail(c, HNotFound, c->req.uri); exits("failed"); } seek(datafd, 0, 2); write(datafd, c->xferbuf, n); close(datafd); sendfd(c, htmlfd, dir, hmkcontent(c, "text", "html", nil), nil); exits(nil); }