Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite and the default document

Getting a rule to work all the time.

         

Gibble

2:49 pm on Jul 17, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, I have the following rule which proxies any asp page requests to my IIS server running on port 81.

RewriteEngine on
RewriteRule (.*\.asp) [192.168.0.102:81...] [P]

The problem, is that if the URL is [localhost...] and the default document is index.asp that gets loaded, the rule doesn't work, since "index.asp" isn't specifically in the URL.

I need the rules to work when the default document that has been loaded is *.asp, but not when it's *.php, or *.htm.

Ideas? Suggesstions? Help!

jdMorgan

5:24 pm on Jul 17, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Where is this code located?

What determines "when the default document that [will be] loaded is *.asp, but not [...] *.php, or *.htm"?

RewriteRule sees only URLs, not filenames. If some other mechanism (such as DirectoryIndex) is used to change the URL-to-filename mapping, then RewriteRule won't see it. If, however, this is done on the same server where the rule is running (not on the back-end proxied server), then you may be able to use a look-ahead to detect it.

Jim

Gibble

6:43 pm on Jul 17, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I set the default with DirectoryIndex in the httpd.conf file.

DirectoryIndex index.php index.html index.htm index.asp

jdMorgan

11:24 pm on Jul 17, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Again: Where is this code located?

Gibble

1:52 pm on Jul 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It's all on the Apache "front-end" server.

I have the rewrite rule in my httpd.conf so it's global and the DefaultIndex is also set in that file.

jdMorgan

4:18 pm on Jul 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, code in http.conf...

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} /index\.asp$
RewriteRule (/[^.]+\.asp¦/)$ http://192.168.0.102:81$1 [P]

As coded, the in-line OR will cause the rule to accept a request for either "<anything>/<something>.asp" or "<anything>/" (slash). The "[^.]+" subpattern will accept one or more characters not equal to a period/dot/full stop, and is more efficient than using ".*".

Checking %{REQUEST_FILENAME} causes the execution of this rule to be deferred until the fix-up phase of API processing, when the server has completed URL-to-filename resolution. So the server variable being checked here is the full server path (including %{DOCUMENT_ROOT} to a *file*.

Change the broken pipe "¦" character to a solid pipe character before use; Posting on this forum modifies the pipe character.

Jim

[edit] Removed slash preceding back-reference in substitution URL [/edit]

[edited by: jdMorgan at 5:02 pm (utc) on July 18, 2006]

Gibble

6:10 pm on Jul 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ok...I'm fuzzy on my regexes, but while this appears like it will work on files like

[localhost...] <--when resolving to index.asp
[localhost...]
[localhost...]

...won't it not work if say the url was...
[localhost...]

...because of the [^.]+ allowing anything except a "."?

jdMorgan

8:14 pm on Jul 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You are correct. If you have multi-dotted files, then use the generic pattern instead.

Jim

Gibble

2:15 am on Jul 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I tried your stuff.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} /index\.asp$
RewriteRule (/[^.]+\.asp¦/)$ [192.168.0.102:81$1...] [P]

And it didn't work at all...not even if I explicitly typed index.asp.

So I tried commenting out the Cond line, and it still didn't work.

So I went back to my RewriteRule, and it worked.

So I uncommented the RewriteCond and it kept working, except the [localhost...] part still doesn't redirect when it loads an .asp file.

Any other ideas?

jdMorgan

2:16 pm on Jul 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Paths forward:
  • Investigate why the REQUEST_FILENAME cannot be properly resolved by referring to your access and error log files, and possibly by changing the rule (temporarily) to an external redirect so that you can watch it work.
  • Move the code to httpd.conf, and use RewriteLogLevel 9 to log each action, again to determine what it's doing.
  • Remove the DirectoryIndex directives, set Options +Indexes, and then use mod_rewrite to completely replace the DirectoryIndex function (see RewriteCond flags "-f" and "-d"). In this way, you could be sure of the order in which the two functions (proxy request test and directory index lookup) are executed.

    One or more of those, or perhaps a combination, may work. The trick is to find a way to determine what filename the directory URL-request resolves to, so that you'll know if it's index.asp and may need to be proxied through to the back-end. Or to use a fixed URL-name, so that you're sure as soon as the rule matches.

    Jim

  • Gibble

    5:21 pm on Jul 19, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    1. Allready have it in httpd.conf.

    2. I can remove the DirectoryIndex stuff.
    2b. How do I recreate that with mod_rewrite?

    jdMorgan

    3:29 am on Jul 20, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    The following depends on using the REQUEST_FILENAME variable. Doing so is often difficult, because the variable is 'hidden' in the server and not exposed as a URL-path would be. So, debugging this stuff can be difficult, and it's often helpful to write a temporary external redirect rule to 'expose' the internal server variables -- say as uniquely-named query string variables that won't break anything, but will appear on the redirected URL where you can see and check them. Once in a while I find that it's necessary to prepend %{DOCUMENT_ROOT} to %{REQUEST_FILENAME} to get this to work with odd server configs.

    Anyway, sometimes this is difficult, so proceed at your own risk...


    # Rewrite requests for "/" to index.php and exit if index.php exists
    RewriteCond %{REQUEST_FILENAME}index.php -f
    RewriteRule ^(.*)/$ $1/index.php [L]
    #
    # Rewrite requests for "/" to index.html and exit if index.html exists
    RewriteCond %{REQUEST_FILENAME}index.html -f
    RewriteRule ^(.*)/$ $1/index.html [L]
    #
    # Rewrite requests for "/" to index.htm and exit if index.htm exists
    RewriteCond %{REQUEST_FILENAME}index.htm -f
    RewriteRule ^(.*)/$ $1/index.htm [L]
    #
    # If none of the above directory index filetypes exist, proxy requests for "/" to index.asp in the back-end
    RewriteRule ^(.*)/$ http://192.168.0.102:81$1/index.asp [P]
    #
    # Proxy requests for requested .asp files to the back-end
    RewriteRule ^/(.*\.asp)$ http://192.168.0.102:81/$1 [P]

    Before even starting, please read the comments carefully, and if they don't describe what you want to do, don't even bother to test this. As written, this code should handle directory-index file requests in all subdirectories as well as the top-level directory. No warranty, expressed or implied, yadda, yadda... :)

    Jim

    Gibble

    4:06 am on Jul 21, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Jim,

    Thanks a bunch for the help!

    I got it working with this.

    #Special Code so PWS will proxy ASP calls for Apache

    RewriteEngine on
    RewriteLog ../logs/rewrite.log
    RewriteLogLevel 0

    # Rewrite requests for "/" to index.php and exit if index.php exists
    RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME}index.php -f
    RewriteRule ^(.*)/$ $1/index.php [L]
    #
    # Rewrite requests for "/" to index.html and exit if index.php exists
    RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME}index.html -f
    RewriteRule ^(.*)/$ $1/index.html [L]
    #
    # If none of the above directory index filetypes exist, proxy requests for "/" to index.asp in the back-end
    RewriteRule ^(.*)/$ [192.168.0.102:81$1...] [P]
    #
    # Proxy requests for requested .asp files to the back-end
    RewriteRule ^/(.*\.asp)$ [192.168.0.102:81...] [P]