Skip to content

Commit cbf81b4

Browse files
committed
Merge r1919532, r1919533 from trunk:
*) mod_proxy: Avoid AH01059 parsing error for SetHandler "unix:" URLs in <Location> (incomplete fix in 2.4.62). PR 69160. When SetHandler "unix:..." is used in a <Location "/path"> block, the path gets appended (including $DOCUMENT_ROOT somehow) to r->filename hence the current checks in fixup_uds_filename() to add "localhost" when missing don't work. Fix them. mod_proxy: Allow for empty UDS URL hostname in ProxyPass workers too. Using "unix:/udspath|scheme:" or "unix:/udspath|scheme://" for a ProxyPass URL does not work currently, while it works for SetHandler "proxy:unix:...". Submitted by: ylavic Reviewed by: ylavic, covener, rpluem Github: closes #467 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1920977 13f79535-47bb-0310-9956-ffa450edef68
1 parent 5849cf5 commit cbf81b4

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

CHANGES

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
-*- coding: utf-8 -*-
22
Changes with Apache 2.4.63
33

4+
*) mod_proxy: Avoid AH01059 parsing error for SetHandler "unix:" URLs
5+
in <Location> (incomplete fix in 2.4.62). PR 69160. [Yann Ylavic]
6+
47
*) mod_md: update to version 2.4.28
58
- When the server starts, it looks for new, staged certificates to
69
activate. If the staged set of files in 'md/staging/<domain>' is messed

modules/proxy/mod_proxy.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,16 +1948,19 @@ PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
19481948
const char *ret, *c;
19491949

19501950
ret = ptr + 1;
1951-
/* special case: "unix:....|scheme:" is OK, expand
1952-
* to "unix:....|scheme://localhost"
1953-
* */
1951+
/* special cases: "unix:...|scheme:" ind "unix:...|scheme://" are OK,
1952+
* expand to "unix:....|scheme://localhost"
1953+
*/
19541954
c = ap_strchr_c(ret, ':');
19551955
if (c == NULL) {
19561956
return NULL;
19571957
}
19581958
if (c[1] == '\0') {
19591959
return apr_pstrcat(p, ret, "//localhost", NULL);
19601960
}
1961+
else if (c[1] == '/' && c[2] == '/' && !c[3]) {
1962+
return apr_pstrcat(p, ret, "localhost", NULL);
1963+
}
19611964
else {
19621965
return ret;
19631966
}

modules/proxy/proxy_util.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,7 +1972,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
19721972
&& (ptr = ap_strchr_c(url + 5, '|'))) {
19731973
rv = apr_uri_parse(p, apr_pstrmemdup(p, url, ptr - url), &uri);
19741974
if (rv == APR_SUCCESS) {
1975-
sockpath = ap_runtime_dir_relative(p, uri.path);;
1975+
sockpath = ap_runtime_dir_relative(p, uri.path);
19761976
ptr++; /* so we get the scheme for the uds */
19771977
}
19781978
else {
@@ -2038,7 +2038,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
20382038
if (!uri.scheme) {
20392039
return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
20402040
}
2041-
if (!uri.hostname) {
2041+
if (!uri.hostname || !*uri.hostname) {
20422042
if (sockpath) {
20432043
/* allow for unix:/path|http: */
20442044
uri.hostname = "localhost";
@@ -2434,7 +2434,7 @@ static int fixup_uds_filename(request_rec *r)
24342434
if (!strncmp(r->filename, "proxy:", 6) &&
24352435
!ap_cstr_casecmpn(uds_url, "unix:", 5) &&
24362436
(origin_url = ap_strchr(uds_url + 5, '|'))) {
2437-
char *uds_path = NULL, *end;
2437+
char *uds_path = NULL, *col;
24382438
apr_uri_t urisock;
24392439
apr_status_t rv;
24402440

@@ -2446,7 +2446,7 @@ static int fixup_uds_filename(request_rec *r)
24462446
|| !urisock.hostname[0])) {
24472447
uds_path = ap_runtime_dir_relative(r->pool, urisock.path);
24482448
}
2449-
if (!uds_path || !(end = ap_strchr(origin_url, ':'))) {
2449+
if (!uds_path || !(col = ap_strchr(origin_url, ':'))) {
24502450
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292)
24512451
"Invalid proxy UDS filename (%s)", r->filename);
24522452
apr_table_unset(r->notes, "uds_path");
@@ -2459,21 +2459,39 @@ static int fixup_uds_filename(request_rec *r)
24592459
r->filename, origin_url, uds_path);
24602460

24612461
/* The hostname part of the URL is not mandated for UDS though
2462-
* the canon_handler hooks will require it, so add "localhost"
2463-
* if it's missing (won't be used anyway for an AF_UNIX socket).
2462+
* the canon_handler hooks will require it. ProxyPass URLs are
2463+
* fixed at load time by adding "localhost" automatically in the
2464+
* worker URL, but SetHandler "proxy:unix:/udspath|scheme:[//]"
2465+
* URLs are not so we have to fix it here the same way.
24642466
*/
2465-
if (!end[1]) {
2467+
if (!col[1]) {
2468+
/* origin_url is "scheme:" */
24662469
r->filename = apr_pstrcat(r->pool, "proxy:",
24672470
origin_url, "//localhost",
24682471
NULL);
24692472
}
2470-
else if (end[1] == '/' && end[2] == '/' && !end[3]) {
2473+
/* For a SetHandler "proxy:..." in a <Location "/path">, the "/path"
2474+
* is appended to r->filename, hence the below origin_url cases too:
2475+
*/
2476+
else if (col[1] == '/' && (col[2] != '/' /* "scheme:/path" */
2477+
|| col[3] == '/' /* "scheme:///path" */
2478+
|| !col[3])) { /* "scheme://" */
2479+
char *scheme = origin_url;
2480+
*col = '\0'; /* nul terminate scheme */
2481+
if (col[2] != '/') {
2482+
origin_url = col + 1;
2483+
}
2484+
else {
2485+
origin_url = col + 3;
2486+
}
24712487
r->filename = apr_pstrcat(r->pool, "proxy:",
2472-
origin_url, "localhost",
2473-
NULL);
2488+
scheme, "://localhost",
2489+
origin_url, NULL);
24742490
}
24752491
else {
2476-
/* Overwrite the UDS part of r->filename in place */
2492+
/* origin_url is normal "scheme://host/path", can overwrite
2493+
* the UDS part of r->filename in place.
2494+
*/
24772495
memmove(uds_url, origin_url, strlen(origin_url) + 1);
24782496
}
24792497
return OK;

0 commit comments

Comments
 (0)