int main(int argc, char **argv) { struct ProxyStruct proxystruct; int s, f, size, rv, parsed_headers=0; char recv_buf[8192]; /* Make sure stuff sane */ pre_check(); proxystruct=parseuri(GETENV("REQUEST_URI")); #ifdef UGLY_DEBUG fprintf(stderr, "URL: %s\nURI: %s\nFile: %s\n", proxystruct.request_url, proxystruct.request_uri, proxystruct.file); fprintf(stderr, "URL Structure:\n\tHost: %s\n\tPort: %d\n\tURI: %s\n", proxystruct.url.host, proxystruct.url.port, proxystruct.url.req); fprintf(stderr, proxystruct.url.httpreq); #endif /* UGLY_DEBUG */ /* Make sure we allow access to this host and port (and what not) */ if(check_auth(proxystruct)==FALSE) { do_error(403, "text/plain", "You are not authorized to do get this."); } else { ensurepath(proxystruct.file); f=open(proxystruct.tmpfile, O_WRONLY|O_CREAT|O_EXCL, 0644); if(f<0) { perror(proxystruct.tmpfile); } s=start_request(proxystruct); while( (size=recv(s, recv_buf, sizeof(recv_buf), 0)) > 0) { if(parsed_headers==0) { parsed_headers=parse_headers(recv_buf, &size); } rv=write(1, recv_buf, size); assert(rv==size); if(f>=0) { rv=write(f, recv_buf, size); assert(rv==size); } } /* Save it */ if(rename(proxystruct.tmpfile, proxystruct.file)<0) { perror(proxystruct.file); } } return(0); }
/* * 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; }