mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
* modules/filters/mod_sed.c (sed_request_filter): Fix handling of the
Content-Length request header; unset it after reading from the next filter. * test/pyhttpd/mod_aptest/mod_aptest.c (aptest_getline_echo): Buffer the body, and return the Content-Length request header left after reading it in an AP-Test-Content-Length response header. * test/modules/filters/test_003_sed.py (test_filters_003_34): New test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> GitHub: PR #791 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1938964 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -516,6 +516,11 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
|
||||
if (status != APR_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
/* The body passed on is not the length the request gave. Only
|
||||
* drop the header after this read: HTTP_IN takes the length from
|
||||
* it on the first.
|
||||
*/
|
||||
apr_table_unset(f->r->headers_in, "Content-Length");
|
||||
for (b = APR_BRIGADE_FIRST(bbinp); b != APR_BRIGADE_SENTINEL(bbinp);
|
||||
b = APR_BUCKET_NEXT(b)) {
|
||||
const char *buf = NULL;
|
||||
|
||||
@@ -386,6 +386,27 @@ class TestSed:
|
||||
assert r.response["status"] == 200
|
||||
assert r.response["body"] == b"one MON two\nMON MON\n"
|
||||
|
||||
# The request Content-Length is the length of the body before it was
|
||||
# filtered, so once mod_sed has started reading the body it is removed:
|
||||
# a handler must not find the original length.
|
||||
def test_filters_003_34(self, env):
|
||||
self.configure(env, "s/monday/MONDAYMONDAY/g", input_sed=True,
|
||||
extra="""
|
||||
<Location "/getline">
|
||||
SetHandler aptest-getline-echo
|
||||
SetInputFilter SED
|
||||
</Location>
|
||||
""")
|
||||
data = "one monday two\nmonday monday\n"
|
||||
r = env.curl_post_data(env.mkurl("http", "test1", "/getline"),
|
||||
data=data)
|
||||
assert r.response, "no response"
|
||||
assert r.response["status"] == 200
|
||||
assert r.response["body"] == \
|
||||
data.replace("monday", "MONDAYMONDAY").encode()
|
||||
assert "ap-test-content-length" not in r.response["header"], \
|
||||
r.response["header"]
|
||||
|
||||
# --- interval expressions ---------------------------------------------
|
||||
|
||||
# \{m,n\} repeats a character or a bracket expression.
|
||||
|
||||
@@ -76,11 +76,16 @@ static int aptest_allow_methods(request_rec *r)
|
||||
|
||||
/*
|
||||
* Handler "aptest-getline-echo": echo the request body back, reading it
|
||||
* with AP_MODE_GETLINE rather than AP_MODE_READBYTES.
|
||||
* with AP_MODE_GETLINE rather than AP_MODE_READBYTES. The Content-Length
|
||||
* request header left once the body has been read, if any, is returned in
|
||||
* an "AP-Test-Content-Length" response header.
|
||||
*/
|
||||
static int aptest_getline_echo(request_rec *r)
|
||||
{
|
||||
apr_bucket_brigade *bb;
|
||||
apr_bucket_brigade *bb, *body;
|
||||
const char *clen;
|
||||
char *data;
|
||||
apr_size_t len;
|
||||
apr_status_t rv;
|
||||
int seen_eos = 0;
|
||||
|
||||
@@ -88,12 +93,9 @@ static int aptest_getline_echo(request_rec *r)
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
ap_set_content_type(r, "text/plain");
|
||||
bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
|
||||
body = apr_brigade_create(r->pool, r->connection->bucket_alloc);
|
||||
while (!seen_eos) {
|
||||
char *line;
|
||||
apr_size_t len;
|
||||
|
||||
rv = ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE,
|
||||
APR_BLOCK_READ, HUGE_STRING_LEN);
|
||||
if (rv != APR_SUCCESS) {
|
||||
@@ -105,14 +107,26 @@ static int aptest_getline_echo(request_rec *r)
|
||||
&& APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
|
||||
seen_eos = 1;
|
||||
}
|
||||
rv = apr_brigade_pflatten(bb, &line, &len, r->pool);
|
||||
rv = apr_brigade_pflatten(bb, &data, &len, r->pool);
|
||||
if (rv == APR_SUCCESS) {
|
||||
rv = apr_brigade_write(body, NULL, NULL, data, len);
|
||||
}
|
||||
if (rv != APR_SUCCESS) {
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
ap_rwrite(line, len, r);
|
||||
apr_brigade_cleanup(bb);
|
||||
}
|
||||
|
||||
clen = apr_table_get(r->headers_in, "Content-Length");
|
||||
if (clen) {
|
||||
apr_table_setn(r->headers_out, "AP-Test-Content-Length", clen);
|
||||
}
|
||||
ap_set_content_type(r, "text/plain");
|
||||
if (apr_brigade_pflatten(body, &data, &len, r->pool) != APR_SUCCESS) {
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
ap_rwrite(data, len, r);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user