static void test()

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);
}