Exemple #1
0
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);
    }
}
Exemple #2
0
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;
}
Exemple #3
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;
}