|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
* weighttp - a lightweight and simple webserver benchmarking tool |
|
|
|
|
* |
|
|
|
|
* Author: |
|
|
|
|
* Copyright (c) 2009 Thomas Porzelt |
|
|
|
|
* Copyright (c) 2009-2011 Thomas Porzelt |
|
|
|
|
* |
|
|
|
|
* License: |
|
|
|
|
* MIT, see COPYING file |
|
|
|
@ -19,8 +19,10 @@ static void show_help(void) {
|
|
|
|
|
printf(" -c num concurrent clients (default: 1)\n"); |
|
|
|
|
printf(" -k keep alive (default: no)\n"); |
|
|
|
|
printf(" -6 use ipv6 (default: no)\n"); |
|
|
|
|
printf(" -H str add header to request\n"); |
|
|
|
|
printf(" -h show help and exit\n"); |
|
|
|
|
printf(" -v show version and exit\n\n"); |
|
|
|
|
printf("example: weighttpd -n 10000 -c 10 -t 2 -k -H \"User-Agent: foo\" localhost/index.html\n\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct addrinfo *resolve_host(char *hostname, uint16_t port, uint8_t use_ipv6) { |
|
|
|
@ -68,10 +70,12 @@ static struct addrinfo *resolve_host(char *hostname, uint16_t port, uint8_t use_
|
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char *forge_request(char *url, char keep_alive, char **host, uint16_t *port) { |
|
|
|
|
static char *forge_request(char *url, char keep_alive, char **host, uint16_t *port, char **headers, uint8_t headers_num) { |
|
|
|
|
char *c, *end; |
|
|
|
|
char *req; |
|
|
|
|
uint32_t len; |
|
|
|
|
uint8_t i; |
|
|
|
|
uint8_t have_user_agent; |
|
|
|
|
|
|
|
|
|
*host = NULL; |
|
|
|
|
*port = 0; |
|
|
|
@ -126,7 +130,22 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
|
|
|
|
|
if (*url == '\0') |
|
|
|
|
url = "/"; |
|
|
|
|
|
|
|
|
|
req = W_MALLOC(char, sizeof("GET HTTP/1.1\r\nHost: :65536\r\nUser-Agent: weighttp/\r\nConnection: keep-alive\r\n\r\n") + strlen(VERSION) + strlen(*host) + strlen(url)); |
|
|
|
|
// total request size
|
|
|
|
|
len = strlen("GET HTTP/1.1\r\nHost: :65536\r\nConnection: keep-alive\r\n\r\n") + 1; |
|
|
|
|
len += strlen(*host); |
|
|
|
|
len += strlen(url); |
|
|
|
|
|
|
|
|
|
have_user_agent = 0; |
|
|
|
|
for (i = 0; i < headers_num; i++) { |
|
|
|
|
len += strlen(headers[i]) + strlen("\r\n"); |
|
|
|
|
if (strncmp(headers[i], "User-Agent: ", sizeof("User-Agent: ")-1) == 0) |
|
|
|
|
have_user_agent = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!have_user_agent) |
|
|
|
|
len += strlen("User-Agent: weighttp/" VERSION "\r\n"); |
|
|
|
|
|
|
|
|
|
req = W_MALLOC(char, len); |
|
|
|
|
|
|
|
|
|
strcpy(req, "GET "); |
|
|
|
|
strcat(req, url); |
|
|
|
@ -135,7 +154,15 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
|
|
|
|
|
if (*port != 80) |
|
|
|
|
sprintf(req + strlen(req), ":%"PRIu16, *port); |
|
|
|
|
|
|
|
|
|
sprintf(req + strlen(req), "\r\nUser-Agent: weighttp/" VERSION "\r\n"); |
|
|
|
|
strcat(req, "\r\n"); |
|
|
|
|
|
|
|
|
|
if (!have_user_agent) |
|
|
|
|
sprintf(req + strlen(req), "User-Agent: weighttp/" VERSION "\r\n"); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < headers_num; i++) { |
|
|
|
|
strcat(req, headers[i]); |
|
|
|
|
strcat(req, "\r\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (keep_alive) |
|
|
|
|
strcat(req, "Connection: keep-alive\r\n\r\n"); |
|
|
|
@ -178,10 +205,14 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
int sec, millisec, microsec; |
|
|
|
|
uint64_t rps; |
|
|
|
|
uint64_t kbps; |
|
|
|
|
|
|
|
|
|
char **headers; |
|
|
|
|
uint8_t headers_num; |
|
|
|
|
|
|
|
|
|
printf("weighttp - a lightweight and simple webserver benchmarking tool\n\n"); |
|
|
|
|
|
|
|
|
|
headers = NULL; |
|
|
|
|
headers_num = 0; |
|
|
|
|
|
|
|
|
|
/* default settings */ |
|
|
|
|
use_ipv6 = 0; |
|
|
|
|
config.thread_count = 1; |
|
|
|
@ -189,7 +220,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
config.req_count = 0; |
|
|
|
|
config.keep_alive = 0; |
|
|
|
|
|
|
|
|
|
while ((c = getopt(argc, argv, ":hv6kn:t:c:")) != -1) { |
|
|
|
|
while ((c = getopt(argc, argv, ":hv6kn:t:c:H:")) != -1) { |
|
|
|
|
switch (c) { |
|
|
|
|
case 'h': |
|
|
|
|
show_help(); |
|
|
|
@ -213,6 +244,11 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
case 'c': |
|
|
|
|
config.concur_count = atoi(optarg); |
|
|
|
|
break; |
|
|
|
|
case 'H': |
|
|
|
|
headers = W_REALLOC(headers, char*, headers_num+1); |
|
|
|
|
headers[headers_num] = optarg; |
|
|
|
|
headers_num++; |
|
|
|
|
break; |
|
|
|
|
case '?': |
|
|
|
|
W_ERROR("unkown option: -%c", optopt); |
|
|
|
|
show_help(); |
|
|
|
@ -259,7 +295,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
return 2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (NULL == (config.request = forge_request(argv[optind], config.keep_alive, &host, &port))) { |
|
|
|
|
if (NULL == (config.request = forge_request(argv[optind], config.keep_alive, &host, &port, headers, headers_num))) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -333,6 +369,10 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
stats.req_failed += worker->stats.req_failed; |
|
|
|
|
stats.bytes_total += worker->stats.bytes_total; |
|
|
|
|
stats.bytes_body += worker->stats.bytes_body; |
|
|
|
|
stats.req_2xx += worker->stats.req_2xx; |
|
|
|
|
stats.req_3xx += worker->stats.req_3xx; |
|
|
|
|
stats.req_4xx += worker->stats.req_4xx; |
|
|
|
|
stats.req_5xx += worker->stats.req_5xx; |
|
|
|
|
|
|
|
|
|
worker_free(worker); |
|
|
|
|
} |
|
|
|
@ -351,6 +391,9 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
printf("requests: %"PRIu64" total, %"PRIu64" started, %"PRIu64" done, %"PRIu64" succeeded, %"PRIu64" failed, %"PRIu64" errored\n", |
|
|
|
|
config.req_count, stats.req_started, stats.req_done, stats.req_success, stats.req_failed, stats.req_error |
|
|
|
|
); |
|
|
|
|
printf("status codes: %"PRIu64" 2xx, %"PRIu64" 3xx, %"PRIu64" 4xx, %"PRIu64" 5xx\n", |
|
|
|
|
stats.req_2xx, stats.req_3xx, stats.req_4xx, stats.req_5xx |
|
|
|
|
); |
|
|
|
|
printf("traffic: %"PRIu64" bytes total, %"PRIu64" bytes http, %"PRIu64" bytes data\n", |
|
|
|
|
stats.bytes_total, stats.bytes_total - stats.bytes_body, stats.bytes_body |
|
|
|
|
); |
|
|
|
@ -361,6 +404,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
free(workers); |
|
|
|
|
free(config.request); |
|
|
|
|
free(host); |
|
|
|
|
free(headers); |
|
|
|
|
freeaddrinfo(config.saddr); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|