1
0
mirror of https://github.com/wg/wrk synced 2026-06-09 16:43:42 +08:00

4 Commits

3 changed files with 53 additions and 18 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ LIBS := -lpthread -lm
TARGET := $(shell uname -s | tr [A-Z] [a-z] 2>/dev/null || echo unknown)
ifeq ($(TARGET), sunos)
CFLAGS += -D_PTHREADS
CFLAGS += -D_PTHREADS -D_POSIX_C_SOURCE=200112L
LIBS += -lsocket
endif
+51 -16
View File
@@ -33,6 +33,7 @@ static struct config {
uint64_t connections;
uint64_t requests;
uint64_t timeout;
uint64_t errors;
} cfg;
static struct {
@@ -50,6 +51,12 @@ static const struct http_parser_settings parser_settings = {
.on_message_complete = request_complete
};
static volatile sig_atomic_t stop = 0;
static void handler(int sig) {
stop = 1;
}
static void usage() {
printf("Usage: wrk <options> <url> \n"
" Options: \n"
@@ -59,6 +66,7 @@ static void usage() {
" \n"
" -H, --header <h> Add header to request \n"
" -v, --version Print version details \n"
" --errors <n> Abort after N errors \n"
" \n"
" Numeric arguments may include a SI unit (2k, 2M, 2G)\n");
}
@@ -104,14 +112,9 @@ int main(int argc, char **argv) {
for (addr = addrs; addr != NULL; addr = addr->ai_next) {
int fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (fd == -1) continue;
if (connect(fd, addr->ai_addr, addr->ai_addrlen) == -1) {
if (errno == EHOSTUNREACH || errno == ECONNREFUSED) {
close(fd);
continue;
}
}
rc = connect(fd, addr->ai_addr, addr->ai_addrlen);
close(fd);
break;
if (rc == 0) break;
}
if (addr == NULL) {
@@ -121,6 +124,7 @@ int main(int argc, char **argv) {
}
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, SIG_IGN);
cfg.addr = *addr;
request.buf = format_request(host, port, path, headers);
request.size = strlen(request.buf);
@@ -145,6 +149,13 @@ int main(int argc, char **argv) {
}
}
struct sigaction sa = {
.sa_handler = handler,
.sa_flags = 0,
};
sigfillset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
printf("Making %"PRIu64" requests to %s\n", cfg.requests, url);
printf(" %"PRIu64" threads and %"PRIu64" connections\n", cfg.threads, cfg.connections);
@@ -320,6 +331,16 @@ static int check_timeouts(aeEventLoop *loop, long long id, void *data) {
}
}
uint64_t errors = 0;
errors += thread->errors.connect;
errors += thread->errors.read;
errors += thread->errors.write;
errors += thread->errors.timeout;
if (stop || errors >= cfg.errors) {
aeStop(loop);
}
return TIMEOUT_INTERVAL_MS;
}
@@ -382,18 +403,24 @@ static char *extract_url_part(char *url, struct http_parser_url *parser_url, enu
}
static char *format_request(char *host, char *port, char *path, char **headers) {
char *req = NULL;
aprintf(&req, "GET %s HTTP/1.1\r\n", path);
aprintf(&req, "Host: %s", host);
if (port) aprintf(&req, ":%s", port);
aprintf(&req, "\r\n");
char *req = NULL;
char *head = NULL;
for (char **h = headers; *h != NULL; h++) {
aprintf(&req, "%s\r\n", *h);
aprintf(&head, "%s\r\n", *h);
if (!strncasecmp(*h, "Host:", 5)) {
host = NULL;
port = NULL;
}
}
aprintf(&req, "\r\n");
aprintf(&req, "GET %s HTTP/1.1\r\n", path);
if (host) aprintf(&req, "Host: %s", host);
if (port) aprintf(&req, ":%s", port);
if (host) aprintf(&req, "\r\n");
aprintf(&req, "%s\r\n", head ? head : "");
free(head);
return req;
}
@@ -402,6 +429,7 @@ static struct option longopts[] = {
{ "requests", required_argument, NULL, 'r' },
{ "threads", required_argument, NULL, 't' },
{ "header", required_argument, NULL, 'H' },
{ "errors", required_argument, NULL, 'E' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
@@ -416,7 +444,7 @@ static int parse_args(struct config *cfg, char **url, char **headers, int argc,
cfg->requests = 100;
cfg->timeout = SOCKET_TIMEOUT_MS;
while ((c = getopt_long(argc, argv, "t:c:r:H:v?", longopts, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "t:c:r:E:H:v?", longopts, NULL)) != -1) {
switch (c) {
case 't':
if (scan_metric(optarg, &cfg->threads)) return -1;
@@ -427,6 +455,9 @@ static int parse_args(struct config *cfg, char **url, char **headers, int argc,
case 'r':
if (scan_metric(optarg, &cfg->requests)) return -1;
break;
case 'E':
if (scan_metric(optarg, &cfg->errors)) return -1;
break;
case 'H':
*header++ = optarg;
break;
@@ -449,6 +480,10 @@ static int parse_args(struct config *cfg, char **url, char **headers, int argc,
return -1;
}
if (cfg->errors == 0) {
cfg->errors = cfg->requests / cfg->threads / 10;
}
*url = argv[optind];
*header = NULL;
+1 -1
View File
@@ -11,7 +11,7 @@
#include "http_parser.h"
#include "tinymt64.h"
#define VERSION "1.1.0"
#define VERSION "1.2.0"
#define RECVBUF 8192
#define SAMPLES 100000