简介: Apache 2.4的mod_proxy似乎没有将Authorization标头传递给PHP-FPM.有没有什么办法解决这一问题?
长版: 我正在使用Apache 2.4和PHP-FPM运行服务器.我正在使用APC进行操作码缓存和用户缓存.根据Internet的建议,我使用Apache 2.4的mod_proxy_fcgi来代理对FPM的请求,如下所示:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/foo/bar/$1
Run Code Online (Sandbox Code Playgroud)
安装工作正常,除了一件事:APC捆绑的apc.php,用于监控APC的状态不允许我登录(查看用户缓存条目所需).当我单击"用户缓存条目"以查看用户缓存时,它会要求我登录,单击登录按钮会显示通常的HTTP登录表单,但输入正确的登录名和密码不会成功.当使用mod_php而不是mod_proxy + php-fpm运行时,此函数运行正常.
经过一些谷歌搜索,我发现其他人有同样的问题,并发现这是因为Apache没有将授权HTTP标头传递给外部FastCgi进程.不幸的是我只找到了mod_fastcgi的修复程序,它看起来像这样:
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
Run Code Online (Sandbox Code Playgroud)
有没有相同的设置或一些解决方法,也适用于mod_proxy_fcgi?
我正在一个运行在共享Apache v2.2服务器上的网站上工作,因此所有配置都是通过.htaccess文件进行的,我想使用mod_rewrite以不太完全直接的方式将URL映射到文件系统.举个例子,让我们说我想做的是:
www.mysite.com/Alice到filesystem文件夹/public_html/Bobwww.mysite.com/Bob到filesystem文件夹/public_html/Alice现在,经过几个小时的工作,仔细设计规则集(真正的规则集,而不是Alice/Bob的规则集!)我将所有精心设计的重写规则放在/ public_html中的.htaccess文件中,然后对其进行测试... 500服务器错误!
我被一个记录良好的"陷阱"所困扰!在Apache中:当在.htaccess文件中使用mod_rewrite规则时,重新提交重写的URL 以进行另一轮处理(就像它是外部请求一样).这样就可以应用重写请求的目标文件夹中的任何规则,但它可能会导致网络服务器出现一些非常违反直觉的行为!
在上面的示例中,这意味着请求www.mysite.com/Alice/foo.html被重写/Bob/foo.html,然后作为请求重新提交(内部)到服务器www.mysite.com/Bob/foo.html.然后重新重新写入/Alice/foo.html并重新提交,这会导致重新重写/Bob/foo.html,等等; 随之而来的是无限循环...仅由服务器超时错误破坏.
RewriteRule中的[L]标志在单次通过规则集期间停止所有进一步的重写,但在重新提交重新提交到服务器之后不会停止重新应用整个规则集.根据文档,Apache v2.3.9 +(目前处于Beta版)包含一个[END]标志,可以精确地提供此功能.不幸的是,网络主机仍在使用Apache 2.2,他们拒绝我的礼貌请求升级到测试版!
我们需要的是一种解决方法,它提供与[END]标志类似的功能.我的第一个想法是我可以使用一个环境变量:在第一次重写过程中设置一个标志,告诉后续的传递不再进行重写.如果我调用我的标志变量'END',代码可能如下所示:
# Prevent further rewriting if 'END' is flagged
RewriteCond %{ENV:END} =1
RewriteRule .* - [L]
# Map /Alice to /Bob, and /Bob to /Alice, and flag 'END' when done
RewriteRule ^Alice(/.*)?$ Bob$1 [L,E=END:1]
RewriteRule ^Bob(/.*)?$ Alice$1 [L,E=END:1]
Run Code Online (Sandbox Code Playgroud)
不幸的是,这段代码不起作用:经过一些实验,我发现环境变量在重新提交重写的URL到服务器的过程中无法生存.这个Apache文档页面的最后一行表明环境变量 …
我试图将.htaccess中的环境变量传递给PHP.这在我的本地WAMP服务器上运行得很好,但在托管我的网站的服务器上,它无故失败.
这是我的测试配置:
的.htaccess:
SetEnv TEST_VARIABLE test_value
Run Code Online (Sandbox Code Playgroud)
test.php的:
<pre>
getenv('TEST_VARIABLE') = <?php print getenv('TEST_VARIABLE'); ?>
getenv('REDIRECT_TEST_VARIABLE') = <?php print getenv('REDIRECT_TEST_VARIABLE'); ?>
</pre>
Run Code Online (Sandbox Code Playgroud)
在我的本地服务器上,正确返回test.php:
getenv('TEST_VARIABLE') = test_value
getenv('REDIRECT_TEST_VARIABLE') =
Run Code Online (Sandbox Code Playgroud)
但是在生产服务器上,它返回:
getenv('TEST_VARIABLE') =
getenv('REDIRECT_TEST_VARIABLE') =
Run Code Online (Sandbox Code Playgroud)
我已经排除的事情:
mod_env主机未安装/启用.不能,因为那时候SetEnv不会被识别,我在处理.htaccess时会得到500.
AllowOverrides在httpd.conf这个目录中不包括FileInfo.不可能,因为当遇到SetEnv指令时,Apache会抛出一个错误"SetEnv不允许在这里" ,我会再次获得500.
variables_order在php.ini中不包含'E'.这可以解释$_ENV超全局是空的(它是),但不是为什么getenv()不返回这些变量的值.
整个环境搞砸了.不能,因为getenv('PATH')和getenv('SERVER_NAME')仍然返回有效值.
在这一点上,我不知道是什么配置可能导致这一点.
我的Web应用程序结构是:
/var/www/myapp/
- www/
- index.php
- css.php
- .htaccess
Run Code Online (Sandbox Code Playgroud)
虚拟主机配置为:
<VirtualHost *:80>
ServerName www.example.org
DocumentRoot /var/www/myapp/www
DirectoryIndex index.php index.html
<Directory /var/www/myapp/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
在/var/www/myapp/www/.htaccess中有:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule css css.php [L,NC]
RewriteRule .* index.php
</IfModule>
Run Code Online (Sandbox Code Playgroud)
现在,如果我打电话给www.example.org,我正确地重定向到index.php,但是如果我打电话给www.example.org/css,我仍然会被重定向到index.php.
如果我删除"RewriteRule.*index.php"行,然后调用www.example.org/css,我正确地重定向到css.php.
怎么了?非常感谢
========编辑=========
192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add path info postfix: /var/www/sviluppo/mattia_dev/example/www/DEV_2 -> /var/www/sviluppo/mattia_dev/example/www/DEV_2/css/example1/test.css
192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip …Run Code Online (Sandbox Code Playgroud) 当一个特定的env变量没有被前一个"RewriteRule"设置时,我只想跳过用"RewriteRule"完成的重定向.
这是我的例子,它不起作用.
RewriteEngine on
RewriteBase /
#
# if /internal ... set ENV var INTERNALAREA = true
#
RewriteRule ^internal(.*)$ - [E=INTERNALAREA:true]
#
# Redirect to /maintenance.php if not in internal area and not already at /maintenance.php
#
RewriteCond %{ENV:INTERNALAREA} !true
RewriteCond %{REQUEST_URI} !^/maintenance.php$
RewriteRule ^(.*)$ /maintenance.php [R=302,L]
#
# Default TYPO3 rewrites
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ $1.$3 [L]
RewriteRule ^fileadmin/(.*/)?_recycler_/ - [F]
RewriteRule ^fileadmin/templates/.*(\.txt|\.ts)$ - [F]
RewriteRule ^typo3conf/ext/[^/]+/Resources/Private/ - [F]
RewriteRule ^(typo3/|t3lib/|fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) …Run Code Online (Sandbox Code Playgroud) 我们正在尝试在我们的登台环境中设置并行运行的多个 PHP 版本。为了实现这一点,我构建了所有相关的 PHP 二进制文件(在适用的情况下使用 --enable-fastcgi)并使用 mod_fastcgi 通过包装脚本调用前者。
如果相关,这里是/php-fcgi/php-5.5:
#!/bin/sh
PHPRC=/usr/local/php55/etc/php.ini
export PHPRC
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN
exec /usr/local/php55/bin/php-cgi
Run Code Online (Sandbox Code Playgroud)
到目前为止一切正常(即所有配置为运行 PHP 5.5 的虚拟主机都在 5.5 上运行,等等);然而,在<Directory>块中使用“SetEnv”设置的环境变量存在问题。所有这些都以REDIRECT_.
示例:
SetEnv APPLICATION_ENV "production"
Run Code Online (Sandbox Code Playgroud)
将导致此输出:
'REDIRECT_APPLICATION_ENV' => string 'production'
Run Code Online (Sandbox Code Playgroud)
任何人都可以就我做错了什么提出建议吗?
澄清为什么这与 mod_rewrite 无关:即使完全禁用 mod_rewrite 也会发生这种行为。