Apache2使用映射的“nph-”CGI发送两个HTTP标头

概要

我试图映射一些文件扩展名由一个nph(非parsing头)CGI可执行文件执行。

比方说,我想要访问一个URL http://server/file.ext并映射“ext”文件扩展名,以“触发”我的nph CGI的执行(/var/www/cgi-bin/nph-test.sh )。

Apacheconfiguration

要做到这一点,我使用mod_actions和mod_cgid,这是我的相关configuration信息:

 <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.shshell:

 #!/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>" 

问题

当我访问nph-test.sh这个URL http://localhost/cgi-bin/nph-test.sh?Hello我得到:

 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 http://localhost/file.ext这样的文件映射时,我得到一个 http头文件(它像nph cgi脚本那样处理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 

我的发现

search了几个小时后,我才发现这个2003年的apache bug报告 。 这也暗示了一个理论上还没有被应用的补丁。

但是search当前的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" 

更新:解决scheme

使用mod_rewrite模块更改configuration以解决问题:

 <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的源代码。 正如你正确的指出,这个bug目前处于重新打开的状态 。

建议的补丁包括两个主要的修改:

  1. 修复nph-detection(这部​​分目前在源代码树中)
  2. 摆脱所有剩余的输出过滤器(源代码树中缺少这个部分)

我无法测试,但我认为可以使用mod_rewrite来解决这个bug:查看mod_rewrite文档似乎工作得很好,用nph

您可以在文档页面找到完整的nph- + mod_rewrite示例