了解 `mod_rewrite`:在内部将 `foo.txt` 重定向到 `foo.txt.cgi`,其中 `foo.txt` 不存在?
Understanding `mod_rewrite`: internally redirect `foo.txt` to `foo.txt.cgi` where `foo.txt` doesn't exist?
我的目标是从目录中提供 .txt
文件,但是如果特定的 .txt
文件不存在,我想执行 internal 重定向到类似命名的 .txt.cgi
脚本,如果存在这样的脚本。这个问题是关于为什么一种方法似乎有效,但两种替代方法不有效。
我有以下目录结构(即,作为 /var/www
或等效目录中某处的子目录):
% ls -ARl rewritecgi
total 0
drwxr-sr-x 2 posita posita 170 Mar 16 14:36 test1
drwxr-sr-x 2 posita posita 170 Mar 16 14:38 test2
drwxr-sr-x 2 posita posita 170 Mar 16 14:38 test3
rewritecgi/test1:
total 24
-rw-r--r-- 1 posita posita 288 Mar 16 14:36 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:20 test.txt.cgi
rewritecgi/test2:
total 24
-rw-r--r-- 1 posita posita 301 Mar 16 14:38 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:19 test.txt.cgi
rewritecgi/test3:
total 24
-rw-r--r-- 1 posita posita 288 Mar 16 14:38 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:20 test.txt.cgi
每个 test{1,2,3}
子目录中的 other.txt
只是一个纯文本文件。
test.txt.cgi
在每个 test{1,2,3}
子目录中包含:
#!/usr/bin/env sh
cat <<EOF
Content-Type: text/plain
Hi! I'm \`[=15=]\`!
EOF
test1/.htaccess
如下:
Options +FollowSymlinks -Indexes -MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test1/
<Files ~ "\.cgi$">
Options +ExecCGI
</Files>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi"
test2/.htaccess
与 test1/.htaccess
相同,但将 +ExecCGI
移动到顶层(如果我使用 <Files>
,我会得到 403
)并且将 [H=cgi-script]
标志添加到 RewriteRule
:
Options +ExecCGI +FollowSymlinks -Indexes -MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test2/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi" [H=cgi-script]
mod_rewrite
documentation for the H
flag 建议这应该有效。
test3/.htaccess
与 test1/.htaccess
相同,但启用 +MultiViews
选项:
Options +FollowSymlinks -Indexes +MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test3/
<Files ~ "\.cgi$">
Options +ExecCGI
</Files>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi"
毫不奇怪,所有 other.txt
文件都可以毫无问题地解决:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/other.txt" ; done
----> 1 <----
Just a plain old text file.
----> 2 <----
Just a plain old text file.
----> 3 <----
Just a plain old text file.
所有三个 test.txt.cgi
脚本 运行 在显式调用时正确:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/test.txt.cgi" ; done
----> 1 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test1/test.txt.cgi`!
----> 2 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test2/test.txt.cgi`!
----> 3 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test3/test.txt.cgi`!
但是,只有 http://localhost/~posita/rewritecgi/test1/test.txt
重定向到 CGI:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/test.txt" ; done
----> 1 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test1/test.txt.cgi`!
----> 2 <----
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /~posita/rewritecgi/test2/test.txt was not found on this server.</p>
</body></html>
----> 3 <----
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /~posita/rewritecgi/test3/test.txt was not found on this server.</p>
</body></html>
使用 RewriteLogLevel 9
我得到以下 http://localhost/~posita/rewritecgi/test2/test.txt
的日志消息:
==> /var/log/apache2/rewrite_log <==
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] strip per-dir prefix: /.../posita/public_html/rewritecgi/test2/test.txt -> test.txt
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] applying pattern '^(.*\.txt)$' to uri 'test.txt'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) [perdir /.../posita/public_html/rewritecgi/test2/] RewriteCond: input='/.../posita/public_html/rewritecgi/test2/test.txt' pattern='!-f' => matched
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) [perdir /.../posita/public_html/rewritecgi/test2/] RewriteCond: input='/.../posita/public_html/rewritecgi/test2/test.txt' pattern='!-d' => matched
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] rewrite 'test.txt' -> 'test.txt.cgi'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] add per-dir prefix: test.txt.cgi -> /.../posita/public_html/rewritecgi/test2/test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] remember /.../posita/public_html/rewritecgi/test2/test.txt.cgi to have Content-handler 'cgi-script'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] trying to replace prefix /.../posita/public_html/rewritecgi/test2/ with /~posita/rewritecgi/test2/
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (5) strip matching prefix: /.../posita/public_html/rewritecgi/test2/test.txt.cgi -> test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) add subst prefix: test.txt.cgi -> /~posita/rewritecgi/test2/test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (1) [perdir /.../posita/public_html/rewritecgi/test2/] internal redirect with /~posita/rewritecgi/test2/test.txt.cgi [INTERNAL REDIRECT]
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (1) force filename redirect:/~posita/rewritecgi/test2/test.txt.cgi to have the Content-handler 'cgi-script'
==> /var/log/apache2/access_log <==
127.0.0.1 - - [16/Mar/2015:15:30:42 -0700] "GET /~posita/rewritecgi/test2/test.txt HTTP/1.1" 404 229
==> /var/log/apache2/error_log <==
[Mon Mar 16 15:30:42 2015] [error] [client 127.0.0.1] script not found or unable to stat: redirect:/~posita/rewritecgi/test2/test.txt.cgi
对于http://localhost/~posita/rewritecgi/test3/test.txt
:
==> /var/log/apache2/rewrite_log <==
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (3) [perdir /.../posita/public_html/rewritecgi/test3/] strip per-dir prefix: /.../posita/public_html/rewritecgi/test3/test.txt.cgi -> test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (3) [perdir /.../posita/public_html/rewritecgi/test3/] applying pattern '^(.*\.txt)$' to uri 'test.txt.cgi'
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (1) [perdir /.../posita/public_html/rewritecgi/test3/] pass through /.../posita/public_html/rewritecgi/test3/test.txt.cgi
==> /var/log/apache2/access_log <==
127.0.0.1 - - [16/Mar/2015:15:35:47 -0700] "GET /~posita/rewritecgi/test3/test.txt HTTP/1.1" 404 229
==> /var/log/apache2/error_log <==
[Mon Mar 16 15:35:47 2015] [error] [client 127.0.0.1] Negotiation: discovered file(s) matching request: /.../posita/public_html/rewritecgi/test3/test.txt (None could be negotiated).
那么是什么原因呢?为什么添加 [H=cgi-script]
会导致 test2
不调用 CGI?对于 test3
,为什么启用 +MultiViews
会规避 mod_rewrite
?我知道 mod_rewrite
is voodoo,但我真的很想了解这些情况之间的细微差别。
如果在当前目录中找不到文件,Multiviews 是在其他目录中查找文件的选项。这意味着它查找结果不限于同一目录,而不是绕过mod_rewrite。它使用 mod_negotiation。使用选项 Multiviews 让服务器根据模式选择最好的文件。这不是你在使用 .htaccess 和 mod_rewrite 时遇到的情况。我从不使用它。
我注意到的是您的 .htaccess 中的 RewriteConds。它们不是必需的。没有他们,我也能正常工作。您在 .htaccess 中指定的越多,您遇到的问题就越多。 (重写确实是巫术。)
我在没有这些条件的情况下制作了一个 .htaccess 文件并且它有效:
Options +ExecCGI
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /WhosebugQuestions/tests/cgi/
RewriteRule ^(.*)\.txt$ .cgi [L]
这足以使其正常工作。现在 RewriteRule 解析为相同的文件名,只是另一个扩展名,而不是文件名 + 扩展名。
在处理程序标签 [H...] 中,您是否需要指定 cgi 文件的 mime 类型。那是 application/x-httpd-cgi,不是 cgi-script。但是使用AddHandler时不需要指定H-flag。
我的目标是从目录中提供 .txt
文件,但是如果特定的 .txt
文件不存在,我想执行 internal 重定向到类似命名的 .txt.cgi
脚本,如果存在这样的脚本。这个问题是关于为什么一种方法似乎有效,但两种替代方法不有效。
我有以下目录结构(即,作为 /var/www
或等效目录中某处的子目录):
% ls -ARl rewritecgi
total 0
drwxr-sr-x 2 posita posita 170 Mar 16 14:36 test1
drwxr-sr-x 2 posita posita 170 Mar 16 14:38 test2
drwxr-sr-x 2 posita posita 170 Mar 16 14:38 test3
rewritecgi/test1:
total 24
-rw-r--r-- 1 posita posita 288 Mar 16 14:36 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:20 test.txt.cgi
rewritecgi/test2:
total 24
-rw-r--r-- 1 posita posita 301 Mar 16 14:38 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:19 test.txt.cgi
rewritecgi/test3:
total 24
-rw-r--r-- 1 posita posita 288 Mar 16 14:38 .htaccess
-rw-r--r-- 1 posita posita 28 Mar 16 14:34 other.txt
-rwxr-xr-x 1 posita posita 143 Mar 16 14:20 test.txt.cgi
每个 test{1,2,3}
子目录中的 other.txt
只是一个纯文本文件。
test.txt.cgi
在每个 test{1,2,3}
子目录中包含:
#!/usr/bin/env sh
cat <<EOF
Content-Type: text/plain
Hi! I'm \`[=15=]\`!
EOF
test1/.htaccess
如下:
Options +FollowSymlinks -Indexes -MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test1/
<Files ~ "\.cgi$">
Options +ExecCGI
</Files>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi"
test2/.htaccess
与 test1/.htaccess
相同,但将 +ExecCGI
移动到顶层(如果我使用 <Files>
,我会得到 403
)并且将 [H=cgi-script]
标志添加到 RewriteRule
:
Options +ExecCGI +FollowSymlinks -Indexes -MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test2/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi" [H=cgi-script]
mod_rewrite
documentation for the H
flag 建议这应该有效。
test3/.htaccess
与 test1/.htaccess
相同,但启用 +MultiViews
选项:
Options +FollowSymlinks -Indexes +MultiViews
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /~posita/rewritecgi/test3/
<Files ~ "\.cgi$">
Options +ExecCGI
</Files>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*\.txt)$" ".cgi"
毫不奇怪,所有 other.txt
文件都可以毫无问题地解决:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/other.txt" ; done
----> 1 <----
Just a plain old text file.
----> 2 <----
Just a plain old text file.
----> 3 <----
Just a plain old text file.
所有三个 test.txt.cgi
脚本 运行 在显式调用时正确:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/test.txt.cgi" ; done
----> 1 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test1/test.txt.cgi`!
----> 2 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test2/test.txt.cgi`!
----> 3 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test3/test.txt.cgi`!
但是,只有 http://localhost/~posita/rewritecgi/test1/test.txt
重定向到 CGI:
% for i in 1 2 3 ; do echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/test.txt" ; done
----> 1 <----
Hi! I'm `/.../posita/public_html/rewritecgi/test1/test.txt.cgi`!
----> 2 <----
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /~posita/rewritecgi/test2/test.txt was not found on this server.</p>
</body></html>
----> 3 <----
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /~posita/rewritecgi/test3/test.txt was not found on this server.</p>
</body></html>
使用 RewriteLogLevel 9
我得到以下 http://localhost/~posita/rewritecgi/test2/test.txt
的日志消息:
==> /var/log/apache2/rewrite_log <==
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] strip per-dir prefix: /.../posita/public_html/rewritecgi/test2/test.txt -> test.txt
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] applying pattern '^(.*\.txt)$' to uri 'test.txt'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) [perdir /.../posita/public_html/rewritecgi/test2/] RewriteCond: input='/.../posita/public_html/rewritecgi/test2/test.txt' pattern='!-f' => matched
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) [perdir /.../posita/public_html/rewritecgi/test2/] RewriteCond: input='/.../posita/public_html/rewritecgi/test2/test.txt' pattern='!-d' => matched
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] rewrite 'test.txt' -> 'test.txt.cgi'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (3) [perdir /.../posita/public_html/rewritecgi/test2/] add per-dir prefix: test.txt.cgi -> /.../posita/public_html/rewritecgi/test2/test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] remember /.../posita/public_html/rewritecgi/test2/test.txt.cgi to have Content-handler 'cgi-script'
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (2) [perdir /.../posita/public_html/rewritecgi/test2/] trying to replace prefix /.../posita/public_html/rewritecgi/test2/ with /~posita/rewritecgi/test2/
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (5) strip matching prefix: /.../posita/public_html/rewritecgi/test2/test.txt.cgi -> test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (4) add subst prefix: test.txt.cgi -> /~posita/rewritecgi/test2/test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (1) [perdir /.../posita/public_html/rewritecgi/test2/] internal redirect with /~posita/rewritecgi/test2/test.txt.cgi [INTERNAL REDIRECT]
127.0.0.1 - - [16/Mar/2015:15:30:42 --0700] [localhost/sid#7fb378812308][rid#7fb3788abea0/initial] (1) force filename redirect:/~posita/rewritecgi/test2/test.txt.cgi to have the Content-handler 'cgi-script'
==> /var/log/apache2/access_log <==
127.0.0.1 - - [16/Mar/2015:15:30:42 -0700] "GET /~posita/rewritecgi/test2/test.txt HTTP/1.1" 404 229
==> /var/log/apache2/error_log <==
[Mon Mar 16 15:30:42 2015] [error] [client 127.0.0.1] script not found or unable to stat: redirect:/~posita/rewritecgi/test2/test.txt.cgi
对于http://localhost/~posita/rewritecgi/test3/test.txt
:
==> /var/log/apache2/rewrite_log <==
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (3) [perdir /.../posita/public_html/rewritecgi/test3/] strip per-dir prefix: /.../posita/public_html/rewritecgi/test3/test.txt.cgi -> test.txt.cgi
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (3) [perdir /.../posita/public_html/rewritecgi/test3/] applying pattern '^(.*\.txt)$' to uri 'test.txt.cgi'
127.0.0.1 - - [16/Mar/2015:15:35:47 --0700] [localhost/sid#7fb378812308][rid#7fb37889aea0/subreq] (1) [perdir /.../posita/public_html/rewritecgi/test3/] pass through /.../posita/public_html/rewritecgi/test3/test.txt.cgi
==> /var/log/apache2/access_log <==
127.0.0.1 - - [16/Mar/2015:15:35:47 -0700] "GET /~posita/rewritecgi/test3/test.txt HTTP/1.1" 404 229
==> /var/log/apache2/error_log <==
[Mon Mar 16 15:35:47 2015] [error] [client 127.0.0.1] Negotiation: discovered file(s) matching request: /.../posita/public_html/rewritecgi/test3/test.txt (None could be negotiated).
那么是什么原因呢?为什么添加 [H=cgi-script]
会导致 test2
不调用 CGI?对于 test3
,为什么启用 +MultiViews
会规避 mod_rewrite
?我知道 mod_rewrite
is voodoo,但我真的很想了解这些情况之间的细微差别。
如果在当前目录中找不到文件,Multiviews 是在其他目录中查找文件的选项。这意味着它查找结果不限于同一目录,而不是绕过mod_rewrite。它使用 mod_negotiation。使用选项 Multiviews 让服务器根据模式选择最好的文件。这不是你在使用 .htaccess 和 mod_rewrite 时遇到的情况。我从不使用它。
我注意到的是您的 .htaccess 中的 RewriteConds。它们不是必需的。没有他们,我也能正常工作。您在 .htaccess 中指定的越多,您遇到的问题就越多。 (重写确实是巫术。) 我在没有这些条件的情况下制作了一个 .htaccess 文件并且它有效:
Options +ExecCGI
AddHandler cgi-script .cgi
RewriteEngine on
RewriteBase /WhosebugQuestions/tests/cgi/
RewriteRule ^(.*)\.txt$ .cgi [L]
这足以使其正常工作。现在 RewriteRule 解析为相同的文件名,只是另一个扩展名,而不是文件名 + 扩展名。 在处理程序标签 [H...] 中,您是否需要指定 cgi 文件的 mime 类型。那是 application/x-httpd-cgi,不是 cgi-script。但是使用AddHandler时不需要指定H-flag。