summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Porzelt <tp@cryosphere.de>2011-10-16 12:01:08 +0200
committerThomas Porzelt <tp@cryosphere.de>2011-10-16 12:01:08 +0200
commit0fdf9d4229d56146023005461b953a864e5dc134 (patch)
tree95c90a2216aeedef9db028c3dacfdf38ec910fcb
parent0e287d6736c38fe357cbc65f59a11e8a7c11d459 (diff)
downloadweighttp-0fdf9d4229d56146023005461b953a864e5dc134.tar.gz
weighttp-0fdf9d4229d56146023005461b953a864e5dc134.zip
add stats about response status codes (2xx, 3xx, 4xx, 5xx)
-rw-r--r--src/client.c49
-rw-r--r--src/client.h2
-rw-r--r--src/weighttp.c7
-rw-r--r--src/worker.c3
-rw-r--r--src/worker.h5
5 files changed, 51 insertions, 15 deletions
diff --git a/src/client.c b/src/client.c
index f6e31cc..87b0a1a 100644
--- a/src/client.c
+++ b/src/client.c
@@ -106,7 +106,7 @@ static void client_reset(Client *client) {
client->request_offset = 0;
client->ts_start = 0;
client->ts_end = 0;
- client->status_200 = 0;
+ client->status_success = 0;
client->success = 0;
client->content_length = -1;
client->bytes_received = 0;
@@ -259,7 +259,7 @@ void client_state_machine(Client *client) {
}
} else {
/* disconnect */
- if (client->parser_state == PARSER_BODY && !client->keepalive && client->status_200
+ if (client->parser_state == PARSER_BODY && !client->keepalive && client->status_success
&& !client->chunked && client->content_length == -1) {
client->success = 1;
client->state = CLIENT_END;
@@ -314,27 +314,50 @@ void client_state_machine(Client *client) {
static uint8_t client_parse(Client *client, int size) {
char *end, *str;
+ uint16_t status_code;
switch (client->parser_state) {
case PARSER_START:
//printf("parse (START):\n%s\n", &client->buffer[client->parser_offset]);
/* look for HTTP/1.1 200 OK */
- if (client->buffer_offset < sizeof("HTTP/1.1 200 OK\r\n"))
+ if (client->buffer_offset < sizeof("HTTP/1.1 200\r\n"))
return 1;
- if (strncmp(client->buffer, "HTTP/1.1 200 OK\r\n", sizeof("HTTP/1.1 200 OK\r\n")-1) == 0) {
- client->status_200 = 1;
- client->parser_offset = sizeof("HTTP/1.1 200 ok\r\n") - 1;
- } else {
- client->status_200 = 0;
- end = strchr(client->buffer, '\r');
+ if (strncmp(client->buffer, "HTTP/1.1 ", sizeof("HTTP/1.1 ")-1) != 0)
+ return 0;
- if (!end || *(end+1) != '\n')
+ // now the status code
+ status_code = 0;
+ str = client->buffer + sizeof("HTTP/1.1 ")-1;
+ for (end = str + 3; str != end; str++) {
+ if (*str < '0' || *str > '9')
return 0;
- client->parser_offset = end + 2 - client->buffer;
+ status_code *= 10;
+ status_code += *str - '0';
+ }
+
+ if (status_code >= 200 && status_code < 300) {
+ client->worker->stats.req_2xx++;
+ client->status_success = 1;
+ } else if (status_code < 400) {
+ client->worker->stats.req_3xx++;
+ client->status_success = 1;
+ } else if (status_code < 500) {
+ client->worker->stats.req_4xx++;
+ } else if (status_code < 600) {
+ client->worker->stats.req_5xx++;
+ } else {
+ // invalid status code
+ return 0;
}
+ // look for next \r\n
+ end = strchr(end, '\r');
+ if (!end || *(end+1) != '\n')
+ return 0;
+
+ client->parser_offset = end + 2 - client->buffer;
client->parser_state = PARSER_HEADER;
case PARSER_HEADER:
//printf("parse (HEADER)\n");
@@ -441,7 +464,7 @@ static uint8_t client_parse(Client *client, int size) {
if (client->chunk_size == 0) {
/* chunk of size 0 marks end of content body */
client->state = CLIENT_END;
- client->success = client->status_200 ? 1 : 0;
+ client->success = client->status_success ? 1 : 0;
return 1;
}
@@ -490,7 +513,7 @@ static uint8_t client_parse(Client *client, int size) {
if (client->bytes_received == (uint64_t) (client->header_size + client->content_length)) {
/* full response received */
client->state = CLIENT_END;
- client->success = client->status_200 ? 1 : 0;
+ client->success = client->status_success ? 1 : 0;
}
}
diff --git a/src/client.h b/src/client.h
index 54ee5a7..0e387d1 100644
--- a/src/client.h
+++ b/src/client.h
@@ -33,7 +33,7 @@ struct Client {
ev_tstamp ts_end;
uint8_t keepalive;
uint8_t success;
- uint8_t status_200;
+ uint8_t status_success;
uint8_t chunked;
int64_t chunk_size;
int64_t chunk_received;
diff --git a/src/weighttp.c b/src/weighttp.c
index 370e9ec..56862ef 100644
--- a/src/weighttp.c
+++ b/src/weighttp.c
@@ -369,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);
}
@@ -387,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
);
diff --git a/src/worker.c b/src/worker.c
index 291981c..fea79a8 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -52,7 +52,8 @@ void *worker_thread(void* arg) {
/* start all clients */
for (i = 0; i < worker->num_clients; i++) {
- client_state_machine(worker->clients[i]);
+ if (worker->stats.req_started < worker->stats.req_todo)
+ client_state_machine(worker->clients[i]);
}
ev_loop(worker->loop, 0);
diff --git a/src/worker.h b/src/worker.h
index fd6f041..318d325 100644
--- a/src/worker.h
+++ b/src/worker.h
@@ -20,6 +20,11 @@ struct Stats {
uint64_t req_error; /* total number of error'd requests */
uint64_t bytes_total; /* total number of bytes received (html+body) */
uint64_t bytes_body; /* total number of bytes received (body) */
+ uint64_t req_1xx;
+ uint64_t req_2xx;
+ uint64_t req_3xx;
+ uint64_t req_4xx;
+ uint64_t req_5xx;
};
struct Worker {