int redirectorStreamHandler1(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { RedirectRequestPtr request = (RedirectRequestPtr)srequest->data; if(status) { if(status >= 0) status = -EPIPE; do_log_error(L_ERROR, -status, "Write to redirector failed"); goto fail; } if(!streamRequestDone(srequest)) return 0; do_stream(IO_READ, redirector_read_fd, 0, redirector_buffer, REDIRECTOR_BUFFER_SIZE, redirectorStreamHandler2, request); return 1; fail: request->handler(status < 0 ? status : -EPIPE, request->url, NULL, NULL, request->data); redirectorDestroyRequest(request); redirectorKill(); return 1; }
void initForbidden(void) { redirectorKill(); if(forbiddenFile) forbiddenFile = expandTilde(forbiddenFile); if(forbiddenFile == NULL) { forbiddenFile = expandTilde(internAtom("~/.polipo-forbidden")); if(forbiddenFile) { if(access(forbiddenFile->string, F_OK) < 0) { releaseAtom(forbiddenFile); forbiddenFile = NULL; } } } if(forbiddenFile == NULL) { if(access("/etc/polipo/forbidden", F_OK) >= 0) forbiddenFile = internAtom("/etc/polipo/forbidden"); } parseDomainFile(forbiddenFile, &forbiddenDomains, &forbiddenRegex); if(uncachableFile) uncachableFile = expandTilde(uncachableFile); if(uncachableFile == NULL) { uncachableFile = expandTilde(internAtom("~/.polipo-uncachable")); if(uncachableFile) { if(access(uncachableFile->string, F_OK) < 0) { releaseAtom(uncachableFile); uncachableFile = NULL; } } } if(uncachableFile == NULL) { if(access("/etc/polipo/uncachable", F_OK) >= 0) uncachableFile = internAtom("/etc/polipo/uncachable"); } parseDomainFile(uncachableFile, &uncachableDomains, &uncachableRegex); return; }
int redirectorStreamHandler2(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { RedirectRequestPtr request = (RedirectRequestPtr)srequest->data; char *c; AtomPtr message; AtomPtr headers; int code; if(status < 0) { do_log_error(L_ERROR, -status, "Read from redirector failed"); request->handler(status, request->url, NULL, NULL, request->data); goto kill; } c = memchr(redirector_buffer, '\n', srequest->offset); if(!c) { if(!status && srequest->offset < REDIRECTOR_BUFFER_SIZE) return 0; do_log(L_ERROR, "Redirector returned incomplete reply.\n"); request->handler(-EREDIRECTOR, request->url, NULL, NULL, request->data); goto kill; } *c = '\0'; if(srequest->offset > c + 1 - redirector_buffer) do_log(L_WARN, "Stray bytes in redirector output.\n"); if(c > redirector_buffer + 1 && (c - redirector_buffer != request->url->length || memcmp(redirector_buffer, request->url->string, request->url->length) != 0)) { code = redirectorRedirectCode; message = internAtom("Redirected by external redirector"); if(message == NULL) { request->handler(-ENOMEM, request->url, NULL, NULL, request->data); goto kill; } headers = internAtomF("\r\nLocation: %s", redirector_buffer); if(headers == NULL) { releaseAtom(message); request->handler(-ENOMEM, request->url, NULL, NULL, request->data); goto kill; } } else { code = 0; message = NULL; headers = NULL; } request->handler(code, request->url, message, headers, request->data); goto cont; cont: redirectorDestroyRequest(request); redirectorTrigger(); return 1; kill: redirectorKill(); goto cont; }
int redirectorStreamHandler2(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { RedirectRequestPtr request = (RedirectRequestPtr)srequest->data; char *c, *c2, *buf; AtomPtr url = request->url; AtomPtr message = NULL; AtomPtr headers = NULL; int code = 0; if(status < 0) { do_log_error(L_ERROR, -status, "Read from redirector failed"); request->handler(status, request->url, NULL, NULL, request->data); goto kill; } c = memchr(redirector_buffer, '\n', srequest->offset); if(!c) { if(!status && srequest->offset < REDIRECTOR_BUFFER_SIZE) return 0; do_log(L_ERROR, "Redirector returned incomplete reply.\n"); request->handler(-EREDIRECTOR, request->url, NULL, NULL, request->data); goto kill; } c2 = memchr(redirector_buffer, ' ', srequest->offset); if (c2 != NULL) c = c2; *c = '\0'; buf = redirector_buffer; if (digit(buf[0]) && digit(buf[1]) && digit(buf[2]) && buf[3] == ':') { code = strtol(buf, NULL, 10); buf += 4; } if(c > buf + 1 && (c - buf != request->url->length || memcmp(buf, request->url->string, request->url->length) != 0)) { if (!redirectorIsServerSide || (300 <= code && code <= 399)) { if (!(300 <= code && code <= 399)) code = redirectorRedirectCode; message = internAtom("Redirected by external redirector"); if(message == NULL) { request->handler(-ENOMEM, request->url, NULL, NULL, request->data); goto kill; } headers = internAtomF("\r\nLocation: %s", redirector_buffer); if(headers == NULL) { releaseAtom(message); request->handler(-ENOMEM, request->url, NULL, NULL, request->data); goto kill; } } else { url = internAtom(buf); if(url == NULL) { request->handler(-ENOMEM, request->url, NULL, NULL, request->data); goto kill; } } } request->handler(code, url, message, headers, request->data); goto cont; cont: redirectorDestroyRequest(request); redirectorTrigger(); return 1; kill: redirectorKill(); goto cont; }