--- ../../httpd-2.2/support/ab.c 2008-04-17 09:31:08.000000000 -0700 +++ ab.c 2008-05-12 14:24:27.000000000 -0700 @@ -80,6 +80,10 @@ ** Switched to the new abstract pollset API, allowing ab to ** take advantage of future apr_pollset_t scalability improvements. ** Contributed by Brian Pane, August 31, 2002 + ** + ** Version 2.3 + ** SIGINT now triggers output_results(). + ** Contributed by colm, March 30, 2006 **/ /* Note: this version string should start with \d+[\d\.]* and be a valid @@ -91,7 +95,7 @@ * ab - or to due to a change in the distribution it is compiled with * (such as an APR change in for example blocking). */ -#define AP_AB_BASEREVISION "2.0.40-dev" +#define AP_AB_BASEREVISION "2.3" /* * BUGS: @@ -199,7 +203,7 @@ #endif /* maximum number of requests on a time limited test */ -#define MAX_REQUESTS 50000 +#define MAX_REQUESTS (INT_MAX > 50000 ? 50000 : INT_MAX) /* good old state hostname */ #define STATE_UNCONNECTED 0 @@ -238,22 +242,22 @@ }; struct data { - int read; /* number of bytes read */ - apr_time_t starttime; /* start time of connection in seconds since - * Jan. 1, 1970 */ - apr_interval_time_t waittime; /* Between writing request and reading - * response */ - apr_interval_time_t ctime; /* time in ms to connect */ - apr_interval_time_t time; /* time in ms for connection */ + apr_time_t starttime; /* start time of connection */ + apr_interval_time_t waittime; /* between request and reading response */ + apr_interval_time_t ctime; /* time to connect */ + apr_interval_time_t time; /* time for connection */ }; #define ap_min(a,b) ((a)<(b))?(a):(b) #define ap_max(a,b) ((a)>(b))?(a):(b) +#define ap_round_ms(a) ((apr_time_t)((a) + 500)/1000) +#define ap_double_ms(a) ((double)(a)/1000.0) #define MAX_CONCURRENCY 20000 /* --------------------- GLOBALS ---------------------------- */ int verbosity = 0; /* no verbosity by default */ +int recverrok = 0; /* ok to proceed after socket receive errors */ int posting = 0; /* GET by default */ int requests = 1; /* Number of requests to make */ int heartbeatres = 100; /* How often do we say we're alive */ @@ -262,6 +266,7 @@ int confidence = 1; /* Show confidence estimator and warnings */ int tlimit = 0; /* time limit in secs */ int keepalive = 0; /* try and do keepalive connections */ +int windowsize = 0; /* we use the OS default window size */ char servername[1024]; /* name that server reports */ char *hostname; /* host name from URL */ char *host_field; /* value of "Host:" header field */ @@ -298,15 +303,20 @@ const char *trstring; const char *tdstring; -apr_size_t doclen = 0; /* the length the document should be */ -long started = 0; /* number of requests started, so no excess */ -apr_uint64_t totalread = 0; /* total number of bytes read */ -apr_uint64_t totalbread = 0; /* totoal amount of entity body read */ -apr_uint64_t totalposted = 0; /* total number of bytes posted, inc. headers */ -long done = 0; /* number of requests we have done */ -long doneka = 0; /* number of keep alive connections done */ -long good = 0, bad = 0; /* number of good and bad requests */ -long epipe = 0; /* number of broken pipe writes */ +apr_size_t doclen = 0; /* the length the document should be */ +apr_int64_t totalread = 0; /* total number of bytes read */ +apr_int64_t totalbread = 0; /* totoal amount of entity body read */ +apr_int64_t totalposted = 0; /* total number of bytes posted, inc. headers */ +int started = 0; /* number of requests started, so no excess */ +int done = 0; /* number of requests we have done */ +int doneka = 0; /* number of keep alive connections done */ +int good = 0, bad = 0; /* number of good and bad requests */ +int epipe = 0; /* number of broken pipe writes */ +int err_length = 0; /* requests failed due to response length */ +int err_conn = 0; /* requests failed due to connection drop */ +int err_recv = 0; /* requests failed due to broken read */ +int err_except = 0; /* requests failed due to exception */ +int err_response = 0; /* requests with invalid or non-200 response */ #ifdef USE_SSL int is_ssl; @@ -316,11 +326,7 @@ BIO *bio_out,*bio_err; #endif -/* store error cases */ -int err_length = 0, err_conn = 0, err_except = 0; -int err_response = 0; - -apr_time_t start, endtime; +apr_time_t start, lasttime, stoptime; /* global request (and its length) */ char _request[2048]; @@ -334,7 +340,7 @@ int percs[] = {50, 66, 75, 80, 90, 95, 98, 99, 100}; struct connection *con; /* connection array */ -struct data *stats; /* date for each request */ +struct data *stats; /* data for each request */ apr_pool_t *cntxt; apr_pollset_t *readbits; @@ -356,7 +362,7 @@ { fprintf(stderr, "%s\n", s); if (done) - printf("Total of %ld requests completed\n" , done); + printf("Total of %d requests completed\n" , done); exit(1); } @@ -370,7 +376,7 @@ "%s: %s (%d)\n", s, apr_strerror(rv, buf, sizeof buf), rv); if (done) - printf("Total of %ld requests completed\n" , done); + printf("Total of %d requests completed\n" , done); exit(rv); } @@ -609,18 +615,20 @@ static void write_request(struct connection * c) { do { - apr_time_t tnow = apr_time_now(); + apr_time_t tnow; apr_size_t l = c->rwrite; apr_status_t e = APR_SUCCESS; /* prevent gcc warning */ + tnow = lasttime = apr_time_now(); + /* * First time round ? */ if (c->rwrite == 0) { apr_socket_timeout_set(c->aprsock, 0); c->connect = tnow; - c->rwrite = reqlen; c->rwrote = 0; + c->rwrite = reqlen; if (posting) c->rwrite += postlen; } @@ -647,30 +655,19 @@ #endif e = apr_socket_send(c->aprsock, request + c->rwrote, &l); - /* - * Bail early on the most common case - */ - if (l == c->rwrite) - break; - - if (e != APR_SUCCESS) { - /* - * Let's hope this traps EWOULDBLOCK too ! - */ - if (!APR_STATUS_IS_EAGAIN(e)) { - epipe++; - printf("Send request failed!\n"); - close_connection(c); - } + if (e != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(e)) { + epipe++; + printf("Send request failed!\n"); + close_connection(c); return; } + totalposted += l; c->rwrote += l; c->rwrite -= l; - } while (1); + } while (c->rwrite); - totalposted += c->rwrite; c->state = STATE_READ; - c->endwrite = apr_time_now(); + c->endwrite = lasttime = apr_time_now(); { apr_pollfd_t new_pollfd; new_pollfd.desc_type = APR_POLL_SOCKET; @@ -723,15 +720,14 @@ return 0; } -static void output_results(void) +static void output_results(int sig) { - apr_interval_time_t timetakenusec; - float timetaken; + double timetaken; - endtime = apr_time_now(); - timetakenusec = endtime - start; - timetaken = ((float)apr_time_sec(timetakenusec)) + - ((float)apr_time_usec(timetakenusec)) / 1000000.0F; + if (sig) { + lasttime = apr_time_now(); /* record final time if interrupted */ + } + timetaken = (double) (lasttime - start) / APR_USEC_PER_SEC; printf("\n\n"); printf("Server Software: %s\n", servername); @@ -747,45 +743,43 @@ printf("Document Length: %" APR_SIZE_T_FMT " bytes\n", doclen); printf("\n"); printf("Concurrency Level: %d\n", concurrency); - printf("Time taken for tests: %ld.%03ld seconds\n", - (long) apr_time_sec(timetakenusec), - (long) apr_time_usec(timetakenusec)); - printf("Complete requests: %ld\n", done); - printf("Failed requests: %ld\n", bad); + printf("Time taken for tests: %.3f seconds\n", timetaken); + printf("Complete requests: %d\n", done); + printf("Failed requests: %d\n", bad); if (bad) - printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", - err_conn, err_length, err_except); - printf("Write errors: %ld\n", epipe); + printf(" (Connect: %d, Receive: %d, Length: %d, Exceptions: %d)\n", + err_conn, err_recv, err_length, err_except); + printf("Write errors: %d\n", epipe); if (err_response) printf("Non-2xx responses: %d\n", err_response); if (keepalive) - printf("Keep-Alive requests: %ld\n", doneka); - printf("Total transferred: %" APR_UINT64_T_FMT " bytes\n", totalread); + printf("Keep-Alive requests: %d\n", doneka); + printf("Total transferred: %" APR_INT64_T_FMT " bytes\n", totalread); if (posting > 0) - printf("Total POSTed: %" APR_UINT64_T_FMT "\n", totalposted); - printf("HTML transferred: %" APR_UINT64_T_FMT " bytes\n", totalbread); + printf("Total POSTed: %" APR_INT64_T_FMT "\n", totalposted); + printf("HTML transferred: %" APR_INT64_T_FMT " bytes\n", totalbread); /* avoid divide by zero */ - if (timetaken) { + if (timetaken && done) { printf("Requests per second: %.2f [#/sec] (mean)\n", - (float) (done / timetaken)); + (double) done / timetaken); printf("Time per request: %.3f [ms] (mean)\n", - (float) (1000 * concurrency * timetaken / done)); + (double) concurrency * timetaken * 1000 / done); printf("Time per request: %.3f [ms] (mean, across all concurrent requests)\n", - (float) (1000 * timetaken / done)); + (double) timetaken * 1000 / done); printf("Transfer rate: %.2f [Kbytes/sec] received\n", - (float) (totalread / 1024 / timetaken)); + (double) totalread / 1024 / timetaken); if (posting > 0) { printf(" %.2f kb/s sent\n", - (float) (totalposted / timetaken / 1024)); + (double) totalposted / timetaken / 1024); printf(" %.2f kb/s total\n", - (float) ((totalread + totalposted) / timetaken / 1024)); + (double) (totalread + totalposted) / timetaken / 1024); } } - if (requests) { + if (done > 0) { /* work out connection times */ - long i; + int i; apr_time_t totalcon = 0, total = 0, totald = 0, totalwait = 0; apr_time_t meancon, meantot, meand, meanwait; apr_interval_time_t mincon = AB_MAX, mintot = AB_MAX, mind = AB_MAX, @@ -794,119 +788,117 @@ apr_interval_time_t mediancon = 0, mediantot = 0, mediand = 0, medianwait = 0; double sdtot = 0, sdcon = 0, sdd = 0, sdwait = 0; - for (i = 0; i < requests; i++) { - struct data s = stats[i]; - mincon = ap_min(mincon, s.ctime); - mintot = ap_min(mintot, s.time); - mind = ap_min(mind, s.time - s.ctime); - minwait = ap_min(minwait, s.waittime); - - maxcon = ap_max(maxcon, s.ctime); - maxtot = ap_max(maxtot, s.time); - maxd = ap_max(maxd, s.time - s.ctime); - maxwait = ap_max(maxwait, s.waittime); - - totalcon += s.ctime; - total += s.time; - totald += s.time - s.ctime; - totalwait += s.waittime; - } - meancon = totalcon / requests; - meantot = total / requests; - meand = totald / requests; - meanwait = totalwait / requests; + for (i = 0; i < done; i++) { + struct data *s = &stats[i]; + mincon = ap_min(mincon, s->ctime); + mintot = ap_min(mintot, s->time); + mind = ap_min(mind, s->time - s->ctime); + minwait = ap_min(minwait, s->waittime); + + maxcon = ap_max(maxcon, s->ctime); + maxtot = ap_max(maxtot, s->time); + maxd = ap_max(maxd, s->time - s->ctime); + maxwait = ap_max(maxwait, s->waittime); + + totalcon += s->ctime; + total += s->time; + totald += s->time - s->ctime; + totalwait += s->waittime; + } + meancon = totalcon / done; + meantot = total / done; + meand = totald / done; + meanwait = totalwait / done; /* calculating the sample variance: the sum of the squared deviations, divided by n-1 */ - for (i = 0; i < requests; i++) { - struct data s = stats[i]; + for (i = 0; i < done; i++) { + struct data *s = &stats[i]; double a; - a = ((double)s.time - meantot); + a = ((double)s->time - meantot); sdtot += a * a; - a = ((double)s.ctime - meancon); + a = ((double)s->ctime - meancon); sdcon += a * a; - a = ((double)s.time - (double)s.ctime - meand); + a = ((double)s->time - (double)s->ctime - meand); sdd += a * a; - a = ((double)s.waittime - meanwait); + a = ((double)s->waittime - meanwait); sdwait += a * a; } - sdtot = (requests > 1) ? sqrt(sdtot / (requests - 1)) : 0; - sdcon = (requests > 1) ? sqrt(sdcon / (requests - 1)) : 0; - sdd = (requests > 1) ? sqrt(sdd / (requests - 1)) : 0; - sdwait = (requests > 1) ? sqrt(sdwait / (requests - 1)) : 0; - - if (gnuplot) { - FILE *out = fopen(gnuplot, "w"); - long i; - apr_time_t sttime; - char tmstring[1024];/* XXXX */ - if (!out) { - perror("Cannot open gnuplot output file"); - exit(1); - } - fprintf(out, "starttime\tseconds\tctime\tdtime\tttime\twait\n"); - for (i = 0; i < requests; i++) { - apr_time_t diff = stats[i].time - stats[i].ctime; + sdtot = (done > 1) ? sqrt(sdtot / (done - 1)) : 0; + sdcon = (done > 1) ? sqrt(sdcon / (done - 1)) : 0; + sdd = (done > 1) ? sqrt(sdd / (done - 1)) : 0; + sdwait = (done > 1) ? sqrt(sdwait / (done - 1)) : 0; - sttime = stats[i].starttime; - (void) apr_ctime(tmstring, sttime); - fprintf(out, "%s\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\n", - tmstring, - sttime, - stats[i].ctime, - diff, - stats[i].time, - stats[i].waittime); - } - fclose(out); - } /* * XXX: what is better; this hideous cast of the compradre function; or * the four warnings during compile ? dirkx just does not know and * hates both/ */ - qsort(stats, requests, sizeof(struct data), + qsort(stats, done, sizeof(struct data), (int (*) (const void *, const void *)) compradre); - if ((requests > 1) && (requests % 2)) - mediancon = (stats[requests / 2].ctime + stats[requests / 2 + 1].ctime) / 2; + if ((done > 1) && (done % 2)) + mediancon = (stats[done / 2].ctime + stats[done / 2 + 1].ctime) / 2; else - mediancon = stats[requests / 2].ctime; + mediancon = stats[done / 2].ctime; - qsort(stats, requests, sizeof(struct data), + qsort(stats, done, sizeof(struct data), (int (*) (const void *, const void *)) compri); - if ((requests > 1) && (requests % 2)) - mediand = (stats[requests / 2].time + stats[requests / 2 + 1].time \ - -stats[requests / 2].ctime - stats[requests / 2 + 1].ctime) / 2; + if ((done > 1) && (done % 2)) + mediand = (stats[done / 2].time + stats[done / 2 + 1].time \ + -stats[done / 2].ctime - stats[done / 2 + 1].ctime) / 2; else - mediand = stats[requests / 2].time - stats[requests / 2].ctime; + mediand = stats[done / 2].time - stats[done / 2].ctime; - qsort(stats, requests, sizeof(struct data), + qsort(stats, done, sizeof(struct data), (int (*) (const void *, const void *)) compwait); - if ((requests > 1) && (requests % 2)) - medianwait = (stats[requests / 2].waittime + stats[requests / 2 + 1].waittime) / 2; + if ((done > 1) && (done % 2)) + medianwait = (stats[done / 2].waittime + stats[done / 2 + 1].waittime) / 2; else - medianwait = stats[requests / 2].waittime; + medianwait = stats[done / 2].waittime; - qsort(stats, requests, sizeof(struct data), + qsort(stats, done, sizeof(struct data), (int (*) (const void *, const void *)) comprando); - if ((requests > 1) && (requests % 2)) - mediantot = (stats[requests / 2].time + stats[requests / 2 + 1].time) / 2; + if ((done > 1) && (done % 2)) + mediantot = (stats[done / 2].time + stats[done / 2 + 1].time) / 2; else - mediantot = stats[requests / 2].time; + mediantot = stats[done / 2].time; printf("\nConnection Times (ms)\n"); + /* + * Reduce stats from apr time to milliseconds + */ + mincon = ap_round_ms(mincon); + mind = ap_round_ms(mind); + minwait = ap_round_ms(minwait); + mintot = ap_round_ms(mintot); + meancon = ap_round_ms(meancon); + meand = ap_round_ms(meand); + meanwait = ap_round_ms(meanwait); + meantot = ap_round_ms(meantot); + mediancon = ap_round_ms(mediancon); + mediand = ap_round_ms(mediand); + medianwait = ap_round_ms(medianwait); + mediantot = ap_round_ms(mediantot); + maxcon = ap_round_ms(maxcon); + maxd = ap_round_ms(maxd); + maxwait = ap_round_ms(maxwait); + maxtot = ap_round_ms(maxtot); + sdcon = ap_double_ms(sdcon); + sdd = ap_double_ms(sdd); + sdwait = ap_double_ms(sdwait); + sdtot = ap_double_ms(sdtot); if (confidence) { -#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4d %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n" +#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4" APR_TIME_T_FMT " %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n" printf(" min mean[+/-sd] median max\n"); printf("Connect: " CONF_FMT_STRING, - mincon, (int) (meancon + 0.5), sdcon, mediancon, maxcon); + mincon, meancon, sdcon, mediancon, maxcon); printf("Processing: " CONF_FMT_STRING, - mind, (int) (meand + 0.5), sdd, mediand, maxd); + mind, meand, sdd, mediand, maxd); printf("Waiting: " CONF_FMT_STRING, - minwait, (int) (meanwait + 0.5), sdwait, medianwait, maxwait); + minwait, meanwait, sdwait, medianwait, maxwait); printf("Total: " CONF_FMT_STRING, - mintot, (int) (meantot + 0.5), sdtot, mediantot, maxtot); + mintot, meantot, sdtot, mediantot, maxtot); #undef CONF_FMT_STRING #define SANE(what,mean,median,sd) \ @@ -928,51 +920,73 @@ else { printf(" min avg max\n"); #define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "\n" - printf("Connect: " CONF_FMT_STRING, - mincon, meancon, maxcon); - printf("Processing: " CONF_FMT_STRING, - mintot - mincon, meantot - meancon, maxtot - maxcon); - printf("Total: " CONF_FMT_STRING, - mintot, meantot, maxtot); + printf("Connect: " CONF_FMT_STRING, mincon, meancon, maxcon); + printf("Processing: " CONF_FMT_STRING, mintot - mincon, + meantot - meancon, + maxtot - maxcon); + printf("Total: " CONF_FMT_STRING, mintot, meantot, maxtot); #undef CONF_FMT_STRING } /* Sorted on total connect times */ - if (percentile && (requests > 1)) { + if (percentile && (done > 1)) { printf("\nPercentage of the requests served within a certain time (ms)\n"); for (i = 0; i < sizeof(percs) / sizeof(int); i++) { if (percs[i] <= 0) printf(" 0%% <0> (never)\n"); else if (percs[i] >= 100) printf(" 100%% %5" APR_TIME_T_FMT " (longest request)\n", - stats[requests - 1].time); + ap_round_ms(stats[done - 1].time)); else printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], - stats[(int) (requests * percs[i] / 100)].time); + ap_round_ms(stats[(int) (done * percs[i] / 100)].time)); } } if (csvperc) { FILE *out = fopen(csvperc, "w"); - int i; if (!out) { perror("Cannot open CSV output file"); exit(1); } fprintf(out, "" "Percentage served" "," "Time in ms" "\n"); for (i = 0; i < 100; i++) { - apr_time_t t; + double t; if (i == 0) - t = stats[0].time; + t = ap_double_ms(stats[0].time); else if (i == 100) - t = stats[requests - 1].time; + t = ap_double_ms(stats[done - 1].time); else - t = stats[(int) (0.5 + requests * i / 100.0)].time; - fprintf(out, "%d,%e\n", i, (double)t); + t = ap_double_ms(stats[(int) (0.5 + done * i / 100.0)].time); + fprintf(out, "%d,%.3f\n", i, t); } fclose(out); } + if (gnuplot) { + FILE *out = fopen(gnuplot, "w"); + char tmstring[APR_CTIME_LEN]; + if (!out) { + perror("Cannot open gnuplot output file"); + exit(1); + } + fprintf(out, "starttime\tseconds\tctime\tdtime\tttime\twait\n"); + for (i = 0; i < done; i++) { + (void) apr_ctime(tmstring, stats[i].starttime); + fprintf(out, "%s\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT + "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT + "\t%" APR_TIME_T_FMT "\n", tmstring, + apr_time_sec(stats[i].starttime), + ap_round_ms(stats[i].ctime), + ap_round_ms(stats[i].time - stats[i].ctime), + ap_round_ms(stats[i].time), + ap_round_ms(stats[i].waittime)); + } + fclose(out); + } + } + if (sig) { + exit(1); } } @@ -982,10 +996,7 @@ static void output_html_results(void) { - long timetaken; - - endtime = apr_time_now(); - timetaken = (long)((endtime - start) / 1000); + double timetaken = (double) (lasttime - start) / APR_USEC_PER_SEC; printf("\n\n
| Server Software: | " @@ -1007,14 +1018,13 @@ "%d | ||
|---|---|---|---|
| Time taken for tests: | " - "%" APR_INT64_T_FMT ".%03ld seconds | %.3f seconds | \n", + trstring, tdstring, tdstring, timetaken); printf("|
| Complete requests: | " - "%ld | %d | \n", trstring, tdstring, tdstring, done); printf("|
| Failed requests: | " - "%ld | %d | \n", trstring, tdstring, tdstring, bad); if (bad) printf("|
| (Connect: %d, Length: %d, Exceptions: %d) | |||
| Keep-Alive requests: | " - "%ld | %d | \n", trstring, tdstring, tdstring, doneka); printf("|
| Total transferred: | " - "%" APR_UINT64_T_FMT " bytes | %" APR_INT64_T_FMT " bytes | \n", trstring, tdstring, tdstring, totalread); if (posting > 0) printf("|
| Total POSTed: | " - "%" APR_UINT64_T_FMT " | %" APR_INT64_T_FMT " | \n", trstring, tdstring, tdstring, totalposted); printf("|
| HTML transferred: | " - "%" APR_UINT64_T_FMT " bytes | %" APR_INT64_T_FMT " bytes | \n", trstring, tdstring, tdstring, totalbread); /* avoid divide by zero */ if (timetaken) { printf("|
| Requests per second: | " "%.2f | ||
| Transfer rate: | " "%.2f kb/s received | ||
| " " | %.2f kb/s sent | ||
| " " | %.2f kb/s total | ||
| Connnection Times (ms) | |||
| min | avg | max | %5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " | \n", - trstring, tdstring, tdstring, mincon, tdstring, totalcon / requests, tdstring, maxcon); + trstring, tdstring, tdstring, mincon, tdstring, totalcon / done, tdstring, maxcon); printf("
| Processing: | " "%5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " |
| Total: | " "%5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " | " "%5" APR_TIME_T_FMT " |
\n");
- printf(" This is ApacheBench, Version %s <%s> apache-2.0
\n", AP_AB_BASEREVISION, "$Revision: 1.146 $");
+ printf(" This is ApacheBench, Version %s <%s>
\n", AP_AB_BASEREVISION, "$Revision: 655654 $");
printf(" Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
\n");
- printf(" Copyright 2006 The Apache Software Foundation, http://www.apache.org/
\n");
+ printf(" Licensed to The Apache Software Foundation, http://www.apache.org/
\n");
printf("
\n"); } } @@ -1775,12 +1815,17 @@ "[s]" #endif "://]hostname[:port]/path\n", progname); +/* 80 column ruler: ******************************************************************************** + */ fprintf(stderr, "Options are:\n"); fprintf(stderr, " -n requests Number of requests to perform\n"); fprintf(stderr, " -c concurrency Number of multiple requests to make\n"); fprintf(stderr, " -t timelimit Seconds to max. wait for responses\n"); - fprintf(stderr, " -p postfile File containing data to POST\n"); - fprintf(stderr, " -T content-type Content-type header for POSTing\n"); + fprintf(stderr, " -b windowsize Size of TCP send/receive buffer, in bytes\n"); + fprintf(stderr, " -p postfile File containing data to POST. Remember also to set -T\n"); + fprintf(stderr, " -T content-type Content-type header for POSTing, eg.\n"); + fprintf(stderr, " 'application/x-www-form-urlencoded'\n"); + fprintf(stderr, " Default is 'text/plain'\n"); fprintf(stderr, " -v verbosity How much troubleshooting info to print\n"); fprintf(stderr, " -w Print out results in HTML tables\n"); fprintf(stderr, " -i Use HEAD instead of GET\n"); @@ -1801,6 +1846,7 @@ fprintf(stderr, " -S Do not show confidence estimators and warnings.\n"); fprintf(stderr, " -g filename Output collected data to gnuplot format file.\n"); fprintf(stderr, " -e filename Output CSV file with percentages served\n"); + fprintf(stderr, " -r Don't exit on socket receive errors.\n"); fprintf(stderr, " -h Display usage information (this message)\n"); #ifdef USE_SSL fprintf(stderr, " -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)\n"); @@ -1963,7 +2009,7 @@ #endif apr_getopt_init(&opt, cntxt, argc, argv); - while ((status = apr_getopt(opt, "n:c:t:T:p:v:kVhwix:y:z:C:H:P:A:g:X:de:Sq" + while ((status = apr_getopt(opt, "n:c:t:b:T:p:v:rkVhwix:y:z:C:H:P:A:g:X:de:Sq" #ifdef USE_SSL "Z:f:" #endif @@ -1971,7 +2017,7 @@ switch (c) { case 'n': requests = atoi(optarg); - if (!requests) { + if (requests <= 0) { err("Invalid number of requests\n"); } break; @@ -1984,6 +2030,9 @@ case 'c': concurrency = atoi(optarg); break; + case 'b': + windowsize = atoi(optarg); + break; case 'i': if (posting == 1) err("Cannot mix POST and HEAD\n"); @@ -2011,6 +2060,9 @@ exit(r); } break; + case 'r': + recverrok = 1; + break; case 'v': verbosity = atoi(optarg); break;