Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BZ-69160: backport to 2.4.x #467

Open
wants to merge 2 commits into
base: 2.4.x
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions changes-entries/pr69160-again.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*) mod_proxy: Avoid AH01059 parsing error for SetHandler "unix:" URLs
in <Location> (incomplete fix in 2.4.62). PR 69160. [Yann Ylavic]
9 changes: 6 additions & 3 deletions modules/proxy/mod_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1948,16 +1948,19 @@ PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
const char *ret, *c;

ret = ptr + 1;
/* special case: "unix:....|scheme:" is OK, expand
* to "unix:....|scheme://localhost"
* */
/* special cases: "unix:...|scheme:" ind "unix:...|scheme://" are OK,
* expand to "unix:....|scheme://localhost"
*/
c = ap_strchr_c(ret, ':');
if (c == NULL) {
return NULL;
}
if (c[1] == '\0') {
return apr_pstrcat(p, ret, "//localhost", NULL);
}
else if (c[1] == '/' && c[2] == '/' && !c[3]) {
return apr_pstrcat(p, ret, "localhost", NULL);
}
else {
return ret;
}
Expand Down
40 changes: 29 additions & 11 deletions modules/proxy/proxy_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1972,7 +1972,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
&& (ptr = ap_strchr_c(url + 5, '|'))) {
rv = apr_uri_parse(p, apr_pstrmemdup(p, url, ptr - url), &uri);
if (rv == APR_SUCCESS) {
sockpath = ap_runtime_dir_relative(p, uri.path);;
sockpath = ap_runtime_dir_relative(p, uri.path);
ptr++; /* so we get the scheme for the uds */
}
else {
Expand Down Expand Up @@ -2038,7 +2038,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
if (!uri.scheme) {
return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
}
if (!uri.hostname) {
if (!uri.hostname || !*uri.hostname) {
if (sockpath) {
/* allow for unix:/path|http: */
uri.hostname = "localhost";
Expand Down Expand Up @@ -2434,7 +2434,7 @@ static int fixup_uds_filename(request_rec *r)
if (!strncmp(r->filename, "proxy:", 6) &&
!ap_cstr_casecmpn(uds_url, "unix:", 5) &&
(origin_url = ap_strchr(uds_url + 5, '|'))) {
char *uds_path = NULL, *end;
char *uds_path = NULL, *col;
apr_uri_t urisock;
apr_status_t rv;

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

/* The hostname part of the URL is not mandated for UDS though
* the canon_handler hooks will require it, so add "localhost"
* if it's missing (won't be used anyway for an AF_UNIX socket).
* the canon_handler hooks will require it. ProxyPass URLs are
* fixed at load time by adding "localhost" automatically in the
* worker URL, but SetHandler "proxy:unix:/udspath|scheme:[//]"
* URLs are not so we have to fix it here the same way.
*/
if (!end[1]) {
if (!col[1]) {
/* origin_url is "scheme:" */
r->filename = apr_pstrcat(r->pool, "proxy:",
origin_url, "//localhost",
NULL);
}
else if (end[1] == '/' && end[2] == '/' && !end[3]) {
/* For a SetHandler "proxy:..." in a <Location "/path">, the "/path"
* is appended to r->filename, hence the below origin_url cases too:
*/
else if (col[1] == '/' && (col[2] != '/' /* "scheme:/path" */
|| col[3] == '/' /* "scheme:///path" */
|| !col[3])) { /* "scheme://" */
char *scheme = origin_url;
*col = '\0'; /* nul terminate scheme */
if (col[2] != '/') {
origin_url = col + 1;
}
else {
origin_url = col + 3;
}
r->filename = apr_pstrcat(r->pool, "proxy:",
origin_url, "localhost",
NULL);
scheme, "://localhost",
origin_url, NULL);
}
else {
/* Overwrite the UDS part of r->filename in place */
/* origin_url is normal "scheme://host/path", can overwrite
* the UDS part of r->filename in place.
*/
memmove(uds_url, origin_url, strlen(origin_url) + 1);
}
return OK;
Expand Down