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 http_protocol.c
Date Tue, 31 Oct 2000 12:30:22 GMT
trawick     00/10/31 04:30:22

  Modified:    src      CHANGES
               src/include http_protocol.h
               src/main http_core.c http_protocol.c
  Log:
  Compute the content length (and add appropriate header field) for
  the response when no content length is available and we can't use
  chunked encoding.
  
  This is going to be painful when the response body is huge, so I
  suspect we'll have additional criteria in the future.
  
  Revision  Changes    Path
  1.301     +4 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.300
  retrieving revision 1.301
  diff -u -r1.300 -r1.301
  --- CHANGES	2000/10/28 15:17:41	1.300
  +++ CHANGES	2000/10/31 12:30:20	1.301
  @@ -1,4 +1,8 @@
   Changes with Apache 2.0a8
  +  *) Compute the content length (and add appropriate header field) for
  +     the response when no content length is available and we can't use 
  +     chunked encoding.  [Jeff Trawick]
  +
     *) Add mod_ext_filter as an experimental module.  This module allows
        the administrator to use external programs as filters.  Currently,
        only filtering of output is supported.  [Jeff Trawick]
  
  
  
  1.36      +3 -0      apache-2.0/src/include/http_protocol.h
  
  Index: http_protocol.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/http_protocol.h,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- http_protocol.h	2000/10/22 13:09:23	1.35
  +++ http_protocol.h	2000/10/31 12:30:21	1.36
  @@ -113,6 +113,8 @@
   AP_DECLARE(void) ap_send_http_header(request_rec *l);
   
   AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, ap_bucket_brigade
*b);
  +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *, 
  +                                                              ap_bucket_brigade *);
   
   /* Send the response to special method requests */
   
  @@ -533,6 +535,7 @@
   
   apr_status_t ap_http_filter(ap_filter_t *f, ap_bucket_brigade *b, ap_input_mode_t mode);
   apr_status_t ap_dechunk_filter(ap_filter_t *f, ap_bucket_brigade *b, ap_input_mode_t mode);
  +
   
     /* Hooks */
     /*
  
  
  
  1.191     +2 -0      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.190
  retrieving revision 1.191
  diff -u -r1.190 -r1.191
  --- http_core.c	2000/10/26 12:03:07	1.190
  +++ http_core.c	2000/10/31 12:30:21	1.191
  @@ -3578,6 +3578,8 @@
       ap_register_input_filter("DECHUNK", ap_dechunk_filter, AP_FTYPE_TRANSCODE);
       ap_register_input_filter("CORE_IN", core_input_filter, AP_FTYPE_NETWORK);
       ap_register_output_filter("HTTP_HEADER", ap_http_header_filter, AP_FTYPE_HTTP_HEADER);
  +    ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter, 
  +                              AP_FTYPE_HTTP_HEADER);
       ap_register_output_filter("CORE", core_output_filter, AP_FTYPE_NETWORK);
       ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter, 
                                 AP_FTYPE_CONTENT);
  
  
  
  1.210     +79 -0     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.209
  retrieving revision 1.210
  diff -u -r1.209 -r1.210
  --- http_protocol.c	2000/10/26 11:05:07	1.209
  +++ http_protocol.c	2000/10/31 12:30:22	1.210
  @@ -1417,6 +1417,7 @@
                  ? &r->server->keep_alive_timeout
                  : &r->server->timeout);
   
  +    ap_add_output_filter("CONTENT_LENGTH", NULL, r, r->connection);
       ap_add_output_filter("HTTP_HEADER", NULL, r, r->connection);
   
       /* Get the request... */
  @@ -2227,6 +2228,84 @@
   
   AP_DECLARE(void) ap_send_http_header(request_rec *r)
   {
  +}
  +
  +struct content_length_ctx {
  +    ap_bucket_brigade *saved;
  +};
  +
  +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *f,
  +                                                              ap_bucket_brigade *b)
  +{
  +    request_rec *r = f->r;
  +    struct content_length_ctx *ctx;
  +    apr_status_t rv;
  +    ap_bucket *e;
  +
  +    ctx = f->ctx;
  +    if (!ctx) { /* first time through */
  +        /* We won't compute a content length if one of the following is true:
  +         * . subrequest
  +         * . HTTP/0.9
  +         * . status HTTP_NOT_MODIFIED or HTTP_NO_CONTENT
  +         * . HEAD
  +         * . content length already computed
  +         * . can be chunked
  +         * . body already chunked
  +         * Much of this should correspond to checks in ap_set_keepalive().
  +         */
  +        if (r->assbackwards 
  +            || r->status == HTTP_NOT_MODIFIED 
  +            || r->status == HTTP_NO_CONTENT
  +            || r->header_only
  +            || apr_table_get(r->headers_out, "Content-Length")
  +            || r->proto_num == HTTP_VERSION(1,1)
  +            || ap_find_last_token(f->r->pool,
  +                                  apr_table_get(r->headers_out,
  +                                                "Transfer-Encoding"),
  +                                  "chunked")) {
  +            ap_remove_output_filter(f);
  +            return ap_pass_brigade(f->next, b);
  +        }
  +
  +        f->ctx = ctx = apr_pcalloc(r->pool, sizeof(struct content_length_ctx));
  +    }
  +
  +    if (AP_BUCKET_IS_EOS(AP_BRIGADE_LAST(b))) {
  +        apr_ssize_t content_length = 0;
  +
  +        if (ctx->saved) {
  +            AP_BRIGADE_CONCAT(ctx->saved, b);
  +            b = ctx->saved;
  +        }
  +
  +        AP_BRIGADE_FOREACH(e, b) {
  +            if (!AP_BUCKET_IS_EOS(e)) {
  +                if (e->length >= 0) {
  +                    content_length += e->length;
  +                }
  +                else {
  +                    const char *ignored;
  +                    apr_ssize_t length;
  +                    
  +                    rv = ap_bucket_read(e, &ignored, &length, 1);
  +                    if (rv != APR_SUCCESS) {
  +                        return rv;
  +                    }
  +                    content_length += e->length;
  +                }
  +            }
  +        }
  +
  +        ap_set_content_length(r, content_length);
  +        return ap_pass_brigade(f->next, b);
  +    }
  +
  +    /* save the brigade; we can't pass any data to the next
  +     * filter until we have the entire content length
  +     */
  +    ap_save_brigade(f, &ctx->saved, &b);
  +    return APR_SUCCESS;
   }
   
   AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, ap_bucket_brigade
*b)
  
  
  

Mime
View raw message