/* The old shoutcast procotol. Don't look at this, it's really nasty */ int httpp_parse_icy(http_parser_t *parser, char *http_data, unsigned long len) { char *data; char *line[MAX_HEADERS]; int lines; if(http_data == NULL) return 0; data = malloc(len + 1); memcpy(data, http_data, len); data[len] = 0; lines = split_headers(data, len, line); /* Now, this protocol looks like: * sourcepassword\n * headers: as normal\n" * \n */ parser->req_type = httpp_req_source; httpp_setvar(parser, HTTPP_VAR_URI, "/"); httpp_setvar(parser, HTTPP_VAR_ICYPASSWORD, line[0]); httpp_setvar(parser, HTTPP_VAR_PROTOCOL, "ICY"); httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE"); /* This protocol is evil */ httpp_setvar(parser, HTTPP_VAR_VERSION, "666"); parse_headers(parser, line, lines); free(data); return 1; }
int httpp_parse_response(http_parser_t *parser, char *http_data, unsigned long len, char *uri) { char *data; char *line[MAX_HEADERS]; int lines, slen,i, whitespace=0, where=0,code; char *version=NULL, *resp_code=NULL, *message=NULL; if(http_data == NULL) return 0; /* make a local copy of the data, including 0 terminator */ data = (char *)malloc(len+1); if (data == NULL) return 0; memcpy(data, http_data, len); data[len] = 0; lines = split_headers(data, len, line); /* In this case, the first line contains: * VERSION RESPONSE_CODE MESSAGE, such as HTTP/1.0 200 OK */ slen = strlen(line[0]); version = line[0]; for(i=0; i < slen; i++) { if(line[0][i] == ' ') { line[0][i] = 0; whitespace = 1; } else if(whitespace) { whitespace = 0; where++; if(where == 1) resp_code = &line[0][i]; else { message = &line[0][i]; break; } } } if(version == NULL || resp_code == NULL || message == NULL) { free(data); return 0; } httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code); code = atoi(resp_code); if(code < 200 || code >= 300) { httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message); } httpp_setvar(parser, HTTPP_VAR_URI, uri); httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "NONE"); parse_headers(parser, line, lines); free(data); return 1; }
int httpp_parse(http_parser_t *parser, const char *http_data, unsigned long len) { char *data, *tmp; char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */ int i; int lines; char *req_type = NULL; char *uri = NULL; char *version = NULL; int whitespace, where, slen; if (http_data == NULL) return 0; /* make a local copy of the data, including 0 terminator */ data = (char *)amalloc(len+1); memcpy(data, http_data, len); data[len] = 0; lines = split_headers(data, len, line); /* parse the first line special ** the format is: ** REQ_TYPE URI VERSION ** eg: ** GET /index.html HTTP/1.0 */ where = 0; whitespace = 0; slen = strlen(line[0]); req_type = line[0]; for (i = 0; i < slen; i++) { if (line[0][i] == ' ') { whitespace = 1; line[0][i] = '\0'; } else { /* we're just past the whitespace boundry */ if (whitespace) { whitespace = 0; where++; switch (where) { case 1: uri = &line[0][i]; break; case 2: version = &line[0][i]; break; } } } } if (strcasecmp("GET", req_type) == 0) { parser->req_type = httpp_req_get; } else if (strcasecmp("POST", req_type) == 0) { parser->req_type = httpp_req_post; } else if (strcasecmp("HEAD", req_type) == 0) { parser->req_type = httpp_req_head; } else if (strcasecmp("SOURCE", req_type) == 0) { parser->req_type = httpp_req_source; } else if (strcasecmp("PLAY", req_type) == 0) { parser->req_type = httpp_req_play; } else if (strcasecmp("STATS", req_type) == 0) { parser->req_type = httpp_req_stats; } else { parser->req_type = httpp_req_unknown; } if (uri != NULL && strlen(uri) > 0) { char *query; if((query = strchr(uri, '?')) != NULL) { httpp_setvar(parser, HTTPP_VAR_RAWURI, uri); httpp_setvar(parser, HTTPP_VAR_QUERYARGS, query); *query = 0; query++; parse_query(parser, query); } parser->uri = strdup(uri); } else { free(data); return 0; } if ((version != NULL) && ((tmp = strchr(version, '/')) != NULL)) { tmp[0] = '\0'; if ((strlen(version) > 0) && (strlen(&tmp[1]) > 0)) { httpp_setvar(parser, HTTPP_VAR_PROTOCOL, version); httpp_setvar(parser, HTTPP_VAR_VERSION, &tmp[1]); } else { free(data); return 0; } } else { free(data); return 0; } if (parser->req_type != httpp_req_none && parser->req_type != httpp_req_unknown) { switch (parser->req_type) { case httpp_req_get: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "GET"); break; case httpp_req_post: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "POST"); break; case httpp_req_head: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "HEAD"); break; case httpp_req_source: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE"); break; case httpp_req_play: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PLAY"); break; case httpp_req_stats: httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "STATS"); break; default: break; } } else { free(data); return 0; } if (parser->uri != NULL) { httpp_setvar(parser, HTTPP_VAR_URI, parser->uri); } else { free(data); return 0; } parse_headers(parser, line, lines); free(data); return 1; }
int main(int argc, char **argv) { int i, opt, use_threads; struct sigaction act; char *filename; Octstr *log_filename; Octstr *file_contents; #ifdef HAVE_LIBSSL Octstr *ssl_server_cert_file = NULL; Octstr *ssl_server_key_file = NULL; #endif char *whitelist_name; char *blacklist_name; int white_asked, black_asked; long threads[MAX_THREADS]; FILE *fp; gwlib_init(); act.sa_handler = sigterm; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); port = 8080; use_threads = 1; verbose = 1; run = 1; filename = NULL; log_filename = NULL; blacklist_name = NULL; whitelist_name = NULL; white_asked = 0; black_asked = 0; reply_text = octstr_create("Sent."); while ((opt = getopt(argc, argv, "hqv:p:t:f:l:sc:k:b:w:r:H:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'q': verbose = 0; break; case 'h': help(); exit(0); case 'p': port = atoi(optarg); break; case 't': use_threads = atoi(optarg); if (use_threads > MAX_THREADS) use_threads = MAX_THREADS; break; case 'c': #ifdef HAVE_LIBSSL octstr_destroy(ssl_server_cert_file); ssl_server_cert_file = octstr_create(optarg); #endif break; case 'k': #ifdef HAVE_LIBSSL octstr_destroy(ssl_server_key_file); ssl_server_key_file = octstr_create(optarg); #endif break; case 's': #ifdef HAVE_LIBSSL ssl = 1; #endif break; case 'f': filename = optarg; break; case 'l': octstr_destroy(log_filename); log_filename = octstr_create(optarg); break; case 'w': whitelist_name = optarg; if (whitelist_name == NULL) whitelist_name = ""; white_asked = 1; break; case 'b': blacklist_name = optarg; if (blacklist_name == NULL) blacklist_name = ""; black_asked = 1; break; case 'r': octstr_destroy(reply_text); reply_text = octstr_create(optarg); break; case 'H': { Octstr *cont; fp = fopen(optarg, "a"); if (fp == NULL) panic(0, "Cannot open header text file %s", optarg); cont = octstr_read_file(optarg); if (cont == NULL) panic(0, "Cannot read header text"); debug("", 0, "headers are"); octstr_dump(cont, 0); split_headers(cont, &extra_headers); fclose(fp); octstr_destroy(cont); break; } case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (log_filename != NULL) { log_open(octstr_get_cstr(log_filename), GW_DEBUG, GW_NON_EXCL); octstr_destroy(log_filename); } if (filename == NULL) file_contents = NULL; else file_contents = octstr_read_file(filename); if (white_asked) { whitelist = octstr_read_file(whitelist_name); if (whitelist == NULL) panic(0, "Cannot read the whitelist"); } if (black_asked) { blacklist = octstr_read_file(blacklist_name); if (blacklist == NULL) panic(0, "Cannot read the blacklist"); } #ifdef HAVE_LIBSSL /* * check if we are doing a SSL-enabled server version here * load the required cert and key file */ if (ssl) { if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) { use_global_server_certkey_file(ssl_server_cert_file, ssl_server_key_file); octstr_destroy(ssl_server_cert_file); octstr_destroy(ssl_server_key_file); } else { panic(0, "certificate and public key need to be given!"); } } #endif if (http_open_port(port, ssl) == -1) panic(0, "http_open_server failed"); /* * Do the real work in a separate thread so that the main * thread can catch signals safely. */ for (i = 0; i < use_threads; ++i) threads[i] = gwthread_create(client_thread, file_contents); /* wait for all working threads */ for (i = 0; i < use_threads; ++i) gwthread_join(threads[i]); octstr_destroy(reply_text); gwlist_destroy(extra_headers, octstr_destroy_item); debug("test.http", 0, "Program exiting normally."); gwlib_shutdown(); return 0; }
int main(int argc, char **argv) { int i, opt, num_threads; Octstr *proxy; List *exceptions; long proxy_port; int proxy_ssl = 0; Octstr *proxy_username; Octstr *proxy_password; Octstr *exceptions_regex; char *p; long threads[MAX_THREADS]; time_t start, end; double run_time; FILE *fp; int ssl = 0; gwlib_init(); proxy = NULL; proxy_port = -1; exceptions = gwlist_create(); proxy_username = NULL; proxy_password = NULL; exceptions_regex = NULL; num_threads = 1; file = 0; fp = NULL; while ((opt = getopt(argc, argv, "hv:qr:p:P:Se:t:i:a:u:sc:H:B:m:f")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'q': verbose = 0; break; case 'r': max_requests = atoi(optarg); break; case 't': num_threads = atoi(optarg); if (num_threads > MAX_THREADS) num_threads = MAX_THREADS; break; case 'i': interval = atof(optarg); break; case 'u': file = 1; fp = fopen(optarg, "a"); if (fp == NULL) panic(0, "Cannot open message text file %s", optarg); msg_text = octstr_read_file(optarg); if (msg_text == NULL) panic(0, "Cannot read message text"); debug("", 0, "message text is"); octstr_dump(msg_text, 0); octstr_url_encode(msg_text); fclose(fp); break; case 'h': help(); exit(0); case 'p': proxy = octstr_create(optarg); break; case 'P': proxy_port = atoi(optarg); break; case 'S': proxy_ssl = 1; break; case 'e': p = strtok(optarg, ":"); while (p != NULL) { gwlist_append(exceptions, octstr_create(p)); p = strtok(NULL, ":"); } break; case 'E': exceptions_regex = octstr_create(optarg); break; case 'a': p = strtok(optarg, ":"); if (p != NULL) { auth_username = octstr_create(p); p = strtok(NULL, ""); if (p != NULL) auth_password = octstr_create(p); } break; case 's': ssl = 1; break; case 'c': octstr_destroy(ssl_client_certkey_file); ssl_client_certkey_file = octstr_create(optarg); break; case 'H': fp = fopen(optarg, "a"); if (fp == NULL) panic(0, "Cannot open header text file %s", optarg); extra_headers = octstr_read_file(optarg); if (extra_headers == NULL) panic(0, "Cannot read header text"); debug("", 0, "headers are"); octstr_dump(extra_headers, 0); split_headers(extra_headers, &split); fclose(fp); break; case 'B': content_file = octstr_create(optarg); break; case 'm': method_name = octstr_create(optarg); break; case 'f': follow_redirect = 0; break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (optind == argc) { help(); exit(0); } #ifdef HAVE_LIBSSL /* * check if we are doing a SSL-enabled client version here * load the required cert and key file */ if (ssl || proxy_ssl) { if (ssl_client_certkey_file != NULL) { use_global_client_certkey_file(ssl_client_certkey_file); } else { panic(0, "client certkey file need to be given!"); } } #endif if (method_name != NULL) { method = http_name2method(method_name); } if (proxy != NULL && proxy_port > 0) { http_use_proxy(proxy, proxy_port, proxy_ssl, exceptions, proxy_username, proxy_password, exceptions_regex); } octstr_destroy(proxy); octstr_destroy(proxy_username); octstr_destroy(proxy_password); octstr_destroy(exceptions_regex); gwlist_destroy(exceptions, octstr_destroy_item); urls = argv + optind; num_urls = argc - optind; time(&start); if (num_threads == 1) client_thread(http_caller_create()); else { for (i = 0; i < num_threads; ++i) threads[i] = gwthread_create(client_thread, http_caller_create()); for (i = 0; i < num_threads; ++i) gwthread_join(threads[i]); } time(&end); run_time = difftime(end, start); info(0, "%ld requests in %f seconds, %f requests/s.", (max_requests * num_threads), run_time, (max_requests * num_threads) / run_time); octstr_destroy(ssl_client_certkey_file); octstr_destroy(auth_username); octstr_destroy(auth_password); octstr_destroy(extra_headers); octstr_destroy(content_file); gwlist_destroy(split, octstr_destroy_item); gwlib_shutdown(); return 0; }