diff options
author | Eric Covener <covener@apache.org> | 2017-01-11 20:58:33 +0000 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2017-01-11 20:58:33 +0000 |
commit | 728cb09d13b44451594803a9619619a12fc3c2ca (patch) | |
tree | 0e267ad147ba1c5f120aa0a356b30af387aade70 | |
parent | 18e99a8f198e5fd52e222ec80efad11f676105fc (diff) | |
download | httpd-728cb09d13b44451594803a9619619a12fc3c2ca.tar.gz |
PR60576: php-fpm broken w/ per-dir rewrites
Attempt to dig out of well-meaning fixes for generic fcgi backends
that negatively affected some FPM configs.
Adds ProxyFCGIBackendType
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1778350 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | docs/manual/mod/mod_proxy_fcgi.xml | 29 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_fcgi.c | 99 |
3 files changed, 123 insertions, 11 deletions
@@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy_fcgi: Return to 2.4.20-and-earlier behavior of leaving + a "proxy:fcgi://" prefix in the SCRIPT_FILENAME environment variable by + default. Add ProxyFCGIBackendType to allow the type of backend to be + specified so these kinds of fixups can be restored without impacting + FPM. PR60576 [Eric Covener] + *) Don't set SO_REUSEPORT unless ListenCoresBucketsRatio is greater than zero. [Eric Covener] diff --git a/docs/manual/mod/mod_proxy_fcgi.xml b/docs/manual/mod/mod_proxy_fcgi.xml index 30cfb7b306..9cdeddfa8d 100644 --- a/docs/manual/mod/mod_proxy_fcgi.xml +++ b/docs/manual/mod/mod_proxy_fcgi.xml @@ -195,4 +195,33 @@ ProxyPass "/myapp/" "balancer://myappcluster/" </dl> </section> +<directivesynopsis> +<name>ProxyFCGIBackendType</name> +<description>Specify the type of backend FastCGI application</description> +<syntax>ProxyFCGIBackendType FPM|GENERIC</syntax> +<default>ProxyFCGIBackendType FPM</default> +<contextlist><context>server config</context> +<context>virtual host</context><context>directory</context> +<context>.htaccess</context></contextlist> +<compatibility>Available in version 2.5 and later</compatibility> + +<usage> +<p>This directive allows the type of backend FastCGI application to be +specified. Some FastCGI servers, such as PHP-FPM, use historical quirks of +environment variables to identify the type of proxy server being used. Set +this direcive to "GENERIC" if your non PHP-FPM application has trouble +interpreting environment variables such as SCRIPT_FILENAME or PATH_TRANSLATED +as set by the server.</p> + +<p>One example of values that change based on the setting of this directive is +SCRIPT_FILENAME. When using <module>mod_proxy_fcgi</module> historically, +SCRIPT_FILENAME was prefixed with the string "proxy:fcgi://". This variable is +what some generic FastCGI applications would read as their script input, but +PHP-FPM would strip the prefix then remember it was talking to Apache. In +2.4.21 through 2.4.25, this prefix was automatically stripped by the server, +breaking the ability of PHP-FPM to detect and interoperate with Apache in some +scenarios.</p> +</usage> +</directivesynopsis> + </modulesynopsis> diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index 397a1a7782..b291dae341 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -24,6 +24,22 @@ typedef struct { int need_dirwalk; } fcgi_req_config_t; +/* We will assume FPM, but still differentiate */ +typedef enum { + BACKEND_DEFAULT_UNKNOWN = 0, + BACKEND_FPM, + BACKEND_GENERIC, +} fcgi_backend_t; + +#define FCGI_MAY_BE_FPM(dconf) \ + (dconf && \ + ((dconf->backend_type == BACKEND_DEFAULT_UNKNOWN) || \ + (dconf->backend_type == BACKEND_FPM))) + +typedef struct { + fcgi_backend_t backend_type; +} fcgi_dirconf_t; + /* * Canonicalise http-like URLs. * scheme is the scheme for the URL @@ -254,6 +270,7 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r, apr_size_t avail_len, len, required_len; int next_elem, starting_elem; fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module); + fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module); if (rconf) { if (rconf->need_dirwalk) { @@ -268,14 +285,21 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r, if (!strncmp(r->filename, "proxy:balancer://", 17)) { newfname = apr_pstrdup(r->pool, r->filename+17); } - else if (!strncmp(r->filename, "proxy:fcgi://", 13)) { - newfname = apr_pstrdup(r->pool, r->filename+13); - } - /* Query string in environment only */ - if (newfname && r->args && *r->args) { - char *qs = strrchr(newfname, '?'); - if (qs && !strcmp(qs+1, r->args)) { - *qs = '\0'; + + if (!FCGI_MAY_BE_FPM(dconf)) { + if (!strncmp(r->filename, "proxy:fcgi://", 13)) { + /* If we strip this under FPM, and any internal redirect occurs + * on PATH_INFO, FPM may use PATH_TRANSLATED instead of + * SCRIPT_FILENAME (a la mod_fastcgi + Action). + */ + newfname = apr_pstrdup(r->pool, r->filename+13); + } + /* Query string in environment only */ + if (newfname && r->args && *r->args) { + char *qs = strrchr(newfname, '?'); + if (qs && !strcmp(qs+1, r->args)) { + *qs = '\0'; + } } } @@ -976,18 +1000,71 @@ cleanup: return status; } +static void *fcgi_create_dconf(apr_pool_t *p, char *path) +{ + fcgi_dirconf_t *a; + + a = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t)); + a->backend_type = BACKEND_DEFAULT_UNKNOWN; + return a; +} + +static void *fcgi_merge_dconf(apr_pool_t *p, void *basev, void *overridesv) +{ + fcgi_dirconf_t *a, *base, *over; + + a = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t)); + base = (fcgi_dirconf_t *)basev; + over = (fcgi_dirconf_t *)overridesv; + + a->backend_type = (over->backend_type != BACKEND_DEFAULT_UNKNOWN) + ? over->backend_type + : base->backend_type; + return a; +} + + +static const char *cmd_servertype(cmd_parms *cmd, void *in_dconf, + const char *val) +{ + fcgi_dirconf_t *dconf = in_dconf; + + if (!val || !*val) { + return "ProxyFCGIBackendType requires one of the following arguments: " + "'GENERIC', 'PHP-FPM'"; + } + + if (!strcasecmp(val, "GENERIC")) { + dconf->backend_type = BACKEND_GENERIC; + } + else if (!strcasecmp(val, "FPM") || !strcasecmp(val, "PHP-FPM")) { + dconf->backend_type = BACKEND_FPM; + } + else { + return "ProxyFCGIBackendType requires one of the following arguments: " + "'GENERIC', 'PHP-FPM'"; + } + + return NULL; +} + static void register_hooks(apr_pool_t *p) { proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST); proxy_hook_canon_handler(proxy_fcgi_canon, NULL, NULL, APR_HOOK_FIRST); } +static const command_rec command_table[] = { + AP_INIT_TAKE1( "ProxyFCGIBackendType", cmd_servertype, NULL, OR_FILEINFO, + " Specify the type of FastCGI server: 'Generic' 'FPM'"), + { NULL } +}; AP_DECLARE_MODULE(proxy_fcgi) = { STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ + fcgi_create_dconf, /* create per-directory config structure */ + fcgi_merge_dconf, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ - NULL, /* command apr_table_t */ + command_table, /* command apr_table_t */ register_hooks /* register hooks */ }; |