httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@locus.apache.org
Subject cvs commit: apache-2.0/src/main http_core.c
Date Mon, 28 Aug 2000 20:36:51 GMT
trawick     00/08/28 13:36:46

  Modified:    src/main http_core.c
  Log:
  Update chunk_filter to handle buckets with unknown length (e.g., pipes).
  As soon as we hit such a bucket, we'll read from it then pass everything
  we have so far on to the next filter.  At that point we'll start over.
  
  Also, increase the size of the chunk header buffer to handle larger
  lengths.
  
  Note: There is still an extra final chunk header (0) when mod_cgi is used
  because EOS is coming down twice.
  
  This is likely to have some bugs here and there.  Even worse, it is butt
  ugly and in need of simplification.
  
  Revision  Changes    Path
  1.107     +64 -29    apache-2.0/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
  retrieving revision 1.106
  retrieving revision 1.107
  diff -u -r1.106 -r1.107
  --- http_core.c	2000/08/23 00:01:52	1.106
  +++ http_core.c	2000/08/28 20:36:42	1.107
  @@ -2921,49 +2921,84 @@
    */
   static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
   {
  -    ap_bucket *dptr = b->head;
  -    int len = 0;
  -    char lenstr[6];
  +    ap_bucket *dptr = b->head, *lb, *next, *tail;
  +    int len = 0, cur_len;
  +    char lenstr[strlen("ffffffff\r\n") + 1];
  +    const char *cur_str;
       int hit_eos = 0;
  +    apr_status_t rv = 0; /* currently bytes written, will be APR_* */
   
       while (dptr) {
           if (dptr->type == AP_BUCKET_EOS) {
               hit_eos = 1;
  +            break;
           } 
  +        else if (dptr->length == -1) { /* indeterminate (e.g., a pipe) */
  +            dptr->read(dptr, &cur_str, &cur_len, 0);
  +            if (cur_len) {
  +                len += cur_len;
  +                /* write out what we have so far */
  +                apr_snprintf(lenstr, sizeof(lenstr), "%x\r\n", len);
  +                lb = ap_bucket_create_transient(lenstr, strlen(lenstr));
  +                lb->next = b->head;
  +                lb->next->prev = lb;
  +                b->head = lb;
  +                next = dptr->next;
  +                tail = b->tail;
  +                b->tail = ap_bucket_create_transient("\r\n", 2);
  +                dptr->next = b->tail;
  +                b->tail->prev = dptr;
  +                rv += ap_pass_brigade(f->next, b);
  +                /* start a new brigade */
  +                len = 0;
  +                b = ap_brigade_create(f->r->pool);
  +                dptr = next;
  +                b->head = dptr;
  +                b->tail = tail;
  +            }
  +            else {
  +                dptr = dptr->next;
  +            }
  +        }
           else {
               len += dptr->length;
  +            dptr = dptr->next;
           }
  -        dptr = dptr->next;
  -    }
  -
  -    apr_snprintf(lenstr, 6, "%x\r\n", len);
  -    dptr = ap_bucket_create_transient(lenstr, strlen(lenstr));
  -    b->head->prev = dptr;
  -    dptr->next = b->head;
  -    b->head = dptr;
  -    dptr = ap_bucket_create_transient("\r\n", 2);
  -    if (hit_eos) {
  -        b->tail->prev->next = dptr;
  -        dptr->prev = b->tail->prev;
  -        b->tail->prev = dptr;
  -        dptr->next = b->tail;
       }
  -    else {
  -        ap_brigade_append_buckets(b, dptr);
  +    if (len) {
  +        apr_snprintf(lenstr, sizeof(lenstr), "%x\r\n", len);
  +        lb = ap_bucket_create_transient(lenstr, strlen(lenstr));
  +        lb->next = b->head;
  +        lb->next->prev = lb;
  +        b->head = lb;
  +        lb = ap_bucket_create_transient("\r\n", 2);
  +        if (hit_eos) {
  +            b->tail->prev->next = lb;
  +            lb->prev = b->tail->prev;
  +            b->tail->prev = lb;
  +            lb->next = b->tail;
  +        }
  +        else {
  +            ap_brigade_append_buckets(b, lb);
  +        }
       }
  -
  -    if (hit_eos && len != 0) {
  -        dptr = ap_bucket_create_transient("0\r\n\r\n", 5);
  -        b->tail->prev->next = dptr;
  -        dptr->prev = b->tail->prev;
  -        b->tail->prev = dptr;
  -        dptr->next = b->tail;
  +    if (hit_eos) {
  +        lb = ap_bucket_create_transient("0\r\n\r\n", 5);
  +        if (b->tail->prev) {
  +            b->tail->prev->next = lb;
  +        }
  +        lb->prev = b->tail->prev;
  +        b->tail->prev = lb;
  +        lb->next = b->tail;
  +        if (b->head == b->tail) {
  +            b->head = lb;
  +        }
       }
  -
  -    return ap_pass_brigade(f->next, b);
  +    rv += ap_pass_brigade(f->next, b);
  +    return rv;
   }
   
  -/* Default filter.  This filter should almost always be used.  It's only job
  +/* Default filter.  This filter should almost always be used.  Its only job
    * is to send the headers if they haven't already been sent, and then send
    * the actual data.  To send the data, we create an iovec out of the bucket
    * brigade and then call the sendv function.  On platforms that don't
  
  
  

Mime
View raw message