问题
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>
回答1:
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
来源:https://stackoverflow.com/questions/22483281/apache2-sends-two-http-headers-with-a-mapped-nph-cgi