Apache2发送两个带有映射的"nph-" HTTP头. CGI [英] Apache2 sends two HTTP headers with a mapped "nph-" CGI
问题描述
摘要
我正在尝试映射一些文件扩展名,以由nph(非解析头)CGI可执行文件执行.
假设我要访问URL http://server/file.ext
,并将"ext"文件扩展名映射为触发"执行我的nph CGI(/var/www/cgi-bin/nph-test.sh)./p>
Apache配置
为此,我正在使用mod_actions和mod_cgid,这是我的相关配置信息:
<VirtualHost *:80>
DocumentRoot /var/www/htdocs
ScriptAlias /cgi-bin /var/www/cgi-bin
Action cgi-wrapper /cgi-bin/nph-test.sh
AddHandler cgi-wrapper .ext
</VirtualHost>
NPH CGI脚本
这是我的nph-test.sh shell:
#!/bin/sh
echo "HTTP/1.0 200 OK"
echo "Server: Shell/1.0"
echo "Status: 200 \"OK\""
echo "Connection: close"
echo "Content-type: text/html"
echo ""
echo "<html><body><pre>"
echo "QUERY_STRING = "${QUERY_STRING}
echo "PATH_TRANSLATED = "${PATH_TRANSLATED}
echo "</pre></body></html>"
问题
当我使用此URL http://localhost/cgi-bin/nph-test.sh?Hello
访问nph-test.sh时,我得到:
HTTP/1.0 200 OK
Server: Shell/1.0
Status: 200 "OK"
Connection: close
Content-type: text/html
<html><body><pre>
QUERY_STRING = Hello
PATH_TRANSLATED =
</pre></body></html>
使用此URL中的文件映射时出现问题,该URL http://localhost/file.ext
我得到一个 double http标头(将nph cgi脚本视为 non nph cgi脚本):
HTTP/1.0 200 OK
Server: Shell/1.0
Status: 200 "OK"
Connection: close
Content-type: text/html
<html><body><pre>
QUERY_STRING =
PATH_TRANSLATED = /var/www/htdocs/file.ext
</pre></body></html>
HTTP/1.1 200 OK^M
Date: Tue, 18 Mar 2014 14:32:29 GMT^M
Server: Apache/2.4.6 (Ubuntu)^M
Content-Length: 0^M
Keep-Alive: timeout=5, max=100^M
Connection: Keep-Alive^M
Content-Type: text/x-sh^M
^M
我的发现
经过几个小时的搜索,我只找到了 2003年Apache错误报告.这也暗示了理论上尚未应用的补丁.
但是搜索当前的 mod_cgid源代码 我可以看到代码已更改为能够捕获"nph-" cgi文件前缀(strrchr):
1372 if ((argv0 = strrchr(r->filename, '/')) != NULL) {
1373 argv0++;
1374 }
1375 else {
1376 argv0 = r->filename;
1377 }
1378
1379 nph = !(strncmp(argv0, "nph-", 4));
问题
apache2是否可以将文件扩展名映射到nph cgi? (不返回两个http标头)
还有其他方法可以解决此问题吗?
Apache和OS服务器信息
我正在使用Ubuntu 13.10中的默认apache2服务器:
# apachectl -V
Server version: Apache/2.4.6 (Ubuntu)
Server built: Dec 5 2013 18:32:22
Server's Module Magic Number: 20120211:23
Server loaded: APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="mime.types"
-D SERVER_CONFIG_FILE="apache2.conf"
更新:解决方案
更改的配置以使用mod_rewrite模块解决问题:
<VirtualHost *:80>
DocumentRoot /var/www/htdocs
ScriptAlias /cgi-bin /var/www/cgi-bin
RewriteEngine on
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/?(.*\.ext)$ /cgi-bin/nph-test.sh?$1 [PT]
RewriteRule ^/?(.*\.ext)$ /cgi-bin/nph-test.sh?$1&%{QUERY_STRING} [PT]
</VirtualHost>
我认为2.4.x源代码上不可能(直接)实现. 如您正确指出的那样,该错误当前处于<a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=22898" rel="nofollow">重新打开的状态.>
建议的补丁程序包含两个主要修改:
- 修复nph检测(该部分当前在源代码树中)
- 摆脱所有剩余的输出过滤器(这部分在源代码树中是 missing )
我无法测试,但是我认为可以使用mod_rewrite解决此错误: 查看mod_rewrite文档似乎可以很好地与 nph
您可以在文档页面中找到完整的nph- + mod_rewrite示例
Summary
I'm trying to map some file extensions to be executed by a nph (Non Parsed Header) CGI executable.
Let's say I want to access a URL http://server/file.ext
and map the "ext" file extension to "trigger" the execution of my nph CGI (/var/www/cgi-bin/nph-test.sh).
Apache configuration
To do that I'm using mod_actions and mod_cgid, this is my relevant configuration information:
<VirtualHost *:80>
DocumentRoot /var/www/htdocs
ScriptAlias /cgi-bin /var/www/cgi-bin
Action cgi-wrapper /cgi-bin/nph-test.sh
AddHandler cgi-wrapper .ext
</VirtualHost>
NPH CGI script
This is my nph-test.sh shell:
#!/bin/sh
echo "HTTP/1.0 200 OK"
echo "Server: Shell/1.0"
echo "Status: 200 \"OK\""
echo "Connection: close"
echo "Content-type: text/html"
echo ""
echo "<html><body><pre>"
echo "QUERY_STRING = "${QUERY_STRING}
echo "PATH_TRANSLATED = "${PATH_TRANSLATED}
echo "</pre></body></html>"
Problem
When I access nph-test.sh with this URL http://localhost/cgi-bin/nph-test.sh?Hello
I get:
HTTP/1.0 200 OK
Server: Shell/1.0
Status: 200 "OK"
Connection: close
Content-type: text/html
<html><body><pre>
QUERY_STRING = Hello
PATH_TRANSLATED =
</pre></body></html>
The problem appears when using the file mapping like in this URL http://localhost/file.ext
I get a double http header (it's treating the nph cgi script like a non nph cgi script):
HTTP/1.0 200 OK
Server: Shell/1.0
Status: 200 "OK"
Connection: close
Content-type: text/html
<html><body><pre>
QUERY_STRING =
PATH_TRANSLATED = /var/www/htdocs/file.ext
</pre></body></html>
HTTP/1.1 200 OK^M
Date: Tue, 18 Mar 2014 14:32:29 GMT^M
Server: Apache/2.4.6 (Ubuntu)^M
Content-Length: 0^M
Keep-Alive: timeout=5, max=100^M
Connection: Keep-Alive^M
Content-Type: text/x-sh^M
^M
My findings
After searching for some hours I only found this 2003 apache bug report. Which also suggests a patch that in theory has not being applied.
But searching the current mod_cgid source code I can see that the code has been changed to be able to capture the "nph-" cgi file prefix (strrchr):
1372 if ((argv0 = strrchr(r->filename, '/')) != NULL) {
1373 argv0++;
1374 }
1375 else {
1376 argv0 = r->filename;
1377 }
1378
1379 nph = !(strncmp(argv0, "nph-", 4));
Question
Is there a way with apache2 to map a file extension to a nph cgi? (without returning two http headers)
Are there other ways to do that or any workarounds?
Apache and OS server information
I'm using the default apache2 server in Ubuntu 13.10:
# apachectl -V
Server version: Apache/2.4.6 (Ubuntu)
Server built: Dec 5 2013 18:32:22
Server's Module Magic Number: 20120211:23
Server loaded: APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="mime.types"
-D SERVER_CONFIG_FILE="apache2.conf"
Update: Solution
The changed configuration to solve the problem using the mod_rewrite module:
<VirtualHost *:80>
DocumentRoot /var/www/htdocs
ScriptAlias /cgi-bin /var/www/cgi-bin
RewriteEngine on
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/?(.*\.ext)$ /cgi-bin/nph-test.sh?$1 [PT]
RewriteRule ^/?(.*\.ext)$ /cgi-bin/nph-test.sh?$1&%{QUERY_STRING} [PT]
</VirtualHost>
I don't think it's possible (directly) on the 2.4.x source code. As you correctly pointed out the bug is currently in reopened status.
The proposed patch consists of two main modification:
- Fix the nph- detection (and this part is currently in the source tree)
- Getting rid of all remaining output filters (this part is missing in the source tree)
I'm not able to test, but I think it's possible to workaround this bug using mod_rewrite: Looking in mod_rewrite documentation seems working just fine with nph
You can find a complete nph- + mod_rewrite example in documentation page
这篇关于Apache2发送两个带有映射的"nph-" HTTP头. CGI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!