apache - Understanding `mod_rewrite`: internally redirect `foo.txt` to `foo.txt.cgi` where `foo.txt` doesn't exist? -


my goal serve .txt files out of directory, particular .txt file not exist, want perform internal redirect named .txt.cgi script, if such script exists. question pertains why 1 approach seems work, 2 alternate approaches not work.

i have following directory structure (i.e., subdirectory somewhere in /var/www or equivalent):

% 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 

other.txt in each test{1,2,3} subdirectory plain old text file.

test.txt.cgi in each test{1,2,3} subdirectory contains:

#!/usr/bin/env sh cat <<eof content-type: text/plain  hi! i'm \`${0}\`! eof 

test1/.htaccess follows:

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)$" "$1.cgi" 

test2/.htaccess same test1/.htaccess, moves +execcgi top level (i 403 if use <files>) , adds [h=cgi-script] flag 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)$" "$1.cgi" [h=cgi-script] 

the mod_rewrite documentation h flag suggests should work.

test3/.htaccess same test1/.htaccess, enables +multiviews option:

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)$" "$1.cgi" 

unsurprisingly, of other.txt files resolve without issue:

% in 1 2 3 ; echo "----> ${i} <----" ; curl --location --post30{1,2,3} --silent "http://localhost/~posita/rewritecgi/test${i}/other.txt" ; done ----> 1 <---- plain old text file. ----> 2 <---- plain old text file. ----> 3 <---- plain old text file. 

all 3 test.txt.cgi scripts run when called explicitly:

% in 1 2 3 ; 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`! 

however, http://localhost/~posita/rewritecgi/test1/test.txt redirects cgi:

% in 1 2 3 ; 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 not found on 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 not found on server.</p> </body></html> 

with rewriteloglevel 9 following log messages 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)$' 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 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 replace prefix /.../posita/public_html/rewritecgi/test2/ /~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 /~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 have 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 stat: redirect:/~posita/rewritecgi/test2/test.txt.cgi 

and 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)$' 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 negotiated). 

so gives? why adding [h=cgi-script] cause test2 not call cgi? test3, why enabling +multiviews circumvent mod_rewrite? know mod_rewrite voodoo, want understand nuances between these situations.

multiviews option files in other directories if not found in current one. implies finding results not restricted same directory, not circumvents mod_rewrite. uses mod_negotiation. using option multiviews let server choose, based on pattern best file chose. not situation imo after when using .htaccess , mod_rewrite. never use it.

what noticed rewriteconds in .htaccess. not required. got working without them. more specify in .htaccess, more problems can have. (rewrite can voodoo indeed.) made .htaccess file without conditions , worked:

options +execcgi addhandler cgi-script .cgi rewriteengine on rewritebase /stackoverflowquestions/tests/cgi/ rewriterule ^(.*)\.txt$ $1.cgi [l] 

that enough make working. rewriterule resolving same filename extension , not filename + extension. in handler tag [h...] need specify mime-type of cgi file. application/x-httpd-cgi, not cgi-script. not need specify h-flag when use addhandler.


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

ios - Possible to get UIButton sizeThatFits to work? -