mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
mod_dav: Do not advertise disabled TRACE
dav_method_options() builds its own Allow field and unconditionally advertised TRACE for existing DAV resources, even when TraceEnable was off. Respect TraceEnable when constructing the DAV Allow field. PR: 70264 GitHub: closes #827 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1939146 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
2
changes-entries/dav-options-trace.txt
Normal file
2
changes-entries/dav-options-trace.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
*) mod_dav: Do not list TRACE in the Allow field of an OPTIONS response when
|
||||
TraceEnable is off. PR 70264
|
||||
@@ -1844,6 +1844,8 @@ static int dav_method_search(request_rec *r)
|
||||
/* handle the OPTIONS method */
|
||||
static int dav_method_options(request_rec *r)
|
||||
{
|
||||
core_server_config *conf =
|
||||
ap_get_core_module_config(r->server->module_config);
|
||||
const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r);
|
||||
const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
|
||||
const dav_hooks_binding *binding_hooks = DAV_GET_HOOKS_BINDING(r);
|
||||
@@ -1975,7 +1977,9 @@ static int dav_method_options(request_rec *r)
|
||||
apr_table_addn(methods, "HEAD", "");
|
||||
apr_table_addn(methods, "POST", "");
|
||||
apr_table_addn(methods, "DELETE", "");
|
||||
apr_table_addn(methods, "TRACE", "");
|
||||
if (conf->trace_enable != AP_TRACE_DISABLE) {
|
||||
apr_table_addn(methods, "TRACE", "");
|
||||
}
|
||||
apr_table_addn(methods, "PROPFIND", "");
|
||||
apr_table_addn(methods, "PROPPATCH", "");
|
||||
apr_table_addn(methods, "COPY", "");
|
||||
|
||||
75
test/modules/dav/test_002_options_trace.py
Normal file
75
test/modules/dav/test_002_options_trace.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from pyhttpd.conf import HttpdConf
|
||||
|
||||
DAV_METHODS = {"OPTIONS", "GET", "HEAD", "POST", "DELETE", "PROPFIND",
|
||||
"PROPPATCH", "COPY", "MOVE", "LOCK", "UNLOCK"}
|
||||
|
||||
|
||||
def _setup(env, trace):
|
||||
dav_dir = os.path.join(env.gen_dir, 'dav')
|
||||
os.makedirs(os.path.join(dav_dir, 'col'), exist_ok=True)
|
||||
with open(os.path.join(dav_dir, 'file.txt'), 'w') as fd:
|
||||
fd.write('hello\n')
|
||||
conf = HttpdConf(env, extras={
|
||||
'base': f"""
|
||||
DavLockDB "{env.gen_dir}/davlock"
|
||||
TraceEnable {trace}
|
||||
""",
|
||||
f"test1.{env.http_tld}": f"""
|
||||
Alias /dav "{dav_dir}"
|
||||
<Directory "{dav_dir}">
|
||||
Dav On
|
||||
Require all granted
|
||||
</Directory>
|
||||
""",
|
||||
})
|
||||
conf.add_vhost_test1()
|
||||
conf.install()
|
||||
assert env.apache_restart() == 0
|
||||
|
||||
|
||||
def _request(env, method, path):
|
||||
r = env.curl_raw(env.mkurl("https", "test1", path),
|
||||
options=['-X', method])
|
||||
assert r.response, f"no response: {r.stderr}"
|
||||
allow = r.response["header"].get("allow", "")
|
||||
return r.response["status"], {m.strip() for m in allow.split(',') if m.strip()}
|
||||
|
||||
|
||||
class TestOptionsTraceDisabled:
|
||||
|
||||
@pytest.fixture(autouse=True, scope='class')
|
||||
def _class_scope(self, env):
|
||||
_setup(env, "off")
|
||||
|
||||
# TRACE is not offered while the server refuses it
|
||||
@pytest.mark.parametrize("path", ["/dav/file.txt", "/dav/col/"])
|
||||
def test_dav_002_001(self, env, path):
|
||||
status, allow = _request(env, "OPTIONS", path)
|
||||
assert status == 200
|
||||
assert "TRACE" not in allow, f"Allow: {allow}"
|
||||
assert DAV_METHODS <= allow, f"Allow: {allow}"
|
||||
|
||||
def test_dav_002_002(self, env):
|
||||
assert _request(env, "TRACE", "/dav/file.txt")[0] == 405
|
||||
|
||||
|
||||
class TestOptionsTraceEnabled:
|
||||
|
||||
@pytest.fixture(autouse=True, scope='class',
|
||||
params=["on", "extended"])
|
||||
def _class_scope(self, env, request):
|
||||
_setup(env, request.param)
|
||||
|
||||
# unchanged: TRACE is offered and works
|
||||
@pytest.mark.parametrize("path", ["/dav/file.txt", "/dav/col/"])
|
||||
def test_dav_002_101(self, env, path):
|
||||
status, allow = _request(env, "OPTIONS", path)
|
||||
assert status == 200
|
||||
assert (DAV_METHODS | {"TRACE"}) <= allow, f"Allow: {allow}"
|
||||
|
||||
def test_dav_002_102(self, env):
|
||||
assert _request(env, "TRACE", "/dav/file.txt")[0] == 200
|
||||
Reference in New Issue
Block a user