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 Wed, 01 Nov 2000 00:52:07 GMT
rbb         00/10/31 16:52:07

  Modified:    src/include http_protocol.h
               src/main http_protocol.c
  Log:
  Clean up the http filter a lot.  Instead of sending a bucket per header,
  we now create a single bucket that has all of the headers and send that.
  One known issue is that this limits the headers to 8k, but it is a minor
  patch to fix that.
  
  This also stops us from exporting ap_send_header_field.  This function no
  longer makes sense to export.
  
  Revision  Changes    Path
  1.37      +3 -12     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.36
  retrieving revision 1.37
  diff -u -r1.36 -r1.37
  --- http_protocol.h	2000/10/31 12:30:21	1.36
  +++ http_protocol.h	2000/11/01 00:52:03	1.37
  @@ -86,24 +86,15 @@
   request_rec *ap_read_request(conn_rec *c);
   
   /**
  - * Send a single HTTP header field
  - * @param r The current request
  - * @param fieldname The Header field to send
  - * @param fieldval The value of the header
  - * @deffunc int ap_send_header_field(request_rec *r, const char *fieldname, const char
*fieldval)
  - */
  -AP_DECLARE_NONSTD(int) ap_send_header_field(request_rec *r, const char *fieldname,
  -                      const char *fieldval);
  -
  -/**
    * Send the minimal part of an HTTP response header.
    * @param r The current request
  + * @param buf The buffer to add the header to.
    * @warning Modules should be very careful about using this, and should 
    *          prefer ap_send_http_header().  Much of the HTTP/1.1 implementation 
    *          correctness depends on code in ap_send_http_header().
  - * @deffunc void ap_basic_http_header(request_rec *r)
  + * @deffunc void ap_basic_http_header(request_rec *r, char *buf)
    */
  -AP_DECLARE(void) ap_basic_http_header(request_rec *r);
  +AP_DECLARE(void) ap_basic_http_header(request_rec *r, char *buf);
   
   /**
    * Send the Status-Line and header fields for HTTP response
  
  
  
  1.213     +101 -48   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.212
  retrieving revision 1.213
  diff -u -r1.212 -r1.213
  --- http_protocol.c	2000/11/01 00:08:33	1.212
  +++ http_protocol.c	2000/11/01 00:52:06	1.213
  @@ -1751,32 +1751,34 @@
       return status_lines[ap_index_of_response(status)];
   }
   
  +typedef struct header_struct {
  +    request_rec *r;
  +    char *buf;
  +} header_struct;
  +
   /* Send a single HTTP header field to the client.  Note that this function
    * is used in calls to table_do(), so their interfaces are co-dependent.
    * In other words, don't change this one without checking table_do in alloc.c.
    * It returns true unless there was a write error of some kind.
    */
  -AP_DECLARE_NONSTD(int) ap_send_header_field(request_rec *r,
  +static int form_header_field(header_struct *h,
       const char *fieldname, const char *fieldval)
   {
       char *headfield;
  -    ap_bucket *headbuck;
  -    ap_bucket_brigade *bb;
   
  -    headfield = apr_pstrcat(r->pool, fieldname, ": ", fieldval, CRLF, NULL);
  +    headfield = apr_pstrcat(h->r->pool, fieldname, ": ", fieldval, CRLF, NULL);
       ap_xlate_proto_to_ascii(headfield, strlen(headfield));
  -    headbuck = ap_bucket_create_pool(headfield, strlen(headfield), r->pool);
  -    bb = ap_brigade_create(r->pool);
  -    AP_BRIGADE_INSERT_HEAD(bb, headbuck);
  -
  -    ap_pass_brigade(r->connection->output_filters, bb);
  +    apr_cpystrn(h->buf, headfield, strlen(headfield) + 1);
  +    h->buf += strlen(headfield);
       return 1;
   }
   
  -AP_DECLARE(void) ap_basic_http_header(request_rec *r)
  +AP_DECLARE(void) ap_basic_http_header(request_rec *r, char *buf)
   {
       char *protocol;
       char *date = NULL;
  +    char *tmp;
  +    header_struct h;
   
       if (r->assbackwards)
           return;
  @@ -1800,12 +1802,17 @@
   
       /* Output the HTTP/1.x Status-Line and the Date and Server fields */
   
  -    (void) checked_bputstrs(r, protocol, " ", r->status_line, CRLF, NULL);
  +    tmp = apr_pstrcat(r->pool, protocol, " ", r->status_line, CRLF, NULL);
  +    apr_cpystrn(buf, tmp, strlen(tmp) + 1);
  +    buf += strlen(tmp);
   
       date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
       apr_rfc822_date(date, r->request_time);
  -    ap_send_header_field(r, "Date", date);
  -    ap_send_header_field(r, "Server", ap_get_server_version());
  +
  +    h.r = r;
  +    h.buf = buf;
  +    form_header_field(&h, "Date", date);
  +    form_header_field(&h, "Server", ap_get_server_version());
   
       apr_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
       apr_table_unset(r->headers_out, "Server");
  @@ -1828,29 +1835,17 @@
    * It is more expensive to check the User-Agent than it is to just add the
    * bytes, so we haven't used the BrowserMatch feature here.
    */
  -static void terminate_header(request_rec *r)
  +static void terminate_header(char *buf)
   {
  -    char *headfield;
  -    ap_bucket *headbuck;
  -    ap_bucket_brigade *bb;
  -
  -    headfield = apr_palloc(r->pool, 3);
  -    headfield[0] = ASCII_CR;
  -    headfield[1] = ASCII_LF;
  -    headfield[2] = '\0';
  -    headbuck = ap_bucket_create_pool(headfield, strlen(headfield), r->pool);
  -    bb = ap_brigade_create(r->pool);
  -    AP_BRIGADE_INSERT_HEAD(bb, headbuck);
  -
  -    ap_pass_brigade(r->connection->output_filters, bb);
  +    int len = strlen(buf);
  +    char *headfield = buf + len;
  +    char *tmp = "X-Pad: avoid browser bug" CRLF;
   
  -#if 0
  -    ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
  -    if (bs >= 255 && bs <= 257)
  -        (void) checked_bputs("X-Pad: avoid browser bug" CRLF, r);
  -
  -    (void) checked_bputs(CRLF, r);  /* Send the terminating empty line */
  -#endif
  +    if (len >= 255 && len <= 257) {
  +        apr_cpystrn(headfield, tmp, strlen(tmp) + 1);
  +        headfield += strlen(tmp);
  +    }
  +    apr_cpystrn(headfield, CRLF, strlen(CRLF) + 1);
   }
   
   /*
  @@ -2088,7 +2083,7 @@
       ap_rvputs(r, r->the_request, CRLF, NULL);
   
       apr_table_do((int (*) (void *, const char *, const char *))
  -                ap_send_header_field, (void *) r, r->headers_in, NULL);
  +                form_header_field, (void *) r, r->headers_in, NULL);
       ap_rputs(CRLF, r);
   
       return OK;
  @@ -2097,23 +2092,38 @@
   int ap_send_http_options(request_rec *r)
   {
       const long int zero = 0L;
  +    char *buff;
  +    ap_bucket *b;
  +    ap_bucket_brigade *bb;
  +    apr_size_t len;
  +    header_struct h;
   
       if (r->assbackwards)
           return DECLINED;
   
  -    ap_basic_http_header(r);
  +    buff = apr_pcalloc(r->pool, HUGE_STRING_LEN);
  +    len = HUGE_STRING_LEN;
  +    ap_basic_http_header(r, buff);
   
       apr_table_setn(r->headers_out, "Content-Length", "0");
       apr_table_setn(r->headers_out, "Allow", make_allow(r));
       ap_set_keepalive(r);
  +
  +    h.r = r;
  +    h.buf = buff;
   
  -    apr_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
  -             (void *) r, r->headers_out, NULL);
  +    apr_table_do((int (*) (void *, const char *, const char *)) form_header_field,
  +             (void *) &h, r->headers_out, NULL);
   
  -    terminate_header(r);
  +    terminate_header(buff);
   
       ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
   
  +    bb = ap_brigade_create(r->pool);
  +    b = ap_bucket_create_pool(buff, len, r->pool);
  +    AP_BRIGADE_INSERT_TAIL(bb, b);
  +    ap_pass_brigade(r->output_filters, bb);
  +
       return OK;
   }
   
  @@ -2298,6 +2308,11 @@
       const long int zero = 0L;
       char *date = NULL;
       request_rec *r = f->r;
  +    char *buff;
  +    ap_bucket *e;
  +    ap_bucket_brigade *b2;
  +    apr_size_t len;
  +    header_struct h;
   
       if (r->assbackwards) {
           if (!r->main)
  @@ -2330,7 +2345,14 @@
   	fixup_vary(r);
       }
   
  -    ap_basic_http_header(r);
  +    /* XXX Should count the bytes in the headers and allocate just enough
  +     * for the headers we have.
  +     */
  +    buff = apr_pcalloc(r->pool, HUGE_STRING_LEN);
  +    len = HUGE_STRING_LEN;
  +    e = ap_bucket_create_pool(buff, len, r->pool);
  +    ap_basic_http_header(r, buff);
  +    buff += strlen(buff) + 1;
   
       ap_set_keepalive(r);
   
  @@ -2340,7 +2362,6 @@
           /* Disable the buffer filter because it may be masking bugs in the 
            * bucket brigade code  */
   /*      ap_add_output_filter("COALESCE", NULL, r, r->connection); */
  -        ap_add_output_filter("CHUNK", NULL, r, r->connection);
       }
   
       if (r->byterange > 1) {
  @@ -2380,10 +2401,14 @@
           apr_rfc822_date(date, r->request_time);
           apr_table_addn(r->headers_out, "Expires", date);
       }
  -    apr_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
  -		 (void *) r, r->headers_out, NULL);
  +
  +    h.r = r;
  +    h.buf = buff;
  +
  +    apr_table_do((int (*) (void *, const char *, const char *)) form_header_field,
  +		 (void *) &h, r->headers_out, NULL);
   
  -    terminate_header(r);
  +    terminate_header(buff);
   
       ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
       r->sent_bodyct = 1;         /* Whatever follows is real body stuff... */
  @@ -2392,7 +2417,20 @@
       if (r->chunked) {
           ap_bsetflag(r->connection->client, B_CHUNK, 1);
       }
  +    e->length = strlen(buff) + 1;
  +    b2 = ap_brigade_create(r->pool);
  +    AP_BRIGADE_INSERT_HEAD(b2, e);
       ap_remove_output_filter(f);
  +    ap_pass_brigade(f->next, b2);
  +
  +    if (r->chunked) {
  +        /* We can't add this filters until we have already sent the headers.
  +         * If we add it before this point, then the headers will be chunked
  +         * as well, and that is just wrong.
  +         */
  +        ap_add_output_filter("CHUNK", NULL, r, r->connection);
  +    }
  +
       return ap_pass_brigade(f->next, b);
   }
   
  @@ -3194,14 +3232,24 @@
        * message body.  Note that being assbackwards here is not an option.
        */
       if (status == HTTP_NOT_MODIFIED) {
  +        char *buff = apr_pcalloc(r->pool, HUGE_STRING_LEN);
  +        header_struct h;
  +        ap_bucket *e;
  +        ap_bucket_brigade *bb;
  +
           if (!apr_is_empty_table(r->err_headers_out))
               r->headers_out = apr_overlay_tables(r->pool, r->err_headers_out,
   						r->headers_out);
  -        ap_basic_http_header(r);
  +
  +        e = ap_bucket_create_pool(buff, HUGE_STRING_LEN, r->pool);
  +        ap_basic_http_header(r, buff);
           ap_set_keepalive(r);
  +
  +        h.r = r;
  +        h.buf = buff;
   
  -        apr_table_do((int (*)(void *, const char *, const char *)) ap_send_header_field,
  -                    (void *) r, r->headers_out,
  +        apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
  +                    (void *) &h, r->headers_out,
                       "Connection",
                       "Keep-Alive",
                       "ETag",
  @@ -3213,8 +3261,13 @@
                       "WWW-Authenticate",
                       "Proxy-Authenticate",
                       NULL);
  +
  +        terminate_header(buff);
  +
  +        bb = ap_brigade_create(r->pool);
  +        AP_BRIGADE_INSERT_HEAD(bb, e);
  +        ap_pass_brigade(r->connection->output_filters, bb);
   
  -        terminate_header(r);
           ap_finalize_request_protocol(r);
           return;
       }
  
  
  

Mime
View raw message