httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@locus.apache.org
Subject cvs commit: apache-2.0/src/main http_protocol.c
Date Sat, 14 Oct 2000 04:37:23 GMT
rbb         00/10/13 21:37:23

  Modified:    src/include httpd.h
               src/main http_protocol.c
  Log:
  Get non-chunked input body filtering working with an EOS bucket.  The
  basic design has ap_setup_client_block setting a field in the conn_rec
  which tells http_filter how much data is in the body (with chunking this
  will represent how much data is in the chunk).  The ap_get_client_block
  then calls down the stack with the maximum amount of data that it can
  receive back.  When http_filter reads all of the data, it adds an eos
  bucket to the end of the brigade.  ap_get_client_block continues to read
  data until it gets the eos bucket.  This allows filters to increase the
  size of the body data.
  
  Revision  Changes    Path
  1.102     +3 -0      apache-2.0/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/httpd.h,v
  retrieving revision 1.101
  retrieving revision 1.102
  diff -u -r1.101 -r1.102
  --- httpd.h	2000/10/13 18:39:16	1.101
  +++ httpd.h	2000/10/14 04:37:22	1.102
  @@ -906,6 +906,9 @@
       /** A list of output filters to be used for this connection
        *  @defvar ap_filter_t *filters */
       struct ap_filter_t *output_filters;
  +    /** The length of the current request body
  +     *  @defvar long remain */
  +    long remain;
   };
   
   /* Per-vhost config... */
  
  
  
  1.170     +59 -22    apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.169
  retrieving revision 1.170
  diff -u -r1.169 -r1.170
  --- http_protocol.c	2000/10/13 18:39:18	1.169
  +++ http_protocol.c	2000/10/14 04:37:22	1.170
  @@ -889,26 +889,35 @@
           }
       }
   
  -    if (length > 0) {
  -        int remain = length;
  -        const char *ignore;
  -
  +    if (f->c->remain) {
  +        int total = 0;
           e = AP_BRIGADE_FIRST(b);
  +        len = length;
           while (e != AP_BRIGADE_SENTINEL(b)) {
  +            const char *ignore;
               ap_bucket_read(e, &ignore, &len, 0);
  -            if (remain <= len) {
  +            if (total + len >= length) {
  +                len = length - total;
  +                total += len;
                   break;
               }
  -            remain -= len;
  +            total += len;
  +            len = length - total;
               e = AP_BUCKET_NEXT(e);
           }
           if (e != AP_BRIGADE_SENTINEL(b)) {
  -            if (remain <= len) {
  -                ap_bucket_split(e, remain);
  -                remain = 0;
  +            ap_bucket *eos_bucket;
  +            if (total >= length) {
  +                ap_bucket_split(e, len);
  +                total = length;
               }
               bb = ap_brigade_split(b, AP_BUCKET_NEXT(e));
               ctx->b = bb;
  +            if (f->c->remain == 0) { 
  +                eos_bucket = ap_bucket_create_eos();
  +                AP_BUCKET_INSERT_AFTER(e, eos_bucket);
  +            }
  +            f->c->remain -= total;
               return APR_SUCCESS;
           }
           else {
  @@ -2289,7 +2298,7 @@
               return HTTP_BAD_REQUEST;
           }
   
  -        r->remaining = atol(lenp);
  +        r->connection->remain = r->remaining = atol(lenp);
       }
   
       if ((r->read_body == REQUEST_NO_BODY) &&
  @@ -2403,24 +2412,27 @@
   
           len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
   
  -        if (len_to_read == 0) {
  -            return 0;
  -        }
           bb = ap_brigade_create(r->pool);
  +
           do {
               if (AP_BRIGADE_EMPTY(bb)) {
  -                apr_getsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
&timeout);
  -                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
0);
  -                if (ap_get_brigade(r->input_filters, bb, len_to_read) != APR_SUCCESS)
{
  +                apr_getsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,

  +                                 &timeout);
  +                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
  +                                 0);
  +                if (ap_get_brigade(r->input_filters, bb, 
  +                                   len_to_read) != APR_SUCCESS) {
                       /* if we actually fail here, we want to just return and
                        * stop trying to read data from the client.
                        */
  -                    apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
timeout);
  +                    apr_setsocketopt(r->connection->client->bsock, 
  +                                     APR_SO_TIMEOUT, timeout);
                       r->connection->keepalive = -1;
                       ap_brigade_destroy(bb);
                       return -1;
                   }
  -                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
timeout);
  +                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
  +                                 timeout);
               }
               b = AP_BRIGADE_FIRST(bb);
               
  @@ -2434,20 +2446,45 @@
   
           total = 0;
           do {
  +            if (AP_BRIGADE_EMPTY(bb)) {
  +                apr_getsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
  +                                 &timeout);
  +                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
  +                                 0);
  +                if (ap_get_brigade(r->input_filters, bb, 
  +                                   len_to_read) != APR_SUCCESS) {
  +                    /* if we actually fail here, we want to just return and
  +                     * stop trying to read data from the client.
  +                     */
  +                    apr_setsocketopt(r->connection->client->bsock, 
  +                                     APR_SO_TIMEOUT, timeout);
  +                    r->connection->keepalive = -1;
  +                    return -1;
  +                }
  +                apr_setsocketopt(r->connection->client->bsock, APR_SO_TIMEOUT,
  +                                 timeout);
  +            }
  +            b = AP_BRIGADE_FIRST(bb);
  +            if (b->type == ap_eos_type()) {
  +                r->connection->remain = 0;
  +                break;
  +            }
               rv = ap_bucket_read(b, &tempbuf, &len_read, 0);
  -            ap_debug_assert(total + len_read <= bufsiz); /* because we told the filter

  -                                                          * below us not to give us too
much */
  +
  +            /* because we told the filter below us not to give us too much */
  +            ap_debug_assert(total + len_read <= bufsiz);
               ap_debug_assert(r->remaining >= len_read);
               memcpy(buffer, tempbuf, len_read);
               buffer += len_read;
               r->read_length += len_read;
               total += len_read;
  +
               r->remaining -= len_read;
  +
               old = b;
  -            b = AP_BUCKET_NEXT(b);
               AP_BUCKET_REMOVE(old);
               ap_bucket_destroy(old);
  -        } while (b != AP_BRIGADE_SENTINEL(bb));
  +        } while (!AP_BRIGADE_EMPTY(bb));
           ap_brigade_destroy(bb);
           return total;
       }
  
  
  

Mime
View raw message