in wb/wb.c [2856:3202]
static void test(void)
{
apr_time_t stoptime;
apr_int16_t rtnev;
apr_status_t rv;
int i;
apr_status_t status;
int snprintf_res = 0;
#ifdef NOT_ASCII
apr_size_t inbytes_left, outbytes_left;
#endif
if (isproxy) {
connecthost = apr_pstrdup(cntxt, proxyhost);
connectport = proxyport;
}
else {
connecthost = apr_pstrdup(cntxt, hostname);
connectport = port;
}
if (!use_html) {
printf("Benchmarking %s ", hostname);
if (isproxy)
printf("[through %s:%d] ", proxyhost, proxyport);
printf("(be patient)%s",
(heartbeatres ? "\n" : "..."));
#ifdef _WAF_BENCH_ // add "\n" even if heartbeat is 0
if (!heartbeatres) printf("\n");
#endif // _WAF_BENCH_ // add "\n" even if heartbeat is 0
fflush(stdout);
}
con = xcalloc(concurrency, sizeof(struct connection));
/*
* XXX: a way to calculate the stats without requiring O(requests) memory
* XXX: would be nice.
*/
#ifdef _WAF_BENCH_ // fixed stats window, <= g_stats_window
stats = xcalloc(ap_min(requests, g_stats_window), sizeof(struct data));
#else // orginal code goes here
stats = xcalloc(requests, sizeof(struct data));
#endif // _WAF_BENCH_ , fixed stats window, <= g_stats_window
if ((status = apr_pollset_create(&readbits, concurrency, cntxt,
APR_POLLSET_NOCOPY)) != APR_SUCCESS) {
apr_err("apr_pollset_create failed", status);
}
/* add default headers if necessary */
if (!opt_host) {
/* Host: header not overridden, add default value to hdrs */
#ifdef _WAF_BENCH_ // Host:localhost option, "-1"
// if no HOST specified in arguments and g_add_localhost is not disabled (-1)
// use "localhost" instead of host_field which comes from URL
if (g_add_localhost) {
host_field = "Localhost";
colonhost = "";
}
#endif //_WAF_BENCH_ , Host:localhost option, "-1"
hdrs = apr_pstrcat(cntxt, hdrs, "Host: ", host_field, colonhost, "\r\n", NULL);
}
else {
/* Header overridden, no need to add, as it is already in hdrs */
}
#ifdef HAVE_TLSEXT
if (is_ssl && tls_use_sni) {
apr_ipsubnet_t *ip;
if (((tls_sni = opt_host) || (tls_sni = hostname)) &&
(!*tls_sni || apr_ipsubnet_create(&ip, tls_sni, NULL,
cntxt) == APR_SUCCESS)) {
/* IP not allowed in TLS SNI extension */
tls_sni = NULL;
}
}
#endif
#ifdef _WAF_BENCH_ // connection:close option, "-2"
// if no Connection specified in arguments and g_add_connection_close is not disabled (-2)
// Add "Connection:Close" in header
if (g_add_connection_close && !opt_connection) {
/* User-Agent: header not overridden, add default value to hdrs */
hdrs = apr_pstrcat(cntxt, hdrs, "Connection: ", "Close", "\r\n", NULL);
}
#endif // _WAF_BENCH_ , connection:close option, "-2"
if (!opt_useragent) {
/* User-Agent: header not overridden, add default value to hdrs */
hdrs = apr_pstrcat(cntxt, hdrs, "User-Agent: ApacheBench/", AP_AB_BASEREVISION, "\r\n", NULL);
}
else {
/* Header overridden, no need to add, as it is already in hdrs */
}
if (!opt_accept) {
/* Accept: header not overridden, add default value to hdrs */
hdrs = apr_pstrcat(cntxt, hdrs, "Accept: */*\r\n", NULL);
}
else {
/* Header overridden, no need to add, as it is already in hdrs */
}
/* setup request */
if (!send_body) {
snprintf_res = apr_snprintf(request, sizeof(_request),
"%s %s HTTP/1.0\r\n"
"%s" "%s" "%s"
"%s" "\r\n",
method_str[method],
(isproxy) ? fullurl : path,
keepalive ? "Connection: Keep-Alive\r\n" : "",
cookie, auth, hdrs);
}
else {
snprintf_res = apr_snprintf(request, sizeof(_request),
"%s %s HTTP/1.0\r\n"
"%s" "%s" "%s"
"Content-length: %" APR_SIZE_T_FMT "\r\n"
"Content-type: %s\r\n"
"%s"
"\r\n",
method_str[method],
(isproxy) ? fullurl : path,
keepalive ? "Connection: Keep-Alive\r\n" : "",
cookie, auth,
postlen,
(content_type != NULL) ? content_type : "text/plain", hdrs);
}
if (snprintf_res >= sizeof(_request)) {
err("Request too long\n");
}
if (verbosity >= 2)
printf("INFO: %s header == \n---\n%s\n---\n",
method_str[method], request);
reqlen = strlen(request);
/*
* Combine headers and (optional) post file into one continuous buffer
*/
#ifdef _WAF_BENCH_
if (g_pkt_length > 0)
fprintf(stderr, "\n read %zu packets from file with total length(%zu).\n",
g_MAX_PKT_COUNT, g_pkt_length);
#endif // _WAF_BENCH_
if (send_body) {
char *buff = xmalloc(postlen + reqlen + 1);
strcpy(buff, request);
memcpy(buff + reqlen, postdata, postlen);
request = buff;
}
#ifdef NOT_ASCII
inbytes_left = outbytes_left = reqlen;
status = apr_xlate_conv_buffer(to_ascii, request, &inbytes_left,
request, &outbytes_left);
if (status || inbytes_left || outbytes_left) {
fprintf(stderr, "only simple translation is supported (%d/%"
APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT ")\n",
status, inbytes_left, outbytes_left);
exit(1);
}
#endif /* NOT_ASCII */
if (myhost) {
/* This only needs to be done once */
if ((rv = apr_sockaddr_info_get(&mysa, myhost, APR_UNSPEC, 0, 0, cntxt)) != APR_SUCCESS) {
char buf[120];
apr_snprintf(buf, sizeof(buf),
"apr_sockaddr_info_get() for %s", myhost);
apr_err(buf, rv);
}
}
/* This too */
if ((rv = apr_sockaddr_info_get(&destsa, connecthost,
myhost ? mysa->family : APR_UNSPEC,
connectport, 0, cntxt))
!= APR_SUCCESS) {
char buf[120];
apr_snprintf(buf, sizeof(buf),
"apr_sockaddr_info_get() for %s", connecthost);
apr_err(buf, rv);
}
/* ok - lets start */
start = lasttime = apr_time_now();
stoptime = tlimit ? (start + apr_time_from_sec(tlimit)) : AB_MAX;
#ifdef SIGINT
/* Output the results if the user terminates the run early. */
apr_signal(SIGINT, output_results);
#endif
/* initialise first connection to determine destination socket address
* which should be used for next connections. */
con[0].socknum = 0;
start_connect(&con[0]);
do {
apr_int32_t n;
const apr_pollfd_t *pollresults, *pollfd;
n = concurrency;
do {
status = apr_pollset_poll(readbits, aprtimeout, &n, &pollresults);
#ifdef _WAF_BENCH_ // print out the progress
print_progress(0);
#endif // _WAF_BENCH_, // print out the progress
} while (APR_STATUS_IS_EINTR(status));
#ifdef _WAF_BENCH_ // wb will not quit when there's a timeout
if (status == APR_TIMEUP) {
struct connection *c = &con[0];
if (c->state != STATE_READ && c->state != STATE_CONNECTING) {
apr_err("Timeout_in_non_STATE_READ", status);
} else {
err_recv++;
bad ++;
if (recverrok) {
if (verbosity > 1)
fprintf(stderr, "WARNING: READ TIMEOUT!\n");
save_logfile("TIMEOUT: READ ERROR\n",0);
close_connection(c);
continue;
} else {
apr_err("Read_Timeout", status);
}
}
} else
#endif // _WAF_BENCH_, // wb will not quit when there's a timeout
if (status != APR_SUCCESS)
apr_err("apr_pollset_poll", status);
for (i = 0, pollfd = pollresults; i < n; i++, pollfd++) {
struct connection *c;
c = pollfd->client_data;
/*
* If the connection isn't connected how can we check it?
*/
if (c->state == STATE_UNCONNECTED)
continue;
rtnev = pollfd->rtnevents;
#ifdef USE_SSL
if (c->state == STATE_CONNECTED && c->ssl && SSL_in_init(c->ssl)) {
ssl_proceed_handshake(c);
continue;
}
#endif
/*
* Notes: APR_POLLHUP is set after FIN is received on some
* systems, so treat that like APR_POLLIN so that we try to read
* again.
*
* Some systems return APR_POLLERR with APR_POLLHUP. We need to
* call read_connection() for APR_POLLHUP, so check for
* APR_POLLHUP first so that a closed connection isn't treated
* like an I/O error. If it is, we never figure out that the
* connection is done and we loop here endlessly calling
* apr_poll().
*/
if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP))
read_connection(c);
if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) {
if (destsa->next && c->state == STATE_CONNECTING && good == 0) {
destsa = destsa->next;
start_connect(c);
}
else {
bad++;
err_except++;
/* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
if (c->state == STATE_CONNECTING) {
read_connection(c);
}
else {
start_connect(c);
}
}
continue;
}
if (rtnev & APR_POLLOUT) {
if (c->state == STATE_CONNECTING) {
/* call connect() again to detect errors */
rv = apr_socket_connect(c->aprsock, destsa);
if (rv != APR_SUCCESS) {
set_conn_state(c, STATE_UNCONNECTED);
apr_socket_close(c->aprsock);
err_conn++;
if (bad++ > 10) {
fprintf(stderr,
"\nTest aborted after 10 failures\n\n");
apr_err("apr_socket_connect()", rv);
}
start_connect(c);
continue;
}
else {
set_conn_state(c, STATE_CONNECTED);
#ifdef USE_SSL
if (c->ssl)
ssl_proceed_handshake(c);
else
#endif
write_request(c);
}
}
else {
/* POLLOUT is one shot */
set_polled_events(c, APR_POLLIN);
if (c->state == STATE_READ) {
read_connection(c);
}
else {
write_request(c);
}
}
}
}
} while (lasttime < stoptime && done < requests);
#ifdef _WAF_BENCH_ // print out the last progress
if (g_interval_print) {
print_progress(1); // forced print out
fprintf(stderr, "Finished %d requests", done);
} else
#endif // _WAF_BENCH_, // print out the last progress
if (heartbeatres)
fprintf(stderr, "Finished %d requests\n", done);
else
printf("..done\n");
if (use_html)
output_html_results();
else
output_results(0);
}