static int tunnelHandlerParent(int fd, TunnelPtr tunnel) { char *message; int n; if(tunnel->buf1.buf == NULL) tunnel->buf1.buf = get_chunk(); if(tunnel->buf1.buf == NULL) { message = "Couldn't allocate buffer"; goto fail; } if(tunnel->buf1.tail != tunnel->buf1.head) { message = "Pipelined connect to parent proxy not implemented"; goto fail; } n = snnprintf(tunnel->buf1.buf, tunnel->buf1.tail, CHUNK_SIZE, "CONNECT %s:%d HTTP/1.1", tunnel->hostname->string, tunnel->port); if (parentAuthCredentials) n = buildServerAuthHeaders(tunnel->buf1.buf, n, CHUNK_SIZE, parentAuthCredentials); n = snnprintf(tunnel->buf1.buf, n, CHUNK_SIZE, "\r\n\r\n"); if(n < 0) { message = "Buffer overflow"; goto fail; } tunnel->buf1.head = n; tunnelDispatch(tunnel); return 1; fail: CLOSE(fd); tunnel->fd2 = -1; tunnelError(tunnel, 501, internAtom(message)); return 1; }
int readDomainFile(char *filename) { FILE *in; char buf[512]; char *rs; int i, j, is_regex, start; in = fopen(filename, "r"); if(in == NULL) { if(errno != ENOENT) do_log_error(L_ERROR, errno, "Couldn't open file %s", filename); return -1; } while(1) { rs = fgets(buf, 512, in); if(rs == NULL) break; for(i = 0; i < 512; i++) { if(buf[i] != ' ' && buf[i] != '\t') break; } start = i; for(i = start; i < 512; i++) { if(buf[i] == '#' || buf[i] == '\r' || buf[i] == '\n') break; } while(i > start) { if(buf[i - 1] != ' ' && buf[i - 1] != '\t') break; i--; } if(i <= start) continue; /* The significant part of the line is now between start and i */ is_regex = 0; for(j = start; j < i; j++) { if(buf[j] == '\\' || buf[j] == '*' || buf[j] == '/') { is_regex = 1; break; } } if(is_regex) { while(rlen + i - start + 8 >= rsize) { char *new_regexbuf; new_regexbuf = realloc(regexbuf, rsize * 2 + 1); if(new_regexbuf == NULL) { do_log(L_ERROR, "Couldn't reallocate regex.\n"); fclose(in); return -1; } regexbuf = new_regexbuf; rsize = rsize * 2 + 1; } if(rlen != 0) rlen = snnprintf(regexbuf, rlen, rsize, "|"); rlen = snnprintf(regexbuf, rlen, rsize, "("); rlen = snnprint_n(regexbuf, rlen, rsize, buf + start, i - start); rlen = snnprintf(regexbuf, rlen, rsize, ")"); } else { DomainPtr new_domain; if(dlen >= dsize - 1) { DomainPtr *new_domains; new_domains = realloc(domains, (dsize * 2 + 1) * sizeof(DomainPtr)); if(new_domains == NULL) { do_log(L_ERROR, "Couldn't reallocate domain list.\n"); fclose(in); return -1; } domains = new_domains; dsize = dsize * 2 + 1; } new_domain = malloc(sizeof(DomainRec) - 1 + i - start); if(new_domain == NULL) { do_log(L_ERROR, "Couldn't allocate domain.\n"); fclose(in); return -1; } new_domain->length = i - start; memcpy(new_domain->domain, buf + start, i - start); domains[dlen++] = new_domain; } } fclose(in); return 1; }
int httpSpecialRequest(ObjectPtr object, int method, int from, int to, HTTPRequestPtr requestor, void *closure) { char buffer[1024]; int hlen; if (method >= METHOD_POST) { return httpSpecialSideRequest(object, method, from, to, requestor, closure); } if (!(object->flags & OBJECT_INITIAL)) { privatiseObject(object, 0); supersedeObject(object); object->flags &= ~(OBJECT_VALIDATING | OBJECT_INPROGRESS); notifyObject(object); return 1; } hlen = snnprintf(buffer, 0, 1024, "\r\nServer: s_server" "\r\nContent-Type: text/html"); object->date = current_time.tv_sec; object->age = current_time.tv_sec; object->headers = internAtomN(buffer, hlen); object->code = 200; object->message = internAtom("Okay"); object->flags &= ~OBJECT_INITIAL; object->flags |= OBJECT_DYNAMIC; if (object->key_size == 8 && memcmp(object->key, "/s_server/", 8) == 0) { objectPrintf(object, 0, "<!DOCTYPE HTML PUBLIC " "\"-//W3C//DTD HTML 4.01 Transitional//EN\" " "\"http://www.w3.org/TR/html4/loose.dtd\">\n" "<html><head>\n" "<title>Polipo</title>\n" "</head><body>\n" "<h1>Polipo</h1>\n" "<p><a href=\"status?\">Status report</a>.</p>\n" "<p><a href=\"config?\">Current configuration</a>.</p>\n" "<p><a href=\"servers?\">Known servers</a>.</p>\n" #ifndef NO_DISK_CACHE "<p><a href=\"index?\">Disk cache index</a>.</p>\n" #endif "</body></html>\n"); object->length = object->size; } else if (matchUrl("/s_server/status", object)) { objectPrintf(object, 0, "<!DOCTYPE HTML PUBLIC " "\"-//W3C//DTD HTML 4.01 Transitional//EN\" " "\"http://www.w3.org/TR/html4/loose.dtd\">\n" "<html><head>\n" "<title>Polipo status report</title>\n" "</head><body>\n" "<h1>Polipo proxy on %s:%d: status report</h1>\n" "<p>The %s proxy on %s:%d is %s.</p>\n" "<p>There are %d public and %d private objects " "currently in memory using %d KB in %d chunks " "(%d KB allocated).</p>\n" "<p>There are %d atoms.</p>" "<p><form method=POST action=\"/s_server/status?\">" "<input type=submit name=\"init-forbidden\" " "value=\"Read forbidden file\"></form>\n" "<form method=POST action=\"/s_server/status?\">" "<input type=submit name=\"writeout-objects\" " "value=\"Write out in-memory cache\"></form>\n" "<form method=POST action=\"/s_server/status?\">" "<input type=submit name=\"discard-objects\" " "value=\"Discard in-memory cache\"></form>\n" "<form method=POST action=\"/s_server/status?\">" "<input type=submit name=\"reopen-log\" " "value=\"Reopen log file\"></form>\n" "<form method=POST action=\"/s_server/status?\">" "<input type=submit name=\"free-chunk-arenas\" " "value=\"Free chunk arenas\"></form></p>\n" "<p><a href=\"/s_server/\">back</a></p>" "</body></html>\n", proxyName->string, proxyPort, cacheIsShared ? "shared" : "private", proxyName->string, proxyPort, proxyOffline ? "off line" : (relaxTransparency ? "on line (transparency relaxed)" : "on line"), publicObjectCount, privateObjectCount, used_chunks * CHUNK_SIZE / 1024, used_chunks, totalChunkArenaSize() / 1024, used_atoms); object->expires = current_time.tv_sec; object->length = object->size; } else if (matchUrl("/s_server/config", object)) { fillSpecialObject(object, printConfig, NULL); object->expires = current_time.tv_sec + 5; #ifndef NO_DISK_CACHE } else if (matchUrl("/s_server/index", object)) { int len; char *root; if (disableIndexing) { abortObject(object, 403, internAtom("Action not allowed")); notifyObject(object); return 1; } len = MAX(0, object->key_size - 14); root = strdup_n((char *)object->key + 14, len); if (root == NULL) { abortObject(object, 503, internAtom("Couldn't allocate root")); notifyObject(object); return 1; } writeoutObjects(1); fillSpecialObject(object, plainIndexDiskObjects, root); free(root); object->expires = current_time.tv_sec + 5; } else if (matchUrl("/s_server/recursive-index", object)) { int len; char *root; if (disableIndexing) { abortObject(object, 403, internAtom("Action not allowed")); notifyObject(object); return 1; } len = MAX(0, object->key_size - 24); root = strdup_n((char *)object->key + 24, len); if (root == NULL) { abortObject(object, 503, internAtom("Couldn't allocate root")); notifyObject(object); return 1; } writeoutObjects(1); fillSpecialObject(object, recursiveIndexDiskObjects, root); free(root); object->expires = current_time.tv_sec + 20; #endif } else if (matchUrl("/s_server/servers", object)) { if (disableServersList) { abortObject(object, 403, internAtom("Action not allowed")); notifyObject(object); return 1; } fillSpecialObject(object, serversList, NULL); object->expires = current_time.tv_sec + 2; } else { abortObject(object, 404, internAtom("Not found")); } object->flags &= ~OBJECT_VALIDATING; notifyObject(object); return 1; }