Commit 01b885d0 authored by Dirk-Willem van Gulik's avatar Dirk-Willem van Gulik
Browse files

Prevent cobbering of lenght for subsequent sends. Still not quite

right; we ough to call apr_send again if len != requested_len - but
then our timeout could be len * timeout if we happen to only stuff
one byte down the pipe each time.

PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88625 13f79535-47bb-0310-9956-ffa450edef68
parent 83605121
Loading
Loading
Loading
Loading
+590 −572
Original line number Diff line number Diff line
@@ -274,15 +274,22 @@ static void write_request(struct connection *c)
    apr_size_t len = reqlen;
    c->connect = apr_time_now();
    apr_setsocketopt(c->aprsock, APR_SO_TIMEOUT, aprtimeout);
    if (apr_send(c->aprsock, request, &reqlen) != APR_SUCCESS ||
    if (apr_send(c->aprsock, request, &len) != APR_SUCCESS ||
	reqlen != len) {
	printf("Send request failed!\n");
	close_connection(c);
	return;
    }
    if (posting) {
        apr_send(c->aprsock, postdata, &postlen);
        totalposted += (reqlen + postlen);
	len = postlen;
	if (apr_send(c->aprsock, postdata, &len) != APR_SUCCESS ||
	    reqlen != len) {
	    printf("Send post request failed!\n");
	    close_connection(c);
	    return;
	}
	totalposted += postlen + reqlen;
    }

    c->state = STATE_READ;
    apr_poll_socket_add(readbits, c->aprsock, APR_POLLIN);
}
@@ -497,7 +504,8 @@ static void start_connect(struct connection *c)
    apr_status_t rv;
    apr_sockaddr_t *destsa;

    if(!(started < requests)) return;
    if (!(started < requests))
	return;

    c->read = 0;
    c->bread = 0;
@@ -552,7 +560,8 @@ static void close_connection(struct connection *c)
{
    if (c->read == 0 && c->keepalive) {
	/* server has legitimately shut down an idle keep alive request */
        if (good) good--;	/* connection never happened */
	if (good)
	    good--;		/* connection never happened */
    }
    else {
	if (good == 1) {
@@ -612,7 +621,8 @@ static void read_connection(struct connection *c)
    if (!c->gotheader) {
	char *s;
	int l = 4;
        int space = CBUFFSIZE - c->cbx - 1;  /* -1 to allow for 0 terminator */
	int space = CBUFFSIZE - c->cbx - 1;	/* -1 to allow for 0
						 * terminator */
	int tocopy = (space < r) ? space : r;
#ifdef NOT_ASCII
	apr_size_t inbytes_left = space, outbytes_left = space;
@@ -634,7 +644,8 @@ static void read_connection(struct connection *c)
	    printf("LOG: header received:\n%s\n", c->cbuff);
	}
	s = strstr(c->cbuff, "\r\n\r\n");
            /* this next line is so that we talk to NCSA 1.5 which blatantly 
	/*
	 * this next line is so that we talk to NCSA 1.5 which blatantly
	 * breaks the http specifaction
	 */
	if (!s) {
@@ -673,10 +684,12 @@ static void read_connection(struct connection *c)
		*q = 0;
	    }

            /* XXX: this parsing isn't even remotely HTTP compliant...
             * but in the interest of speed it doesn't totally have to be,
             * it just needs to be extended to handle whatever servers
             * folks want to test against. -djg */
	    /*
	     * XXX: this parsing isn't even remotely HTTP compliant... but in
	     * the interest of speed it doesn't totally have to be, it just
	     * needs to be extended to handle whatever servers folks want to
	     * test against. -djg
	     */

	    /* check response code */
	    part = strstr(c->cbuff, "HTTP");	/* really HTTP/1.x_ */
@@ -852,22 +865,24 @@ static void test(void)
	}

	for (i = 0; i < concurrency; i++) {
            /* If the connection isn't connected how can we check it?
	    /*
	     * If the connection isn't connected how can we check it?
	     */
	    if (con[i].state == STATE_UNCONNECTED)
		continue;

	    apr_poll_revents_get(&rv, con[i].aprsock, readbits);
            /* 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.
	    /*
	     * 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().
	     * 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 ((rv & APR_POLLIN) || (rv & APR_POLLPRI) || (rv & APR_POLLHUP))
		read_connection(&con[i]);
@@ -880,11 +895,12 @@ static void test(void)
	    if (rv & APR_POLLOUT)
		write_request(&con[i]);

            /* When using a select based poll every time we check the bits
             * are reset. In 1.3's ab we copied the FD_SET's each time through,
             * but here we're going to check the state and if the connection
             * is in STATE_READ or STATE_CONNECTING we'll add the socket back
             * in as APR_POLLIN.
	    /*
	     * When using a select based poll every time we check the bits
	     * are reset. In 1.3's ab we copied the FD_SET's each time
	     * through, but here we're going to check the state and if the
	     * connection is in STATE_READ or STATE_CONNECTING we'll add the
	     * socket back in as APR_POLLIN.
	     */
	    if (con[i].state == STATE_READ || con[i].state == STATE_CONNECTING)
		apr_poll_socket_add(readbits, con[i].aprsock, APR_POLLIN);
@@ -903,14 +919,14 @@ static void test(void)
static void copyright(void)
{
    if (!use_html) {
        printf("This is ApacheBench, Version %s\n", AB_VERSION " <$Revision: 1.57 $> apache-2.0");
	printf("This is ApacheBench, Version %s\n", AB_VERSION " <$Revision: 1.58 $> apache-2.0");
	printf("Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n");
	printf("Copyright (c) 1998-2001 The Apache Software Foundation, http://www.apache.org/\n");
	printf("\n");
    }
    else {
	printf("<p>\n");
        printf(" This is ApacheBench, Version %s <i>&lt;%s&gt;</i> apache-2.0<br>\n", AB_VERSION, "$Revision: 1.57 $");
	printf(" This is ApacheBench, Version %s <i>&lt;%s&gt;</i> apache-2.0<br>\n", AB_VERSION, "$Revision: 1.58 $");
	printf(" Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/<br>\n");
	printf(" Copyright (c) 1998-2001 The Apache Software Foundation, http://www.apache.org/<br>\n");
	printf("</p>\n<p>\n");
@@ -1109,7 +1125,8 @@ int main(int argc, const char * const argv[])
	    break;
	case 't':
	    tlimit = atoi(optarg);
            requests = MAX_REQUESTS;  /* need to size data array on something */
	    requests = MAX_REQUESTS;	/* need to size data array on
					 * something */
	    break;
	case 'T':
	    strcpy(content_type, optarg);
@@ -1120,7 +1137,8 @@ int main(int argc, const char * const argv[])
	    strncat(cookie, "\r\n", sizeof(cookie));
	    break;
	case 'A':
            /* assume username passwd already to be in colon separated form. 
	    /*
	     * assume username passwd already to be in colon separated form.
	     * Ready to be uu-encoded.
	     */
	    while (apr_isspace(*optarg))