/* * Canonicalize scgi-like URLs. */ static int scgi_canon(request_rec *r, char *url) { char *host, sport[sizeof(":65535")]; const char *err, *path; apr_port_t port = SCGI_DEFAULT_PORT; if (strncasecmp(url, SCHEME "://", sizeof(SCHEME) + 2)) { return DECLINED; } url += sizeof(SCHEME); /* Keep slashes */ err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "error parsing URL %s: %s", url, err); return HTTP_BAD_REQUEST; } apr_snprintf(sport, sizeof(sport), ":%u", port); if (ap_strchr(host, ':')) { /* if literal IPv6 address */ host = apr_pstrcat(r->pool, "[", host, "]", NULL); } path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); if (!path) { return HTTP_BAD_REQUEST; } r->filename = apr_pstrcat(r->pool, "proxy:" SCHEME "://", host, sport, "/", path, NULL); r->path_info = apr_pstrcat(r->pool, "/", path, NULL); return OK; }
/* * Canonicalise http-like URLs. * scheme is the scheme for the URL * url is the URL starting with the first '/' * def_port is the default port for this scheme. */ static int proxy_ajp_canon(request_rec *r, char *url) { char *host, *path, sport[7]; char *search = NULL; const char *err; apr_port_t port = AJP13_DEF_PORT; /* ap_port_of_scheme() */ if (strncasecmp(url, "ajp:", 4) == 0) { url += 4; } else { return DECLINED; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: AJP: canonicalising URL %s", url); /* * do syntactic check. * We break the URL into host, port, path, search */ err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "error parsing URL %s: %s", url, err); return HTTP_BAD_REQUEST; } /* * now parse path/search args, according to rfc1738: * process the path. With proxy-noncanon set (by * mod_proxy) we use the raw, unparsed uri */ if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); search = r->args; } if (path == NULL) return HTTP_BAD_REQUEST; apr_snprintf(sport, sizeof(sport), ":%d", port); if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ host = apr_pstrcat(r->pool, "[", host, "]", NULL); } r->filename = apr_pstrcat(r->pool, "proxy:ajp://", host, sport, "/", path, (search) ? "?" : "", (search) ? search : "", NULL); return OK; }
static int proxy_balancer_canon(request_rec *r, char *url) { char *host, *path; char *search = NULL; const char *err; apr_port_t port = 0; if (strncasecmp(url, "balancer:", 9) == 0) { url += 9; } else { return DECLINED; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: BALANCER: canonicalising URL %s", url); /* do syntatic check. * We break the URL into host, port, path, search */ err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "error parsing URL %s: %s", url, err); return HTTP_BAD_REQUEST; } /* * now parse path/search args, according to rfc1738: * process the path. With proxy-noncanon set (by * mod_proxy) we use the raw, unparsed uri */ if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); search = r->args; } if (path == NULL) return HTTP_BAD_REQUEST; r->filename = apr_pstrcat(r->pool, "proxy:balancer://", host, "/", path, (search) ? "?" : "", (search) ? search : "", NULL); return OK; }
/* * Canonicalise http-like URLs. * scheme is the scheme for the URL * url is the URL starting with the first '/' * def_port is the default port for this scheme. */ int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, int def_port) { char *host, *path, *search, sport[7]; const char *err; int port; /* * do syntatic check. We break the URL into host, port, path, search */ port = def_port; err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) return HTTP_BAD_REQUEST; /* now parse path/search args, according to rfc1738 */ /* * N.B. if this isn't a true proxy request, then the URL _path_ has * already been decoded. True proxy requests have r->uri == * r->unparsed_uri, and no others have that property. */ if (r->uri == r->unparsed_uri) { search = strchr(url, '?'); if (search != NULL) *(search++) = '\0'; } else search = r->args; /* process path */ path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq); if (path == NULL) return HTTP_BAD_REQUEST; if (port != def_port) ap_snprintf(sport, sizeof(sport), ":%d", port); else sport[0] = '\0'; r->filename = ap_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, "/", path, (search) ? "?" : "", (search) ? search : "", NULL); return OK; }
/* * Canonicalise http-like URLs. * scheme is the scheme for the URL * url is the URL starting with the first '/' * def_port is the default port for this scheme. */ static int proxy_fcgi_canon(request_rec *r, char *url) { char *host, sport[7]; const char *err; char *path; apr_port_t port, def_port; fcgi_req_config_t *rconf = NULL; const char *pathinfo_type = NULL; if (strncasecmp(url, "fcgi:", 5) == 0) { url += 5; } else { return DECLINED; } port = def_port = ap_proxy_port_of_scheme("fcgi"); ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "canonicalising URL %s", url); err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); if (err) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01059) "error parsing URL %s: %s", url, err); return HTTP_BAD_REQUEST; } if (port != def_port) apr_snprintf(sport, sizeof(sport), ":%d", port); else sport[0] = '\0'; if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ host = apr_pstrcat(r->pool, "[", host, "]", NULL); } if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); } if (path == NULL) return HTTP_BAD_REQUEST; r->filename = apr_pstrcat(r->pool, "proxy:fcgi://", host, sport, "/", path, NULL); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01060) "set r->filename to %s", r->filename); rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module); if (rconf == NULL) { rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t)); ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf); } if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) { /* It has to be on disk for this to work */ if (!strcasecmp(pathinfo_type, "full")) { rconf->need_dirwalk = 1; ap_unescape_url_keep2f(path, 0); } else if (!strcasecmp(pathinfo_type, "first-dot")) { char *split = ap_strchr(path, '.'); if (split) { char *slash = ap_strchr(split, '/'); if (slash) { r->path_info = apr_pstrdup(r->pool, slash); ap_unescape_url_keep2f(r->path_info, 0); *slash = '\0'; /* truncate path */ } } } else if (!strcasecmp(pathinfo_type, "last-dot")) { char *split = ap_strrchr(path, '.'); if (split) { char *slash = ap_strchr(split, '/'); if (slash) { r->path_info = apr_pstrdup(r->pool, slash); ap_unescape_url_keep2f(r->path_info, 0); *slash = '\0'; /* truncate path */ } } } else { /* before proxy-fcgi-pathinfo had multi-values. This requires the * the FCGI server to fixup PATH_INFO because it's the entire path */ r->path_info = apr_pstrcat(r->pool, "/", path, NULL); if (!strcasecmp(pathinfo_type, "unescape")) { ap_unescape_url_keep2f(r->path_info, 0); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061) "set r->path_info to %s", r->path_info); } } return OK; }