Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions modules/http/http_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,7 @@ static char *make_allow(request_rec *r)

/* ### this is rather annoying. we should enforce registration of
### these methods */
if ((mask & (AP_METHOD_BIT << M_INVALID))
&& (r->allowed_methods->method_list != NULL)
if (r->allowed_methods->method_list != NULL
&& (r->allowed_methods->method_list->nelts != 0)) {
apr_array_cat(allow, r->allowed_methods->method_list);
}
Expand Down
46 changes: 46 additions & 0 deletions test/modules/core/test_009_allow_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import pytest

from pyhttpd.conf import HttpdConf


class TestAllowMethods:

@pytest.fixture(autouse=True, scope='class')
def _class_scope(self, env):
conf = HttpdConf(env)
conf.add_vhost_test1()
conf.install()
assert env.apache_restart() == 0

# mod_aptest passes the methods named in AP-Test-Allow-Methods to
# ap_allow_methods() from a fixups hook; the default handler then
# merges its own and answers OPTIONS with the Allow header.
def options(self, env, methods=None):
options = ['-X', 'OPTIONS']
if methods is not None:
options.extend(['-H', f'AP-Test-Allow-Methods: {methods}'])
r = env.curl_get(env.mkurl("http", "test1", "/index.html"),
options=options)
assert r.response, f"no response: {r.stderr}"
assert r.response["status"] == 200
return [m.strip() for m in r.response["header"]["allow"].split(',')]

def test_core_009_01(self, env):
allow = self.options(env)
for method in ["GET", "POST", "OPTIONS"]:
assert method in allow, f"expected {method} in Allow: {allow}"

def test_core_009_02(self, env):
allow = self.options(env, "DELETE")
assert "DELETE" in allow, f"expected DELETE in Allow: {allow}"

# An extension method reaches make_allow() only through method_list,
# which is emitted just when the M_INVALID bit is set in method_mask.
def test_core_009_03(self, env):
allow = self.options(env, "FROBNICATE")
assert "FROBNICATE" in allow, f"expected FROBNICATE in Allow: {allow}"

def test_core_009_04(self, env):
allow = self.options(env, "DELETE, FROBNICATE")
for method in ["DELETE", "FROBNICATE"]:
assert method in allow, f"expected {method} in Allow: {allow}"
24 changes: 24 additions & 0 deletions test/pyhttpd/mod_aptest/mod_aptest.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ static int aptest_post_read_request(request_rec *r)
return DECLINED;
}

/*
* Register the methods named in an "AP-Test-Allow-Methods" request header
* via ap_allow_methods(), so a test can check how they are reflected in the
* Allow response header.
*/
static int aptest_allow_methods(request_rec *r)
{
const char *methods = apr_table_get(r->headers_in, "AP-Test-Allow-Methods");
char *list, *name, *last;

if (methods == NULL) {
return DECLINED;
}

list = apr_pstrdup(r->pool, methods);
for (name = apr_strtok(list, ", ", &last); name != NULL;
name = apr_strtok(NULL, ", ", &last)) {
ap_allow_methods(r, MERGE_ALLOW, name, NULL);
}

return DECLINED;
}

/* Install this module into the apache2 infrastructure.
*/
static void aptest_hooks(apr_pool_t *pool)
Expand All @@ -61,6 +84,7 @@ static void aptest_hooks(apr_pool_t *pool)
/* test case monitoring */
ap_hook_post_read_request(aptest_post_read_request, NULL,
NULL, APR_HOOK_MIDDLE);
ap_hook_fixups(aptest_allow_methods, NULL, NULL, APR_HOOK_MIDDLE);

}

Loading