diff --git a/changes-entries/expr-protocol-version.txt b/changes-entries/expr-protocol-version.txt new file mode 100644 index 00000000000..75661591fd5 --- /dev/null +++ b/changes-entries/expr-protocol-version.txt @@ -0,0 +1,2 @@ + *) ap_expr: Add SERVER_PROTOCOL_VERSION, ..._MAJOR, and ..._MINOR + variables. [Stefan Fritsch] diff --git a/changes-entries/pr70295.txt b/changes-entries/pr70295.txt new file mode 100644 index 00000000000..b9a24f78e5e --- /dev/null +++ b/changes-entries/pr70295.txt @@ -0,0 +1,2 @@ + *) core: Fix REMOTE_PORT in expressions and environment variables. + PR 70295. [Steve Bennett ] diff --git a/docs/manual/expr.xml b/docs/manual/expr.xml index 27cfb5c74aa..8d3a7e849ef 100644 --- a/docs/manual/expr.xml +++ b/docs/manual/expr.xml @@ -256,7 +256,20 @@ listfunction ::= listfuncname "(" word ")" The ServerAdmin of the current vhost SERVER_PROTOCOL - The protocol used by the request + The protocol used by the request (e.g. HTTP/1.1). In some types of + internal subrequests, this variable has the value + INCLUDED. + SERVER_PROTOCOL_VERSION + A number that encodes the HTTP version of the request: + 1000 * major + minor. For example, 1001 + corresponds to HTTP/1.1 and 9 corresponds + to HTTP/0.9 + SERVER_PROTOCOL_VERSION_MAJOR + A major version part of the HTTP version of the request, + e.g. 1 for HTTP/1.0 + SERVER_PROTOCOL_VERSION_MINOR + A minor version part of the HTTP version of the request, + e.g. 0 for HTTP/1.0 DOCUMENT_ROOT The DocumentRoot of the current vhost @@ -704,6 +717,11 @@ CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'4 Version History

The req_novary function is available for versions 2.4.4 and later.

+

The SERVER_PROTOCOL_VERSION, + SERVER_PROTOCOL_VERSION_MAJOR and + SERVER_PROTOCOL_VERSION_MINOR + variables + are available for versions 2.4.71 and later.

diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index a61199beb57..be9684df290 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -1380,7 +1380,10 @@ static const char *const request_var_names[] = { "CONTEXT_DOCUMENT_ROOT", /* 26 */ "REQUEST_STATUS", /* 27 */ "REMOTE_ADDR", /* 28 */ - "REMOTE_PORT", /* 29 */ + "SERVER_PROTOCOL_VERSION", /* 29 */ + "SERVER_PROTOCOL_VERSION_MAJOR", /* 30 */ + "SERVER_PROTOCOL_VERSION_MINOR", /* 31 */ + "REMOTE_PORT", /* 32 */ NULL }; @@ -1471,7 +1474,27 @@ static const char *request_var_fn(ap_expr_eval_ctx_t *ctx, const void *data) case 28: return r->useragent_ip; case 29: - return apr_psprintf(ctx->p, "%u", ctx->c->client_addr->port); + switch (r->proto_num) { + case 1001: return "1001"; /* 1.1 */ + case 1000: return "1000"; /* 1.0 */ + case 9: return "9"; /* 0.9 */ + } + return apr_psprintf(ctx->p, "%d", r->proto_num); + case 30: + switch (HTTP_VERSION_MAJOR(r->proto_num)) { + case 0: return "0"; + case 1: return "1"; + } + return apr_psprintf(ctx->p, "%d", HTTP_VERSION_MAJOR(r->proto_num)); + case 31: + switch (HTTP_VERSION_MINOR(r->proto_num)) { + case 0: return "0"; + case 1: return "1"; + case 9: return "9"; + } + return apr_psprintf(ctx->p, "%d", HTTP_VERSION_MINOR(r->proto_num)); + case 32: + return apr_psprintf(ctx->p, "%u", r->useragent_addr->port); default: ap_assert(0); return NULL; diff --git a/server/util_script.c b/server/util_script.c index 6a18aec8c90..34d4942bb54 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -175,7 +175,6 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) { apr_table_t *e; server_rec *s = r->server; - conn_rec *c = r->connection; core_dir_config *conf = (core_dir_config *)ap_get_core_module_config(r->per_dir_config); const char *env_temp; @@ -291,7 +290,7 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ } - rport = c->client_addr->port; + rport = r->useragent_addr->port; apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport)); if (r->user) { diff --git a/test/modules/metadata/test_004_remoteip.py b/test/modules/metadata/test_004_remoteip.py index 8afca7784c7..dfc8a3aab68 100644 --- a/test/modules/metadata/test_004_remoteip.py +++ b/test/modules/metadata/test_004_remoteip.py @@ -245,7 +245,8 @@ def test_metadata_004_06(self, env): # wherever a configuration asks for it: the REMOTE_PORT variable of # ap_expr (here via mod_headers) and the CGI/SSI REMOTE_PORT variable # (here via mod_include). Bug 70295. - REMOTE_PORT_FIX = not_backported("gh-896", "REMOTE_PORT from the useragent address") + REMOTE_PORT_FIX = not_backported("gh-896", "REMOTE_PORT from the useragent address", + backported_in="2.4.71") def remote_port_install(self, env): """A PROXY protocol vhost on http_port2 and an X-Forwarded-For one