rbb 01/02/08 23:17:55
Modified: . CHANGES
include http_protocol.h
modules/http http_protocol.c
Log:
Make the header filter use the brigade buffering functions for creating
the header string. This allows us to clean up the header handling a bit,
because we don't need to compute the correct length before we can create
the headers.
Revision Changes Path
1.82 +5 -0 httpd-2.0/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-2.0/CHANGES,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -b -w -u -r1.81 -r1.82
--- CHANGES 2001/02/09 07:04:50 1.81
+++ CHANGES 2001/02/09 07:17:50 1.82
@@ -1,5 +1,10 @@
Changes with Apache 2.0b1
+ *) Cleanup the header handling a bit. This uses the apr_brigade_*
+ functions for the buffering so that we don't need to compute
+ the length of the headers before we actually create the header
+ buffer. [Ryan Bloom]
+
*) Allow filters to buffer data using the ap_f* functions. These have
become macros that resolve directly to apr_brigade_*.
[Ryan Bloom]
1.52 +3 -3 httpd-2.0/include/http_protocol.h
Index: http_protocol.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/http_protocol.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -b -w -u -r1.51 -r1.52
--- http_protocol.h 2001/02/05 03:31:43 1.51
+++ http_protocol.h 2001/02/09 07:17:52 1.52
@@ -88,13 +88,13 @@
/**
* Send the minimal part of an HTTP response header.
* @param r The current request
- * @param buf The buffer to add the header to.
+ * @param bb The brigade 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, char *buf)
+ * @deffunc void ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
*/
-AP_DECLARE(void) ap_basic_http_header(request_rec *r, char *buf);
+AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb);
/**
* Send the Status-Line and header fields for HTTP response
1.293 +25 -74 httpd-2.0/modules/http/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.292
retrieving revision 1.293
diff -u -d -b -w -u -r1.292 -r1.293
--- http_protocol.c 2001/02/08 07:44:03 1.292
+++ http_protocol.c 2001/02/09 07:17:53 1.293
@@ -1792,7 +1792,7 @@
typedef struct header_struct {
request_rec *r;
- char *buf;
+ apr_bucket_brigade *bb;
} header_struct;
/* Send a single HTTP header field to the client. Note that this function
@@ -1807,16 +1807,7 @@
headfield = apr_pstrcat(h->r->pool, fieldname, ": ", fieldval, CRLF, NULL);
ap_xlate_proto_to_ascii(headfield, strlen(headfield));
- apr_cpystrn(h->buf, headfield, strlen(headfield) + 1);
- h->buf += strlen(headfield);
- return 1;
-}
-
-static int compute_header_len(apr_size_t *length, const char *fieldname,
- const char *fieldval)
-{
- /* The extra five are for ": " and CRLF, plus one for a '\0'. */
- *length = *length + strlen(fieldname) + strlen(fieldval) + 6;
+ apr_brigade_write(h->bb, NULL, NULL, headfield, strlen(headfield));
return 1;
}
@@ -1844,7 +1835,7 @@
}
}
-static void basic_http_header(request_rec *r, char *buf, const char *protocol)
+static void basic_http_header(request_rec *r, apr_bucket_brigade *bb, const char *protocol)
{
char *date = NULL;
char *tmp;
@@ -1857,14 +1848,13 @@
tmp = apr_pstrcat(r->pool, protocol, " ", r->status_line, CRLF, NULL);
ap_xlate_proto_to_ascii(tmp, strlen(tmp));
- apr_cpystrn(buf, tmp, strlen(tmp) + 1);
- buf += strlen(tmp);
+ apr_brigade_write(bb, NULL, NULL, tmp, strlen(tmp));
date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
apr_rfc822_date(date, r->request_time);
h.r = r;
- h.buf = buf;
+ h.bb = bb;
form_header_field(&h, "Date", date);
form_header_field(&h, "Server", ap_get_server_version());
@@ -1872,12 +1862,12 @@
apr_table_unset(r->headers_out, "Server");
}
-AP_DECLARE(void) ap_basic_http_header(request_rec *r, char *buf)
+AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
{
const char *protocol;
basic_http_header_check(r, &protocol);
- basic_http_header(r, buf, protocol);
+ basic_http_header(r, bb, protocol);
}
/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
@@ -1897,18 +1887,19 @@
* 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(char *buf)
+static void terminate_header(apr_bucket_brigade *bb)
{
- int len = strlen(buf);
- char *headfield = buf + len;
char *tmp = "X-Pad: avoid browser bug" CRLF;
+ char *crlf = CRLF;
+ apr_bucket *b = APR_BRIGADE_LAST(bb);
+ apr_bucket_shared *s = b->data;
- if (len >= 255 && len <= 257) {
- apr_cpystrn(headfield, tmp, strlen(tmp) + 1);
- headfield += strlen(tmp);
+ if (s->end >= 255 && s->end <= 257) {
+ ap_xlate_proto_to_ascii(tmp, strlen(tmp));
+ apr_brigade_write(bb, NULL, NULL, tmp, strlen(tmp));
}
- apr_cpystrn(headfield, CRLF, strlen(CRLF) + 1);
- ap_xlate_proto_to_ascii(buf + len, strlen(buf + len));
+ ap_xlate_proto_to_ascii(crlf, strlen(crlf));
+ apr_brigade_write(bb, NULL, NULL, crlf, strlen(crlf));
}
/*
@@ -2154,42 +2145,28 @@
int ap_send_http_options(request_rec *r)
{
- char *buff;
- apr_bucket *b;
- apr_bucket_brigade *bb;
- apr_size_t len = 0;
+ apr_bucket_brigade *bb = apr_brigade_create(r->pool);
header_struct h;
if (r->assbackwards)
return DECLINED;
-
- apr_table_do((int (*) (void *, const char *, const char *)) compute_header_len,
- (void *) &len, r->headers_out, NULL);
- /* Need to add a fudge factor so that the CRLF at the end of the headers
- * and the basic http headers don't overflow this buffer.
- */
- len += strlen(ap_get_server_version()) + 100;
- buff = apr_pcalloc(r->pool, len);
- ap_basic_http_header(r, buff);
+ ap_basic_http_header(r, bb);
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;
+ h.bb = bb;
apr_table_do((int (*) (void *, const char *, const char *)) form_header_field,
(void *) &h, r->headers_out, NULL);
- terminate_header(buff);
+ terminate_header(bb);
r->bytes_sent = 0;
- bb = apr_brigade_create(r->pool);
- b = apr_bucket_pool_create(buff, strlen(buff), r->pool);
- APR_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(r->output_filters, bb);
return OK;
@@ -2462,11 +2439,10 @@
int i;
char *date = NULL;
request_rec *r = f->r;
- char *buff, *buff_start;
const char *clheader;
const char *protocol;
apr_bucket *e;
- apr_bucket_brigade *b2;
+ apr_bucket_brigade *b2 = apr_brigade_create(r->pool);
apr_size_t len = 0;
header_struct h;
header_filter_ctx *ctx = f->ctx;
@@ -2580,33 +2556,11 @@
!strcmp(clheader, "0")) {
apr_table_unset(r->headers_out, "Content-Length");
}
-
- if (r->status == HTTP_NOT_MODIFIED) {
- apr_table_do((int (*)(void *, const char *, const char *)) compute_header_len,
- (void *) &len, r->headers_out,
- "Connection",
- "Keep-Alive",
- "ETag",
- "Content-Location",
- "Expires",
- "Cache-Control",
- "Vary",
- "Warning",
- "WWW-Authenticate",
- "Proxy-Authenticate",
- NULL);
- }
- else {
- apr_table_do((int (*) (void *, const char *, const char *)) compute_header_len,
- (void *) &len, r->headers_out, NULL);
- }
- buff_start = buff = apr_pcalloc(r->pool, len);
- basic_http_header(r, buff, protocol);
- buff += strlen(buff);
+ basic_http_header(r, b2, protocol);
h.r = r;
- h.buf = buff;
+ h.bb = b2;
if (r->status == HTTP_NOT_MODIFIED) {
apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
@@ -2628,13 +2582,10 @@
(void *) &h, r->headers_out, NULL);
}
- terminate_header(buff);
+ terminate_header(b2);
r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
- b2 = apr_brigade_create(r->pool);
- e = apr_bucket_pool_create(buff_start, strlen(buff_start), r->pool);
- APR_BRIGADE_INSERT_HEAD(b2, e);
ap_pass_brigade(f->next, b2);
if (r->header_only) {
|