apr_status_t generic_recv_resp()

in flood_socket_generic.c [100:167]


apr_status_t generic_recv_resp(response_t **resp, socket_t *sock, apr_pool_t *pool)
{
    char b[MAX_DOC_LENGTH];
    apr_size_t i;
    response_t *new_resp;
    apr_status_t status;

    generic_socket_t *gsock = (generic_socket_t *)sock;

    new_resp = apr_pcalloc(pool, sizeof(response_t));
    new_resp->rbuftype = POOL;

    if (gsock->wantresponse)
    {
        /* Ugh, we want everything. */
        apr_size_t currentalloc;
        char *cp, *op;

        new_resp->rbufsize = 0;
        currentalloc = MAX_DOC_LENGTH;
        new_resp->rbuf = apr_palloc(pool, currentalloc);
        cp = new_resp->rbuf;
        do
        {
            i = MAX_DOC_LENGTH - 1;
            status = gsock->ssl ? ssl_read_socket(gsock->s, b, &i)
                                : read_socket(gsock->s, b, &i);
            if (new_resp->rbufsize + i > currentalloc)
            {
                /* You can think why this always work. */
                currentalloc *= 2;
                op = new_resp->rbuf;
                new_resp->rbuf = apr_palloc(pool, currentalloc);
                memcpy(new_resp->rbuf, op, cp - op);
                cp = new_resp->rbuf + (cp - op);
            }
            
            memcpy(cp, b, i);
            new_resp->rbufsize += i;
            cp += i;
        }
        while (status != APR_EOF && status != APR_TIMEUP);
    }
    else
    {
        /* We just want to store the first chunk read. */
        new_resp->rbufsize = MAX_DOC_LENGTH - 1;
        new_resp->rbuf = apr_palloc(pool, new_resp->rbufsize);
        status = gsock->ssl ? ssl_read_socket(gsock->s, new_resp->rbuf, 
                                              &new_resp->rbufsize) :
                              read_socket(gsock->s, new_resp->rbuf, 
                                          &new_resp->rbufsize);

        while (status != APR_EOF && status != APR_TIMEUP) {
            i = MAX_DOC_LENGTH - 1;
            status = gsock->ssl ? ssl_read_socket(gsock->s, b, &i) :
                                  read_socket(gsock->s, b, &i);
        }
        if (status != APR_SUCCESS && status != APR_EOF) {
            return status;
        }

    }

    *resp = new_resp;

    return APR_SUCCESS;
}