view release on metacpan or search on metacpan
* implement per-run execute() using system threads, then global execute() can
just fire off as many threads as there are runs
- this would allow (re-)sending of individual runs, iterations within a run
- complications with concurrent request slots: does each thread keep
its own set of file descriptors, or (sh)(c)ould threads share them?
* need a way to simulate real-world problems: for example
- slow dialup modem connections
o e.g. add an automatic delay after each request in a run
o also support a pre-configured delay inside a run
- user-presses-stop, aka broken socket
* bring up-to-date with current Apache 2.0 distribution of ab.c
- including SSL support
* perl subroutine hooks between requests in a sequence, with access
to all prior regression data and ability to dynamically change current or
future requests in sequence
doc/README.old view on Meta::CPAN
After having your desired configuration and runs added, call
$re->execute to perform the requests,
RETURN VALUE
Bench returns a hash reference which has the key for each run,
(keys as "run0", "run1", etc), besides "warn" and "total_time"
and "bytes_received". Each run is again a hash, which has the
keys for each url,besides "thread".
The value stored in the key for each run is again a hash
reference which has the following key/value pairs:
"hostname" => a string of the url's hostname;
"software" => a string of the server software;
"path" => a string of the url's path;
"port" => the port of the server;
"doc_length" => the document length(amount of body read);
"completed_requests" => the requests completed;
doc/README.old view on Meta::CPAN
connect in total among our requests to this url;
"average_connect_time" => the average time taken to
connect this server for all the requests;
"average_time" => the average time taken to process and
connect this server for all the requests;
if "POST" is used:
"total_posted" => total amount posted to the server;
The value stored in the key "threads" is an array reference which
keeps information for each sequence of requests (that is, visit
each of the urls once in order).
Each entry of the array is a reference to a hash which has the
following key/value pairs:
"total_time" => an array reference, keeps how much time
taken (process and connect) for each url
in order for this thread;
"connect_time" => an array reference,keeps how much time
taken to connect each server in order
for this thread;
"page_content" => an array reference, keeps the contents
read from the servers;
"headers" => an array reference keeping the headers
for every urls in the thread.
The value stored in the key "warn" is a string containing the
warn and error message generated by ab.
The value stored in the key "total_time" is the total time taken
for all our processs and connections in total.
The value stored in the key "bytes_received" is the total bytes
received from all the requests in total.
doc/README.upgrading_0.5x-0.6x view on Meta::CPAN
$rhash = $re->{'regression'};
4) The regression hash no longer contains any per-URL information.
Half of the data keyed on URL was wrong, and the other half was
fairly useless, so it is no longer returned at all.
The fix:
- remove all references to URLs in the regression hash, e.g.
anything that looks like $re->{'run0'}->{'http://test.url/'}
5) What was stored in the 'threads' array reference (for each run),
is now in the top-level of the regression hash for each run.
The term threads was confusing, especially considering an upcoming
rewrite will probably include multi-threaded request sending.
The fix:
- replace all $re->{'run0'}->{'threads'} with $rhash->{'run0'}
Notice that each runI entry in the regression hash is now an ARRAY ref, not
a HASH ref. Your Perl script will fail unless you treat them as such.
6) Read the documentation. There is a much more intuitive way of
getting regression data using object method calls, rather than poking
around through the huge regression hash. Configuration can also now be
done with method calls.
--
src/ApacheBench.xs view on Meta::CPAN
if (AB_DEBUG_XS) printf("AB_DEBUG: done with test()\n");
RETVAL = newHV();/* ready to get information stored in global variables */
for (k = 0; k < registry->number_of_runs; k++) {
if (registry->memory[k] >= 1) {
AV *started = newAV();/* number of started requests for each url */
AV *good = newAV(); /* number of good responses for each url */
AV *failed = newAV(); /* number of bad responses for each url */
tmpav = newAV(); /* array to keep the thread information */
if (AB_DEBUG_XS) printf("AB_DEBUG: getting regression info for run %d\n", k);
for (i = 0; i < registry->repeats[k]; i++) {
AV *th_t = newAV(); /* times for processing and connecting */
AV *th_r = newAV(); /* times for http request */
AV *th_c = newAV(); /* connecting times */
AV *page_contents = newAV(); /* pages read from servers */
AV *request_headers = newAV(); /* HTTP requests sent to servers */
AV *request_body = newAV(); /* HTTP requests sent to servers */
src/apachebench/execute.c view on Meta::CPAN
int i,j;
#ifdef AB_DEBUG
printf("AB_DEBUG: start of initialize()\n");
#endif
registry->cookie = malloc(registry->number_of_runs * sizeof(char *));
registry->buffersize = malloc(registry->number_of_runs * sizeof(int));
registry->auto_cookies = (char ***) calloc(registry->number_of_runs, sizeof(char **)); // must be zeroed for the calloc code in http_util.c
registry->which_thread = malloc(registry->number_of_urls * sizeof(int *));
registry->arranged = malloc(registry->number_of_urls * sizeof(int));
for (i = 0; i < registry->number_of_urls; i++)
registry->arranged[i] = 0;
for (i = 0; i < registry->number_of_runs; i++) {
for (j = registry->position[i]; j < registry->position[i+1]; j++)
registry->which_thread[j] = malloc(registry->repeats[i] * sizeof(int));
for (j = 0; j < registry->repeats[i]; j++)
registry->which_thread[registry->position[i]][j] = j;
registry->need_to_be_done += registry->repeats[i] * (registry->position[i+1] - registry->position[i]);
}
registry->ready_to_run_queue = malloc(registry->need_to_be_done * sizeof(struct threadval));
for (i = 0; i < registry->number_of_runs; i++) {
if (registry->order[i] == DEPTH_FIRST) {
if ((registry->priority == EQUAL_OPPORTUNITY) || (registry->tail < registry->concurrency)) {
registry->arranged[registry->position[i]] = 1;
registry->ready_to_run_queue[registry->tail].run = i;
registry->ready_to_run_queue[registry->tail].url = registry->position[i];
registry->ready_to_run_queue[registry->tail++].thread = 0;
}
} else for (j = 0; j < registry->repeats[i]; j++)
if ((registry->priority == EQUAL_OPPORTUNITY) || (registry->tail < registry->concurrency)) {
registry->arranged[registry->position[i]] += 1;
registry->ready_to_run_queue[registry->tail].run = i;
registry->ready_to_run_queue[registry->tail].thread = j;
registry->ready_to_run_queue[registry->tail++].url = registry->position[i];
}
}
registry->hostname = malloc(registry->number_of_urls * sizeof(char *));
registry->path = malloc(registry->number_of_urls * sizeof(char *));
registry->port = malloc(registry->number_of_urls * sizeof(int));
registry->ctypes = malloc(registry->number_of_urls * sizeof(char *));
registry->req_headers = malloc(registry->number_of_urls * sizeof(char *));
registry->keepalive = malloc(registry->number_of_urls * sizeof(bool));
registry->url_tlimit = malloc(registry->number_of_urls * sizeof(double));
src/apachebench/execute.c view on Meta::CPAN
memset(registry->con, 0, registry->concurrency * sizeof(struct connection));
#ifdef AB_DEBUG
printf("AB_DEBUG: start of test()\n");
#endif
for (i = 0; i < registry->concurrency; i++) {
registry->con[i].url = registry->ready_to_run_queue[i].url;
registry->con[i].run = registry->ready_to_run_queue[i].run;
registry->con[i].state = STATE_READY;
registry->con[i].thread = registry->ready_to_run_queue[i].thread;
}
#ifdef AB_DEBUG
printf("AB_DEBUG: test() - stage 1\n");
#endif
registry->stats = calloc(registry->number_of_urls, sizeof(struct data *));
for (i = 0; i < registry->number_of_runs; i++) {
int j;
for (j = registry->position[i]; j < registry->position[i+1]; j++)
src/apachebench/execute.c view on Meta::CPAN
#ifdef AB_DEBUG
printf("AB_DEBUG: test() - stage 5.5.4, Time taken for current request = %d ms; Per-url time limit = %.4f sec; for run %d, url %d\n", timedif(url_now, c->start_time), registry->url_tlimit[c->url], c->run, c->url - registry->position[c...
printf("AB_DEBUG: test() - stage 5.5.5, registry->done = %d, i = %d\n", registry->done, i);
#endif
if (registry->url_tlimit[c->url] &&
timedif(url_now, c->start_time) > (registry->url_tlimit[c->url] * 1000)) {
char *warn = malloc(256 * sizeof(char));
#ifdef AB_DEBUG
printf("AB_DEBUG: test() - stage 5.5.5.3, registry->done = %d, i = %d\n", registry->done, i);
#endif
sprintf(warn, "Per-url time limit reached (%.3f sec) for run %d, url %d, iteration %d; connection closed prematurely", registry->url_tlimit[c->url], c->run, c->url - registry->position[c->run], c->thread);
myerr(registry->warn_and_error, warn);
free(warn);
registry->failed[c->url]++;
close_connection(registry, c);
continue;
}
}
if (registry->con[i].state == STATE_DONE)
src/apachebench/http_util.c view on Meta::CPAN
}
/* --------------------------------------------------------- */
/* extract cookies from response_data (Set-Cookie: headers) and save to auto_cookies */
static void
allocate_auto_cookie_memory(struct global * registry, struct connection * c) {
#ifdef AB_DEBUG
printf("AB_DEBUG: start of allocate_auto_cookie_memory(): run %d, thread %d\n", c->run, c->thread);
#endif
if (registry->auto_cookies[c->run] == NULL) {
registry->auto_cookies[c->run] = (char **) calloc(registry->repeats[c->run], sizeof(char *));
#ifdef AB_DEBUG
printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 1: run %d, thread %d\n", c->run, c->thread);
#endif
}
if (registry->auto_cookies[c->run][c->thread] == NULL) {
registry->auto_cookies[c->run][c->thread] = (char *) calloc(CBUFFSIZE, sizeof(char));
#ifdef AB_DEBUG
printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 2: run %d, thread %d\n", c->run, c->thread);
#endif
}
}
static void
extract_cookies_from_response(struct global * registry, struct connection * c) {
char * set_cookie_hdr, * eoh;
#ifdef AB_DEBUG
printf("AB_DEBUG: start of extract_cookies_from_response()\n");
#endif
if (registry->failed[c->url] > 0)
return;
allocate_auto_cookie_memory(registry, c);
#ifdef AB_DEBUG
printf("AB_DEBUG: extract_cookies_from_response() - stage 1; run %d, thread %d\n", c->run, c->thread);
#endif
if (! c->response_headers) return;
set_cookie_hdr = strstr(c->response_headers, "\r\nSet-Cookie: ");
while (set_cookie_hdr) {
remove_existing_cookie_from_auto_cookies(registry, c, set_cookie_hdr);
#ifdef AB_DEBUG
printf("AB_DEBUG: extract_cookies_from_response() - stage 2.1; run %d, thread %d, postdata[%d] = %s\n", c->run, c->thread, c->url, registry->postdata[c->url]);
#endif
eoh = strstr(set_cookie_hdr+2, "\r\n");
if (! strnstr(set_cookie_hdr, "=; Expires=", eoh - set_cookie_hdr)) // hack: do not set expired headers
// drop the "Set-" from beginning to just append "Cookie: ....\r\n"
strncat(registry->auto_cookies[c->run][c->thread], set_cookie_hdr + 6, eoh - set_cookie_hdr - 4);
#ifdef AB_DEBUG
printf("AB_DEBUG: extract_cookies_from_response() - stage 2.2; run %d, thread %d, auto_cookies[%d][%d] = %s\n", c->run, c->thread, c->run, c->url, registry->auto_cookies[c->run][c->thread]);
#endif
set_cookie_hdr = strstr(set_cookie_hdr+1, "\r\nSet-Cookie: ");
}
}
/* remove existing cookies from registry->auto_cookies[..][..] which will be set again by extract_cookies_from_response() */
static void
remove_existing_cookie_from_auto_cookies(struct global * registry, struct connection * c, char * set_cookie_hdr) {
src/apachebench/http_util.c view on Meta::CPAN
// first need to find the name of cookie on current "Set-Cookie: " header line
cookie_name = (char *) calloc(CBUFFSIZE, sizeof(char));
strcat(cookie_name, "Cookie: ");
eoh = strstr(set_cookie_hdr+14, "\r\n");
strncat(cookie_name, set_cookie_hdr+14, strnstr(set_cookie_hdr+14, "=", eoh-(set_cookie_hdr+14)) - (set_cookie_hdr+14));
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1\n");
#endif
existing_cookie = strstr(registry->auto_cookies[c->run][c->thread], cookie_name);
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1.1\n");
#endif
if (existing_cookie) {
new_auto_cookies = (char *) calloc(CBUFFSIZE, sizeof(char));
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.1\n");
#endif
strncpy(new_auto_cookies, registry->auto_cookies[c->run][c->thread], existing_cookie - registry->auto_cookies[c->run][c->thread]);
end_of_existing_cookie = strstr(existing_cookie, "\r\n");
strcat(new_auto_cookies, end_of_existing_cookie+2);
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.2\n");
#endif
// overwrite auto_cookies with new version with existing_cookie removed
strcpy(registry->auto_cookies[c->run][c->thread], new_auto_cookies);
free(new_auto_cookies);
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.3, auto_cookies[%d][%d] = %s\n", c->url, c->thread, registry->auto_cookies[c->url][c->thread]);
#endif
}
#ifdef AB_DEBUG
printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 3, cookie_name = %s\n", cookie_name);
#endif
free(cookie_name);
#ifdef AB_DEBUG
printf("AB_DEBUG: end of remove_existing_cookie_from_auto_cookies(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);
src/apachebench/regression_data.c view on Meta::CPAN
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "regression_data.h"
static void
initialize_regression_data(struct data * s) {
s->run = 0;
s->thread = 0;
s->read = 0;
s->bread = 0;
s->ctime = 0;
s->rtime = 0;
s->time = 0;
s->request = 0;
s->request_headers = 0;
s->response_headers = 0;
src/apachebench/regression_data.c view on Meta::CPAN
#ifdef AB_DEBUG
printf("AB_DEBUG: start of store_regression_data(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);
#endif
if (registry->failed[c->url] > 0)
return;
if (c->read >= registry->buffersize[c->run] &&
registry->memory[c->run] >= 3) {
char * warn = malloc(256 * sizeof(char));
sprintf(warn, "[run %d, iter %d, req %d]: Buffer size of %d is too small, got response of size %d", c->run, c->thread, c->url, registry->buffersize[c->run], c->read);
myerr(registry->warn_and_error, warn);
free(warn);
}
if (c->read == 0) {
if (registry->memory[c->run] >= 3)
c->response = "";
if (registry->memory[c->run] >= 2)
c->response_headers = "";
}
src/apachebench/regression_data.c view on Meta::CPAN
int postdata_generation_time = timedif(c->connect_time, c->before_postdata_time);
if (c->connect_time.tv_sec || c->connect_time.tv_usec)
s.ctime = timedif(c->connect_time, c->start_time) - postdata_generation_time;
else
s.ctime = 0;
if (c->sent_request_time.tv_sec || c->sent_request_time.tv_usec)
s.rtime = timedif(c->sent_request_time, c->start_time) - postdata_generation_time;
else
s.rtime = 0;
s.time = timedif(c->done_time, c->start_time) - postdata_generation_time;
s.thread = c->thread;
s.read = c->read;
}
#ifdef AB_DEBUG
printf("AB_DEBUG: store_regression_data() - stage 2\n");
#endif
if (registry->memory[c->run] >= 2) {
s.bread = c->bread;
s.request_headers = malloc((strlen(c->request_headers)+1) * sizeof(char));
src/apachebench/regression_data.c view on Meta::CPAN
#endif
strcat(s.request, registry->postdata[c->url]);
} else {
s.request = malloc((strlen(c->request)+1) * sizeof(char));
strcpy(s.request, c->request);
}
}
#ifdef AB_DEBUG
printf("AB_DEBUG: store_regression_data() - saving stats, c->url %d, c->thread %d\n", c->url, c->thread);
#endif
registry->stats[c->url][c->thread] = s;
registry->total_bytes_received += c->read;
}
src/apachebench/socket_io.c view on Meta::CPAN
char *post_body;
#ifdef AB_DEBUG
printf("AB_DEBUG: write_request() - stage 1, registry->done = %d\n", registry->done);
#endif
gettimeofday(&c->before_postdata_time, 0);
/* the url in this run has dynamicly-generated postdata */
if (registry->posting[c->url] == 2) {
res = call_perl_function__one_arg(registry->postsubs[c->url],
newSVpv(c->url > 0 ? registry->stats[c->url - 1][c->thread].response : "", 0));
if (SvPOK(res)) {
post_body = SvPV(res, len);
#ifdef AB_DEBUG
printf("AB_DEBUG: write_request() - stage 1-postsub.2, postsub res %s, length %d\n", post_body, (int)len);
#endif
registry->postdata[c->url] = post_body;
registry->postlen[c->url] = (int) len;
} else {
registry->postdata[c->url] = "";
src/apachebench/socket_io.c view on Meta::CPAN
if (registry->keepalive[i])
strcat(c->request_headers, "Connection: Keep-Alive\r\n");
if (registry->cookie[c->run]) {
strcat(c->request_headers, "Cookie: ");
strcat(c->request_headers, registry->cookie[c->run]);
strcat(c->request_headers, "\r\n");
}
#ifdef AB_DEBUG
printf("AB_DEBUG: reset_request() - stage 2.1: c->run %d; c->thread %d\n", c->run, c->thread);
#endif
allocate_auto_cookie_memory(registry, c);
if (registry->use_auto_cookies[c->run] && registry->auto_cookies[c->run] != NULL && registry->auto_cookies[c->run][c->thread] != NULL) {
#ifdef AB_DEBUG
printf("AB_DEBUG: reset_request() - stage 2.2a: request_headers %s\n", c->request_headers);
printf("AB_DEBUG: reset_request() - stage 2.2b: auto_cookies %s\n", registry->auto_cookies[c->run][c->thread]);
#endif
strcat(c->request_headers, registry->auto_cookies[c->run][c->thread]);
}
#ifdef AB_DEBUG
printf("AB_DEBUG: reset_request() - stage 2.3: c->run %d; c->thread %d\n", c->run, c->thread);
#endif
if (registry->req_headers[i]) {
strcat(c->request_headers, registry->req_headers[i]);
strcat(c->request_headers, "\r\n");
}
strcat(c->request_headers, "\r\n");
#ifdef AB_DEBUG
printf("AB_DEBUG: reset_request() - stage 2.4: c->run %d; c->thread %d\n", c->run, c->thread);
#endif
strcpy(c->request, c->request_headers);
c->reqlen = strlen(c->request);
#ifdef AB_DEBUG
printf("AB_DEBUG: reset_request() - stage 3\n");
#endif
#ifdef CHARSET_EBCDIC
src/apachebench/socket_io.c view on Meta::CPAN
#endif /* CHARSET_EBCDIC */
return 0;
}
/* --------------------------------------------------------- */
/* setup the next request in the sequence / repetition / run to be sent
returns 1 if the next request is ready to be sent,
returns 0 if this connection is done,
sets the connection values: c->run, c->url, c->thread, and c->state,
as well as helper structures: registry->which_thread[][],
registry->ready_to_run_queue[], and registry->arranged[]
*/
static int
schedule_next_request(struct global * registry, struct connection * c) {
if (registry->priority == RUN_PRIORITY) {
/* if the last url in this run has repeated enough, go to next run */
if (registry->started[registry->position[c->run + 1] - 1] >= registry->repeats[c->run])
return schedule_request_in_next_run(registry, c);
/* possible more resources needed in this group */
/* started[position[c->run + 1] - 1] < repeats[c->run] */
if (registry->order[c->run] == DEPTH_FIRST) {
/* for depth_first, connect the next one and restart the
sequence if we're at the last url in the run */
if (++c->url == registry->position[c->run + 1]) {
c->url = registry->position[c->run];
c->thread = registry->started[c->url];
}
return 1;
} else { /* breadth_first */
if (c->url < (registry->position[c->run + 1] - 1))
/* TODO: check if (registry->finished[c->url] > 0) ??? */
registry->which_thread[c->url+1][registry->finished[c->url] - 1] = c->thread;
if (registry->started[c->url] == registry->repeats[c->run])
/* go to next url in sequence if we repeated this one enough */
c->url++;
if (c->url == registry->position[c->run]) {
/* this is the first url in the sequence: set its repetition
number to the initial incremental value (0, 1, 2, 3, ...) */
c->thread = registry->which_thread[c->url][registry->started[c->url]];
return 1;
}
/* only start another request from this run if more requests of the
previous url in the sequence have finished(in-order execution)*/
if (registry->started[c->url] < registry->finished[c->url - 1]) {
c->thread = registry->started[c->url];
return 1;
} else {
return schedule_request_in_next_run(registry, c);
}
}
} else { /* equal_opportunity */
/* we use a FIFO to queue up requests to be sent */
if (c->url < registry->position[c->run + 1]-1) {
/* if url is before the end of the url sequence,
add it to the tail of the request queue */
registry->ready_to_run_queue[registry->tail].url = c->url + 1;
registry->ready_to_run_queue[registry->tail].thread = c->thread;
registry->ready_to_run_queue[registry->tail++].run = c->run;
registry->arranged[c->url + 1]++;
} else if (registry->order[c->run] == DEPTH_FIRST
&& registry->arranged[registry->position[c->run]] < registry->repeats[c->run]) {
/* end of the url sequence in depth_first with more repetitions
necessary: start from the beginning of the url sequence */
registry->ready_to_run_queue[registry->tail].url = registry->position[c->run];
registry->ready_to_run_queue[registry->tail].thread = registry->arranged[registry->position[c->run]]++;
registry->ready_to_run_queue[registry->tail++].run = c->run;
}
if (registry->head >= registry->tail) {
c->state = STATE_DONE;
return 0;
}
c->thread = registry->ready_to_run_queue[registry->head].thread;
c->url = registry->ready_to_run_queue[registry->head].url;
c->run = registry->ready_to_run_queue[registry->head++].run;
return 1;
}
}
/* --------------------------------------------------------- */
/* move connection to the next run, because the current run either doesn't need
or cannot use any more connection slots (resources)
src/apachebench/socket_io.c view on Meta::CPAN
or is a depth_first run which only requires one slot,
so doesn't need this resource anymore */
c->run++;
continue;
}
/* start at first url in the run */
c->url = registry->position[c->run];
if (registry->started[c->url] < registry->repeats[c->run]) {
/* for breadth_first, start one more connect to 1st url if possible
for depth_first, get started here */
c->thread = registry->which_thread[c->url][registry->started[c->url]];
return 1;
}
/* look at each url in the sequence until we find one which needs
to be repeated more */
while (++c->url < registry->position[c->run + 1]
&& registry->started[c->url] >= registry->repeats[c->run]);
/* only start another request from this run if more requests of the
previous url in the sequence have finished (in-order execution) */
if (registry->started[c->url] < registry->finished[c->url - 1]) {
c->thread = registry->which_thread[c->url][registry->started[c->url]];
return 1;
} else
/* this run doesn't need any more resources */
c->run++;
}
/* no one needs any more resources */
c->state = STATE_DONE;
return 0;
}
src/apachebench/types.h view on Meta::CPAN
int state;
int url; /* which url are we testing */
int read; /* amount of bytes read */
int bread; /* amount of body read */
int length; /* Content-Length value used for keep-alive */
char cbuff[CBUFFSIZE]; /* a buffer to store server response header */
int cbx; /* offset in cbuffer */
int keepalive; /* non-zero if a keep-alive request */
int gotheader; /* non-zero if we have the entire header in
* cbuff */
int thread; /* Thread number */
int run;
struct timeval start_time, connect_time, before_postdata_time, sent_request_time, done_time;
char *request; /* HTTP request */
char *request_headers;
int reqlen;
char *response_headers; /* HTTP response */
char *response;
};
struct data {
int run; /* which run */
int thread; /* Thread number */
int read; /* number of bytes read */
int bread; /* total amount of entity body read */
int ctime; /* time in ms to connect */
int rtime; /* time in ms for http request */
int time; /* time in ms for full req/resp interval */
char *request;
char *request_headers;
char *response_headers;
char *response;
};
struct threadval {
int run; /* which run */
int url; /* which url are we testing */
int thread; /* Thread number */
};
/* --------------------- GLOBALS ---------------------------- */
struct global {
int concurrency; /* Number of multiple requests to make */
int *repeats; /* Number of time to repeat for each run */
int requests; /* the max of the repeats */
double tlimit; /* global time limit, in seconds */
struct timeval min_tlimit; /* minimum of all time limits */
src/apachebench/types.h view on Meta::CPAN
char **req_headers; /* optional arbitrary request headers to add */
char ***auto_cookies; /* cookies extracted from response_headers for the run, i.e. set by http server */
bool *use_auto_cookies; /* whether to use auto_cookie feature for the run */
int *postlen; /* length of data to be POSTed */
int *totalposted; /* total number of bytes posted, inc. headers*/
int *good, *failed; /* number of good and bad requests */
int *started, *finished, *arranged;
/* numbers of requests started , */
/* finished or arranged for each url*/
int **which_thread; /* which thread is available */
struct threadval *ready_to_run_queue;
int head, tail, done, need_to_be_done;
int priority;
int *order;
int *buffersize;
int *memory;
int number_of_urls, number_of_runs;
char version[8]; /* to store perl module version */
char warn_and_error[WARN_BUFFSIZE]; /* warn and error message returned to perl */