void do_proxy(int clifd, const struct sockaddr_in *cliaddr, int pid) { /* get the request from the client */ char *request; int request_len; request = calloc(MAXLINE, sizeof(char)); request_len = Read(clifd, request, MAXLINE); /* get the request line, header lines and entity body */ const char *request_line, *header_lines, *body; int rlen, hlen, blen; separate_http_message(request, request_len, &request_line, &rlen, &header_lines, &hlen, &body, &blen); /* get header fields */ struct header_field *header_fields; header_fields = get_header_fields(header_lines, hlen); /* remove Connection and Proxy-Connection from header fields */ remove_header_field(&header_fields, "Connection"); remove_header_field(&header_fields, "Proxy-Connection"); /* get the hostname of the server */ const struct header_field *host_header_field; char *host; const char *p_host, *method, *url, *version; int hostlen, methodlen, urllen, versionlen; if ((host_header_field = get_header_field(header_fields, "Host")) == NULL) { get_start_fields(request_line, rlen, &method, &methodlen, &url, &urllen, &version, &versionlen); get_host_from_url(url, &p_host, &hostlen); } else { p_host = host_header_field->value; hostlen = host_header_field->vlen; } host = calloc(1, hostlen + 1); memcpy(host, p_host, hostlen); /* connect to the server */ int servfd; struct sockaddr_in servaddr; socklen_t servaddrlen; struct addrinfo hints, *result; fprintf(stdout, "---pid=%d, Connect to the server\n", pid); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; getaddrinfo(host, "http", &hints, &result); memcpy(&servaddr, result->ai_addr, sizeof(servaddr)); servaddrlen = result->ai_addrlen; freeaddrinfo(result); servfd = Socket(AF_INET, SOCK_STREAM, 0); Connect(servfd, (struct sockaddr *)&servaddr, servaddrlen); /* assemble the new request, assuming that the whole request is less than 4096 bytes */ char *new_request, *bufpos; int new_request_len; struct header_field *iter_header_field; new_request = calloc(MAXLINE, sizeof(char)); new_request_len = 0; bufpos = new_request; bufpos = write_to_buf(bufpos, request_line, rlen); bufpos = write_to_buf(bufpos, "\r\n", 2); new_request_len += rlen + 2; for (iter_header_field = header_fields; iter_header_field; iter_header_field = iter_header_field->next) { bufpos = write_to_buf(bufpos, iter_header_field->name, iter_header_field->nlen); bufpos = write_to_buf(bufpos, ": ", 2); bufpos = write_to_buf(bufpos, iter_header_field->value, iter_header_field->vlen); bufpos = write_to_buf(bufpos, "\r\n", 2); new_request_len += iter_header_field->nlen + iter_header_field->vlen + 4; } bufpos = write_to_buf(bufpos, "\r\n", 2); bufpos = write_to_buf(bufpos, body, blen); new_request_len += blen + 2; /* send the new request to the server */ fprintf(stdout, "---pid=%d, Send the new request to the server\n", pid); Write(servfd, new_request, new_request_len); /* get and send back the response */ char *response; int response_len; fprintf(stdout, "---pid=%d, Send the response back to the client\n", pid); response = calloc(MAXLINE, sizeof(char)); while ((response_len = Read(servfd, response, MAXLINE)) > 0) { fprintf(stdout, "---pid=%d, %d bytes received from the server\n", pid, response_len); Write(clifd, response, response_len); } /* close the server socket */ fprintf(stdout, "---pid=%d, Close the server socket\n", pid); close(servfd); /* release memory */ struct header_field *next_header_field; free(request); free(new_request); free(response); free(host); for (iter_header_field = header_fields; iter_header_field; iter_header_field = next_header_field) { next_header_field = iter_header_field->next; free(iter_header_field); } }
int main(int argc, char* argv[]) { char *pacfile = NULL, *url = NULL, *host = NULL, *urlslist = NULL, *client_ip = NULL; if (argv[1] && (STREQ(argv[1], "--help") || STREQ(argv[1], "--helpshort"))) { usage(argv[0]); } signed char c; while ((c = getopt(argc, argv, "evp:u:h:f:c:")) != -1) switch (c) { case 'v': printf("%s\n", pacparser_version()); return 0; case 'p': pacfile = optarg; break; case 'u': url = optarg; break; case 'h': host = optarg; break; case 'f': urlslist = optarg; break; case 'c': client_ip = optarg; break; case 'e': break; case '?': usage(argv[0]); /* fallthrough */ default: abort (); } if (!pacfile) { fprintf(stderr, "pactester.c: You didn't specify the PAC file\n"); usage(argv[0]); } if (!url && !urlslist) { fprintf(stderr, "pactester.c: You didn't specify the URL\n"); usage(argv[0]); } // Initialize pacparser. if (!pacparser_init()) { fprintf(stderr, "pactester.c: Could not initialize pacparser\n"); return 1; } // Read pacfile from stdin. if (STREQ("-", pacfile)) { char *script; size_t script_size = 1; // for the null terminator char buffer[LINEMAX]; script = (char *) malloc(sizeof(char) * LINEMAX); if (script == NULL) { perror("pactetser.c: Failed to allocate the memory for the script"); return 1; } script[0] = '\0'; // Null terminate to prepare for strcat while (fgets(buffer, LINEMAX, stdin)) { if (strlen(buffer) == 0) break; char *old = script; script_size += strlen(buffer); if (script_size > PACMAX) { fprintf(stderr, "Input file is too big. Maximum allowed size is: %d", PACMAX); free(script); return 1; } script = realloc(script, script_size); if (script == NULL) { perror("pactester.c: Failed to allocate the memory for the script"); free(old); return 1; } strcat(script, buffer); } if (ferror(stdin)) { free(script); perror("pactester.c: Error reading from stdin"); return 1; } if (!pacparser_parse_pac_string(script)) { fprintf(stderr, "pactester.c: Could not parse the pac script: %s\n", script); free(script); pacparser_cleanup(); return 1; } free(script); } else { if (!pacparser_parse_pac_file(pacfile)) { fprintf(stderr, "pactester.c: Could not parse the pac file: %s\n", pacfile); pacparser_cleanup(); return 1; } } if (client_ip) pacparser_setmyip(client_ip); char *proxy; if (url) { // If the host was not explicitly given, get it from the URL. // If that fails, return with error (the get_host_from_url() // function will print a proper error message in that case). host = host ? host: get_host_from_url(url); if (!host) { return 1; } proxy = pacparser_find_proxy(url, host); if (proxy == NULL) { fprintf(stderr, "pactester.c: %s %s.\n", "Problem in finding proxy for", url); pacparser_cleanup(); return 1; } printf("%s\n", proxy); } else if (urlslist) { char line[LINEMAX]; FILE *fp; if (!(fp = fopen(urlslist, "r"))) { fprintf(stderr, "pactester.c: Could not open urlslist: %s", urlslist); pacparser_cleanup(); return 1; } while (fgets(line, sizeof(line), fp)) { char *url = line; // Remove spaces from the beginning. while (*url == ' ' || *url == '\t') url++; // Skip comment lines. if (*url == '#') { printf("%s", url); continue; } char *urlend = url; while (*urlend != '\r' && *urlend != '\n' && *urlend != '\0' && *urlend != ' ' && *urlend != '\t') urlend++; // keep moving till you hit space or end of string *urlend = '\0'; if (!(host = get_host_from_url(url)) ) continue; proxy = NULL; proxy = pacparser_find_proxy(url, host); if (proxy == NULL) { fprintf(stderr, "pactester.c: %s %s.\n", "Problem in finding proxy for", url); pacparser_cleanup(); return 1; } if (proxy) printf("%s : %s\n", url, proxy); } fclose(fp); } pacparser_cleanup(); return 0; }
int main(int argc, char* argv[]) { const char *pacfile = NULL, *host = NULL, *url = NULL, *urlsfile = NULL, *client_ip = NULL, *dns_servers = NULL, *dns_domains = NULL; int dns_resolver_variant = DNS_GETADDRINFO; int enable_microsoft_extensions = 1; if (argv[1] && (STREQ(argv[1], "--help") || STREQ(argv[1], "--helpshort"))) { usage(argv[0]); } signed char c; while ((c = getopt(argc, argv, "eEvp:u:h:f:c:s:d:r:")) != -1) switch (c) { case 'v': printf("%s\n", pacparser_version()); return 0; case 'p': pacfile = optarg; break; case 'u': url = optarg; break; case 'h': host = optarg; break; case 'f': urlsfile = optarg; break; case 'c': client_ip = optarg; break; case 's': dns_servers = optarg; break; case 'd': dns_domains = optarg; break; case 'r': if (!strcmp(optarg, "none")) { dns_resolver_variant = DNS_NONE; } else if (!strcmp(optarg, "getaddrinfo")) { dns_resolver_variant = DNS_GETADDRINFO; } else if (!strcmp(optarg, "c-ares")) { dns_resolver_variant = DNS_C_ARES; } else { usage(argv[0]); abort(); } break; case 'e': enable_microsoft_extensions = 1; break; case 'E': enable_microsoft_extensions = 0; break; case '?': usage(argv[0]); /* fallthrough */ default: abort(); } if (!pacfile) { fprintf(stderr, __FILE__": You didn't specify the PAC file\n"); usage(argv[0]); } if (!url && !urlsfile) { fprintf(stderr, __FILE__": You didn't specify a URL or URL-FILE\n"); usage(argv[0]); } if (url && urlsfile) { fprintf(stderr, __FILE__": You can't specify both URL and URL-FILE\n"); usage(argv[0]); } std::unique_ptr<PacParser> parser = PacParser::create( dns_servers, dns_domains, enable_microsoft_extensions); if (!parser->set_dns_resolver_variant(dns_resolver_variant)) usage(argv[0]); // Read pacfile from stdin. if (STREQ("-", pacfile)) { char *script; size_t script_size = 1; // for the null terminator char buffer[LINEMAX]; script = (char*)calloc(1, sizeof(char)); if (script == NULL) { perror(__FILE__": Failed to allocate the memory for the script"); return 1; } while (fgets(buffer, sizeof(buffer), stdin)) { if (strlen(buffer) == 0) break; char *old = script; script_size += strlen(buffer); if (script_size > PACMAX) { fprintf(stderr, __FILE__": Input file is too big. " "Maximum allowed size in bytes is: %d\n", PACMAX); free(script); return 1; } script = (char*)realloc(script, script_size); if (script == NULL) { perror(__FILE__": Failed to allocate the memory for the script"); free(old); return 1; } strncat(script, buffer, strlen(buffer)); } if (ferror(stdin)) { free(script); perror(__FILE__": Error reading from stdin"); return 1; } if (!parser->parse_pac_string(script)) { fprintf(stderr, __FILE__": Could not parse the pac script '%s'\n", script); free(script); return 1; } free(script); } else { if (!parser->parse_pac_file(pacfile)) { fprintf(stderr, __FILE__": Could not parse the pac file: %s\n", pacfile); return 1; } } if (client_ip) parser->setmyip(client_ip); char *h; std::string proxy; int rc = 0; if (url) { if (host) { parser->find_proxy(url, host, proxy); } else { // If the host was not explicitly given, get it from the URL. // If that fails, return with error (the get_host_from_url() // function will print a proper error message in that case). if ((h = get_host_from_url(url)) == NULL) { return 1; } parser->find_proxy(url, h, proxy); free(h); } if (!proxy.length()) { fprintf(stderr, __FILE__": Problem in finding proxy for %s\n", url); return 1; } printf("%s\n", proxy.c_str()); } else if (urlsfile) { char line[LINEMAX]; FILE *fp; if ((fp = fopen(urlsfile, "r")) == NULL) { fprintf(stderr, __FILE__": Could not open urlsfile '%s'\n", urlsfile); return 1; } while (fgets(line, sizeof(line), fp)) { char *url = line; // Remove spaces from the beginning. while (*url == ' ' || *url == '\t') url++; // Skip comment lines. if (*url == '#') { printf("%s", url); continue; } char *urlend = url; while (*urlend != '\r' && *urlend != '\n' && *urlend != '\0' && *urlend != ' ' && *urlend != '\t') urlend++; // keep moving till you hit space or end of string *urlend = '\0'; if ((h = get_host_from_url(url)) == NULL) { rc = 1; // will exit with error continue; } parser->find_proxy(url, h, proxy); free(h); if (!proxy.length()) { fprintf(stderr, __FILE__": Problem in finding proxy for %s\n", url); rc = 1; // will exit with error continue; } printf("%s : %s\n", url, proxy.c_str()); } fclose(fp); } return rc; }