Should I continue this way? Simply to propose patches?
On Sat, Oct 19, 2013 at 4:13 PM, Eric Covener <[email protected]> wrote:
> Currently, when the body is consumed by a handler, a side effect is
> reading footers that might be present and copying them to
> r->headers_in.
>
> This presents a series of problems.
>
> * things that inspect r->headers_in expect it to be fluffed up much
> earlier than midway through the handler phase
>
> * if the handler looks at headers before reading the body, they could
> differ from what's logged
>
> * if the handler looks at headers after reading the body, mod_headers
> was out of the loop if configured.
>
> I am thinking:
>
> now:
>
> 1) add r->footers_in and use it in 2.2 and up by default
>
Do that mean no API/ABI change ?
> 2) add a directive to copy them up to r->headers_in (for those broken
> by the change)
>
> soon:
>
> 3) add a hook to parse footers
>
> later:
> 4) try to teach mod_headers to do something useful with that hook, but
> not with existing directives.
> 5) teach mod_log_config to log from footers_in
>
Not done (yet), maybe I could try or am I completely bogged down with the
design?
Maybe it worth also :
6) teach ap_expr/ssl_lookup to interpolate from footers
7) teach mod_rewrite (hooked) how to play with footers
8) teach mod_proxy_http to forward the footers
A proposition for 8) follows.
Regards.
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c (revision 1534970)
+++ modules/proxy/proxy_util.c (working copy)
@@ -3114,11 +3114,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
char **old_te_val)
{
conn_rec *c = r->connection;
- int counter;
char *buf;
- const apr_array_header_t *headers_in_array;
- const apr_table_entry_t *headers_in;
- apr_table_t *headers_in_copy;
apr_bucket *e;
int do_100_continue;
conn_rec *origin = p_conn->connection;
@@ -3278,19 +3274,42 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
}
proxy_run_fixups(r);
+ return ap_proxy_fill_hdrbrgd(p, header_brigade, r->headers_in, r,
+ old_cl_val, old_te_val);
+}
+
+PROXY_DECLARE(int) ap_proxy_fill_hdrbrgd(apr_pool_t *p,
+ apr_bucket_brigade
*header_brigade,
+ const apr_table_t *header_table,
+ request_rec *r, char **old_cl_val,
+ char **old_te_val)
+{
+ const apr_array_header_t *headers_in_array;
+ const apr_table_entry_t *headers_in;
+ apr_table_t *headers_in_copy;
+ apr_bucket *e;
+ int counter;
+ char *buf;
+
+ /* easy path first */
+ if (apr_is_empty_table(header_table)) {
+ return OK;
+ }
+
/*
- * Make a copy of the headers_in table before clearing the connection
+ * Make a copy of the header_table before clearing the connection
* headers as we need the connection headers later in the http output
* filter to prepare the correct response headers.
*
* Note: We need to take r->pool for apr_table_copy as the key / value
- * pairs in r->headers_in have been created out of r->pool and
- * p might be (and actually is) a longer living pool.
+ * pairs in header_table (eg. r->headers/footers_in) have been created
+ * out of r->pool and p might be (and actually is) a longer living
pool.
* This would trigger the bad pool ancestry abort in apr_table_copy if
* apr is compiled with APR_POOL_DEBUG.
*/
- headers_in_copy = apr_table_copy(r->pool, r->headers_in);
+ headers_in_copy = apr_table_copy(r->pool, header_table);
ap_proxy_clear_connection(r, headers_in_copy);
+
/* send request headers */
headers_in_array = apr_table_elts(headers_in_copy);
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
@@ -3317,7 +3336,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
* If we have used it then MAYBE: RFC2616 says we MAY propagate it.
* So let's make it configurable by env.
*/
- if (!strcasecmp(headers_in[counter].key,"Proxy-Authorization")) {
+ if (!strcasecmp(headers_in[counter].key, "Proxy-Authorization")) {
if (r->user != NULL) { /* we've authenticated */
if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))
{
continue;
@@ -3328,17 +3347,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
/* Skip Transfer-Encoding and Content-Length for now.
*/
if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) {
- *old_te_val = headers_in[counter].val;
+ if (old_te_val) {
+ *old_te_val = headers_in[counter].val;
+ }
continue;
}
if (!strcasecmp(headers_in[counter].key, "Content-Length")) {
- *old_cl_val = headers_in[counter].val;
+ if (old_cl_val) {
+ *old_cl_val = headers_in[counter].val;
+ }
continue;
}
/* for sub-requests, ignore freshness/expiry headers */
if (r->main) {
- if ( !strcasecmp(headers_in[counter].key, "If-Match")
+ if ( !strcasecmp(headers_in[counter].key, "If-Match")
|| !strcasecmp(headers_in[counter].key,
"If-Modified-Since")
|| !strcasecmp(headers_in[counter].key, "If-Range")
|| !strcasecmp(headers_in[counter].key,
"If-Unmodified-Since")
@@ -3351,9 +3374,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
headers_in[counter].val, CRLF,
NULL);
ap_xlate_proto_to_ascii(buf, strlen(buf));
- e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
+ e = apr_bucket_pool_create(buf, strlen(buf), p,
+ r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
}
+
return OK;
}
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c (revision 1534970)
+++ modules/proxy/mod_proxy_http.c (working copy)
@@ -339,11 +339,11 @@ static int stream_reqbody_chunked(apr_pool_t *p,
bb = input_brigade;
}
- e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
- /* <trailers> */
- ASCII_CRLF,
- 5, bucket_alloc);
+ e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF, 3, bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
+ ap_proxy_fill_hdrbrgd(p, bb, r->footers_in, r, NULL, NULL);
+ e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) {
e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
@@ -994,6 +994,7 @@ static request_rec *make_fake_req(conn_rec *c, req
rp->status = HTTP_OK;
rp->headers_in = apr_table_make(pool, 50);
+ rp->footers_in = apr_table_make(pool, 5);
rp->subprocess_env = apr_table_make(pool, 50);
rp->headers_out = apr_table_make(pool, 12);
rp->err_headers_out = apr_table_make(pool, 5);
Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h (revision 1534970)
+++ modules/proxy/mod_proxy.h (working copy)
@@ -971,6 +971,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
char **old_te_val);
/**
+ * Fill a HTTP request header brigade, old_cl_val and old_te_val as
required.
+ * @param p pool
+ * @param header_brigade header brigade to fill
+ * @param header_table header table to use
+ * @param r request
+ * @param old_cl_val stored old content-len val
+ * @param old_te_val stored old TE val
+ * @return OK
+ */
+PROXY_DECLARE(int) ap_proxy_fill_hdrbrgd(apr_pool_t *p,
+ apr_bucket_brigade
*header_brigade,
+ const apr_table_t *header_table,
+ request_rec *r, char **old_cl_val,
+ char **old_te_val);
+/**
* @param bucket_alloc bucket allocator
* @param r request
* @param p_conn proxy connection
[EOS]
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c (revision 1534970)
+++ modules/proxy/proxy_util.c (working copy)
@@ -3114,11 +3114,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
char **old_te_val)
{
conn_rec *c = r->connection;
- int counter;
char *buf;
- const apr_array_header_t *headers_in_array;
- const apr_table_entry_t *headers_in;
- apr_table_t *headers_in_copy;
apr_bucket *e;
int do_100_continue;
conn_rec *origin = p_conn->connection;
@@ -3278,19 +3274,42 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
}
proxy_run_fixups(r);
+ return ap_proxy_fill_hdrbrgd(p, header_brigade, r->headers_in, r,
+ old_cl_val, old_te_val);
+}
+
+PROXY_DECLARE(int) ap_proxy_fill_hdrbrgd(apr_pool_t *p,
+ apr_bucket_brigade *header_brigade,
+ const apr_table_t *header_table,
+ request_rec *r, char **old_cl_val,
+ char **old_te_val)
+{
+ const apr_array_header_t *headers_in_array;
+ const apr_table_entry_t *headers_in;
+ apr_table_t *headers_in_copy;
+ apr_bucket *e;
+ int counter;
+ char *buf;
+
+ /* easy path first */
+ if (apr_is_empty_table(header_table)) {
+ return OK;
+ }
+
/*
- * Make a copy of the headers_in table before clearing the connection
+ * Make a copy of the header_table before clearing the connection
* headers as we need the connection headers later in the http output
* filter to prepare the correct response headers.
*
* Note: We need to take r->pool for apr_table_copy as the key / value
- * pairs in r->headers_in have been created out of r->pool and
- * p might be (and actually is) a longer living pool.
+ * pairs in header_table (eg. r->headers/footers_in) have been created
+ * out of r->pool and p might be (and actually is) a longer living pool.
* This would trigger the bad pool ancestry abort in apr_table_copy if
* apr is compiled with APR_POOL_DEBUG.
*/
- headers_in_copy = apr_table_copy(r->pool, r->headers_in);
+ headers_in_copy = apr_table_copy(r->pool, header_table);
ap_proxy_clear_connection(r, headers_in_copy);
+
/* send request headers */
headers_in_array = apr_table_elts(headers_in_copy);
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
@@ -3317,7 +3336,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
* If we have used it then MAYBE: RFC2616 says we MAY propagate it.
* So let's make it configurable by env.
*/
- if (!strcasecmp(headers_in[counter].key,"Proxy-Authorization")) {
+ if (!strcasecmp(headers_in[counter].key, "Proxy-Authorization")) {
if (r->user != NULL) { /* we've authenticated */
if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
continue;
@@ -3328,17 +3347,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
/* Skip Transfer-Encoding and Content-Length for now.
*/
if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) {
- *old_te_val = headers_in[counter].val;
+ if (old_te_val) {
+ *old_te_val = headers_in[counter].val;
+ }
continue;
}
if (!strcasecmp(headers_in[counter].key, "Content-Length")) {
- *old_cl_val = headers_in[counter].val;
+ if (old_cl_val) {
+ *old_cl_val = headers_in[counter].val;
+ }
continue;
}
/* for sub-requests, ignore freshness/expiry headers */
if (r->main) {
- if ( !strcasecmp(headers_in[counter].key, "If-Match")
+ if ( !strcasecmp(headers_in[counter].key, "If-Match")
|| !strcasecmp(headers_in[counter].key, "If-Modified-Since")
|| !strcasecmp(headers_in[counter].key, "If-Range")
|| !strcasecmp(headers_in[counter].key, "If-Unmodified-Since")
@@ -3351,9 +3374,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
headers_in[counter].val, CRLF,
NULL);
ap_xlate_proto_to_ascii(buf, strlen(buf));
- e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
+ e = apr_bucket_pool_create(buf, strlen(buf), p,
+ r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
}
+
return OK;
}
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c (revision 1534970)
+++ modules/proxy/mod_proxy_http.c (working copy)
@@ -339,11 +339,11 @@ static int stream_reqbody_chunked(apr_pool_t *p,
bb = input_brigade;
}
- e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
- /* <trailers> */
- ASCII_CRLF,
- 5, bucket_alloc);
+ e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF, 3, bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
+ ap_proxy_fill_hdrbrgd(p, bb, r->footers_in, r, NULL, NULL);
+ e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) {
e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
@@ -994,6 +994,7 @@ static request_rec *make_fake_req(conn_rec *c, req
rp->status = HTTP_OK;
rp->headers_in = apr_table_make(pool, 50);
+ rp->footers_in = apr_table_make(pool, 5);
rp->subprocess_env = apr_table_make(pool, 50);
rp->headers_out = apr_table_make(pool, 12);
rp->err_headers_out = apr_table_make(pool, 5);
Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h (revision 1534970)
+++ modules/proxy/mod_proxy.h (working copy)
@@ -971,6 +971,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_poo
char **old_te_val);
/**
+ * Fill a HTTP request header brigade, old_cl_val and old_te_val as required.
+ * @param p pool
+ * @param header_brigade header brigade to fill
+ * @param header_table header table to use
+ * @param r request
+ * @param old_cl_val stored old content-len val
+ * @param old_te_val stored old TE val
+ * @return OK
+ */
+PROXY_DECLARE(int) ap_proxy_fill_hdrbrgd(apr_pool_t *p,
+ apr_bucket_brigade *header_brigade,
+ const apr_table_t *header_table,
+ request_rec *r, char **old_cl_val,
+ char **old_te_val);
+/**
* @param bucket_alloc bucket allocator
* @param r request
* @param p_conn proxy connection