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 buff.c http_core.c http_protocol.c
Date Thu, 17 Aug 2000 00:54:04 GMT
rbb         00/08/16 17:54:04

  Modified:    src      CHANGES
               src/main buff.c http_core.c http_protocol.c
  Log:
  A first pass at the chunking filter.  This is incredibly simple.  As
  bucket brigades are sent to this filter, it inserts the chunking header
  at the front of the brigade.  When the filter sees an EOS bucket, it
  adds the 0 chunking trailer.
  
  Revision  Changes    Path
  1.202     +6 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.201
  retrieving revision 1.202
  diff -u -r1.201 -r1.202
  --- CHANGES	2000/08/14 02:54:41	1.201
  +++ CHANGES	2000/08/17 00:54:03	1.202
  @@ -1,4 +1,10 @@
   Changes with Apache 2.0a6
  +  *) Add a chunking filter to Apache.  This brings us one step closer
  +     to removing BUFF. [Ryan Bloom]
  +
  +  *) ap_add_filter now adds filters in a LIFO fashion.  The first filter
  +     added to the stack is the last filter to be called.  [Ryan Bloom]
  +
     *) Apache 2.0 has been completely documented using Scandoc.  The
        docs can be generated by running 'make docs'.  [Ryan Bloom]
   
  
  
  
  1.58      +1 -112    apache-2.0/src/main/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/buff.c,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- buff.c	2000/08/07 19:26:00	1.57
  +++ buff.c	2000/08/17 00:54:03	1.58
  @@ -309,8 +309,6 @@
    */
   static void start_chunk(BUFF *fb)
   {
  -    fb->outchunk = fb->outcnt;
  -    fb->outcnt += CHUNK_HEADER_SIZE;
   }
   
   /*
  @@ -322,67 +320,9 @@
   */
   static int end_chunk(BUFF *fb, int extra)
   {
  -    int i;
  -    unsigned char *strp;
  -    int chunk_size;
  -#ifdef CHARSET_EBCDIC
  -    apr_size_t inbytes_left, outbytes_left;
  -#endif
  -
  -    chunk_size = fb->outcnt - fb->outchunk - CHUNK_HEADER_SIZE + extra;
  -    if (chunk_size == 0) {
  -        /* nothing was written into this chunk, and we can't write a 0 size
  -         * chunk because that signifies EOF, so just erase it
  -         */
  -        fb->outcnt = fb->outchunk;
  -        fb->outchunk = -1;
           return 0;
       }
   
  -    if (chunk_size > MAX_CHUNK_SIZE) {
  -	extra -= chunk_size - MAX_CHUNK_SIZE;
  -	chunk_size = MAX_CHUNK_SIZE;
  -    }
  -
  -    /* we know this will fit because of space we saved in start_chunk() */
  -    i = apr_snprintf((char *) &fb->outbase[fb->outchunk], CHUNK_HEADER_SIZE,
  -                "%x", chunk_size);
  -
  -    /* we may have to tack some trailing spaces onto the number we just wrote
  -     * in case it was smaller than our estimated size.  We've also written
  -     * a \0 into the buffer with apr_snprintf so we might have to put a
  -     * \r back in.
  -     */
  -    strp = &fb->outbase[fb->outchunk + i];
  -    while (i < CHUNK_HEADER_SIZE - 2) {
  -        *strp++ = ' ';
  -        ++i;
  -    }
  -    /* CRLF intentionally left hardcoded in ascii on ebcdic boxes */
  -    *strp++ = '\015';
  -    *strp = '\012';
  -
  -#ifdef CHARSET_EBCDIC
  -    /* Convert printable hex chunk size and padding from ebcdic->ascii,
  -     * but leave CRLF in ascii
  -     */
  -    inbytes_left = outbytes_left = CHUNK_HEADER_SIZE - 2;
  -    apr_xlate_conv_buffer(ap_hdrs_to_ascii,
  -                          &fb->outbase[fb->outchunk], &inbytes_left,
  -                          &fb->outbase[fb->outchunk], &outbytes_left);
  -#endif /*CHARSET_EBCDIC*/
  -
  -    if (extra == 0) {
  -	/* tack on the trailing CRLF, we've reserved room for this */
  -	fb->outbase[fb->outcnt++] = '\015';
  -	fb->outbase[fb->outcnt++] = '\012';
  -    }
  -
  -    fb->outchunk = -1;
  -    
  -    return extra;
  -}
  -
   
   
   /*
  @@ -868,58 +808,7 @@
   static apr_status_t large_write_chunk(BUFF *fb, const char *buf, apr_size_t nbyte,
                                        apr_ssize_t *bytes_written)
   {
  -    apr_status_t rv;
  -    apr_ssize_t total, n, amt;
  -
  -    ap_assert(nbyte > 0);
  -    total = 0;
  -    if (fb->chunk_overcommit) {
  -	amt = nbyte > fb->chunk_overcommit ? fb->chunk_overcommit : nbyte;
  -	rv = large_write(fb, buf, amt, &total);
  -	fb->chunk_overcommit -= total;
  -	if (rv != APR_SUCCESS) {
  -	    *bytes_written = total;
  -            return rv;
  -	}
  -	if (fb->chunk_overcommit) {
  -	    /* above we ensured that we'd write at most the overcommit
  -	       bytes -- so either we had a partial write,
  -	       or we used up all of buf.  either way we're done.  */
  -	    ap_assert(amt < fb->chunk_overcommit || *bytes_written < amt);
  -	    *bytes_written = total;
  -	    return APR_SUCCESS;
  -	}
  -	/* we've finished the overcommit so we end off the previous
  -	   chunk, begin a new one, and shift buf
  -
  -           CRLF is intentionally left hardcoded in ascii on ebcdic boxes */
  -	fb->outbase[0] = '\015';
  -	fb->outbase[1] = '\012';
  -	fb->outcnt = 2;
  -	start_chunk(fb);
  -	nbyte -= total;
  -	buf += total;
  -    }
  -    ap_assert(fb->chunk_overcommit == 0 && fb->outchunk != -1);
  -    while (nbyte) {
  -	amt = end_chunk(fb, nbyte);
  -	rv = large_write(fb, buf, amt, &n);
  -	if (n < amt) {
  -	    /* can only be non-blocking or an error... */
  -	    fb->chunk_overcommit = amt - n;
  -            *bytes_written = total + n;
  -            return rv;
  -	}
  -	fb->outbase[0] = '\015';
  -	fb->outbase[1] = '\012';
  -	fb->outcnt = 2;
  -	start_chunk(fb);
  -	nbyte -= amt;
  -	buf += amt;
  -	total += amt;
  -    }
  -    *bytes_written = total;
  -    return APR_SUCCESS;
  +    return large_write(fb, buf, nbyte, bytes_written);
   }
   
   /* A wrapper for write which deals with error conditions and
  
  
  
  1.102     +50 -2     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.101
  retrieving revision 1.102
  diff -u -r1.101 -r1.102
  --- http_core.c	2000/08/16 19:03:28	1.101
  +++ http_core.c	2000/08/17 00:54:03	1.102
  @@ -2915,6 +2915,54 @@
       return OK;
   }
   
  +/* This is an incredibly stupid chunking filter.  This will need to be somewhat
  + * smart about when it actually sends the data, but this implements some sort
  + * of chunking for right now.
  + */
  +static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
  +{
  +    ap_bucket *dptr = b->head;
  +    int len = 0;
  +    int tempint = 0;
  +    char lenstr[6];
  +    int hit_eos = 0;
  +
  +    while (dptr) {
  +        if (dptr->type == AP_BUCKET_EOS) {
  +            hit_eos = 1;
  +        } 
  +        else {
  +            len += dptr->length;
  +        }
  +        dptr = dptr->next;
  +    }
  +
  +    apr_snprintf(lenstr, 6, "%x\r\n", len);
  +    dptr = ap_bucket_transient_create(lenstr, 4, &tempint);
  +    b->head->prev = dptr;
  +    dptr->next = b->head;
  +    b->head = dptr;
  +    dptr = ap_bucket_heap_create("\r\n", 2, &tempint);
  +    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 (hit_eos && len != 0) {
  +        apr_snprintf(lenstr, 6, "0\r\n\r\n");
  +        dptr = ap_bucket_transient_create(lenstr, 5, &tempint);
  +        ap_brigade_append_buckets(b, dptr);
  +    }
  +        
  +
  +    return ap_pass_brigade(f->next, b);
  +}
  +
   /* Default filter.  This filter should almost always be used.  It's 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
  @@ -3019,9 +3067,9 @@
       /* define the CORE filter, then register a hook to insert it at
        * request-processing time.
        */
  +    ap_hook_insert_filter(core_register_filter, NULL, NULL, AP_HOOK_MIDDLE);
       ap_register_filter("CORE", core_filter, AP_FTYPE_CONNECTION);
  -    ap_hook_insert_filter(core_register_filter, NULL, NULL,
  -                          AP_HOOK_REALLY_LAST);
  +    ap_register_filter("CHUNK", chunk_filter, AP_FTYPE_CONNECTION);
   }
   
   API_VAR_EXPORT module core_module = {
  
  
  
  1.111     +1 -23     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.110
  retrieving revision 1.111
  diff -u -r1.110 -r1.111
  --- http_protocol.c	2000/08/16 21:29:34	1.110
  +++ http_protocol.c	2000/08/17 00:54:03	1.111
  @@ -1863,6 +1863,7 @@
       if (r->chunked) {
           apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
           apr_table_unset(r->headers_out, "Content-Length");
  +        ap_add_filter("CHUNK", NULL, r);
       }
   
       if (r->byterange > 1)
  @@ -1920,30 +1921,7 @@
   {
       /* tell the filter chain there is no more content coming */
       end_output_stream(r);
  -
  -    if (r->chunked && !r->connection->aborted) {
  -#ifdef APACHE_XLATE
  -	AP_PUSH_OUTPUTCONVERSION_STATE(r->connection->client,
  -                                       ap_hdrs_to_ascii);
  -#endif
  -        /*
  -         * Turn off chunked encoding --- we can only do this once.
  -         */
  -        r->chunked = 0;
  -        ap_bsetflag(r->connection->client, B_CHUNK, 0);
  -
  -        (void) checked_bputs("0" CRLF, r);
  -
  -        /* If we had footer "headers", we'd send them now */
  -        /* ### these need to be added to allow message digests */
  -
  -        (void) checked_bputs(CRLF, r);
  -
  -#ifdef APACHE_XLATE
  -	AP_POP_OUTPUTCONVERSION_STATE(r->connection->client);
  -#endif /*APACHE_XLATE*/
       }
  -}
   
   /* Here we deal with getting the request message body from the client.
    * Whether or not the request contains a body is signaled by the presence
  
  
  

Mime
View raw message