LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Server
User Name
Password
Linux - Server This forum is for the discussion of Linux Software used in a server related context.

Notices


Reply
  Search this Thread
Old 06-26-2009, 03:19 PM   #1
deesto
Member
 
Registered: May 2002
Location: NY, USA
Distribution: FreeBSD, Fedora, RHEL, Ubuntu; OS X, Win; have used Slackware, Mandrake, SuSE, Xandros
Posts: 448

Rep: Reputation: 31
Question Apache trailing slash problem for multiple rewrites


I'm trying to proxy multiple instances of a web application (Nagios) on multiple remote machines via one Apache proxy machine.

In a virtual host definition, I've created separate Location entries for each instance, since each has a different authentication mechanism. And for each Location, I've created a set of RewriteRule directives, like the following:
Code:
RewriteRule ^/instance1$ /instance1/ [R]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
The second rule is working, but the first rule (to fix a missing trailing slash) does not, and the user is kicked to a blank page. I've read the mod_rewrite docs, the regular and advanced rewrite guides, and many 'trailing slash' posts here:'UseCanonicalNames' is on, and I've also tried these methods, with the same results:

Code:
#Reverse proxy:
ProxyPass /instance1 https://remote.url/and/path
ProxyPassReverse /instance1 https://remote.url/and/path

#Rewrite within Location directive:
<Location instance1>
...
RewriteBase /
RewriteRule ^$ / [R]
</Location
None of these seemed to address the problem with the missing slash. When I went back to the first set of RewriteRule directives above, the rewrite log showed the engine init for the request, then 'applying pattern' for all the possible definitions (instance1, instance2, etc.), including the one for the slash fix, but only returned a 'rewrite' entry for rewriting the URL without the slash to the remote server. This means that while the remote rewrite was a match, the slash rewrite didn't match and was skipped, but I'm not sure why.
 
Old 06-29-2009, 06:15 PM   #2
Guttorm
Senior Member
 
Registered: Dec 2003
Location: Trondheim, Norway
Distribution: Debian and Ubuntu
Posts: 1,453

Rep: Reputation: 446Reputation: 446Reputation: 446Reputation: 446Reputation: 446
Hi

I'm no expert on this, but why not just make 2 rules. One without a slash and one with:
Code:
RewriteRule ^/instance1$ https://remote.url/and/path [L,P]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
 
Old 06-30-2009, 09:00 AM   #3
deesto
Member
 
Registered: May 2002
Location: NY, USA
Distribution: FreeBSD, Fedora, RHEL, Ubuntu; OS X, Win; have used Slackware, Mandrake, SuSE, Xandros
Posts: 448

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by Guttorm View Post
I'm no expert on this, but why not just make 2 rules. One without a slash and one with:
Code:
RewriteRule ^/instance1$ https://remote.url/and/path [L,P]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
Thanks Guttorm. Seems sensible enough. Unfortunately, this ended up with the same problem as my original solution: requests without the trailing slash (/instance ) end up without a trailing slash and at a blank page. From the rewrite log output, it looks like the rule matches, but then the engine continues to check and apply later rules, even though I've specified the 'L' flag (for "last", meaning "don't process any further rules if this matches", or at least that's what I thought it meant).

Maybe someone can make some sense of what is happening; the request here is for the URL '/instance' (no trailing slash):
Code:
(2) init rewrite engine with requested uri /instance
(3) applying pattern '.*' to uri '/instance'
(3) applying pattern '/instance$' to uri '/instance'
(2) rewrite '/instance' -> 'https://remote.url/and/path/'
(2) forcing proxy-throughput with https://remote.url/and/path/
(1) go-ahead with proxy request proxy:https://remote.url/and/path/ [OK]
(2) init rewrite engine with requested uri /favicon.ico
(3) applying pattern '.*' to uri '/favicon.ico'
(3) applying pattern '/instance$' to uri '/favicon.ico'
(3) applying pattern '/instance/(.*)$' to uri '/favicon.ico'
(3) applying pattern '/instance2$' to uri '/favicon.ico'
(3) applying pattern '/instance2/(.*)$' to uri '/favicon.ico'
(3) applying pattern '^/(nagios_config_graph.pl)(.*)$' to uri '/favicon.ico'
(3) applying pattern '^/cgi-bin/nagios_config_graph.pl$' to uri '/favicon.ico'
(3) applying pattern '^/instance3$' to uri '/favicon.ico'
(3) applying pattern '^/instance3/(.*)$' to uri '/favicon.ico'
(3) applying pattern '/' to uri '/favicon.ico'
(2) rewrite '/favicon.ico' -> 'https://remote.url/and/path/'
(2) forcing proxy-throughput with https://remote.url/and/path/
(1) go-ahead with proxy request proxy:https://remote.url/and/path/ [OK]
The first pattern seems to match, but the trailing slash is not being appended.

Viewing the resulting page source confirms that the trailing slash was not added, and that the URL remains unchanged. Also, the resultant page, though blank, is actually a "no frames" page (which includes a hidden comment that says "This page requires a web browser which supports frames"). And the Apache access log shows GETs for /instance instead of /instance/ (and for /favicon.ico too, which should be /instance/favicon.ico).
 
Old 08-05-2009, 12:52 PM   #4
deesto
Member
 
Registered: May 2002
Location: NY, USA
Distribution: FreeBSD, Fedora, RHEL, Ubuntu; OS X, Win; have used Slackware, Mandrake, SuSE, Xandros
Posts: 448

Original Poster
Rep: Reputation: 31
I could still use some help with this: nothing I can think of trying seems to work.
 
Old 01-15-2011, 03:54 PM   #5
acksys
LQ Newbie
 
Registered: Dec 2010
Distribution: Ubuntu, Debian
Posts: 3

Rep: Reputation: 2
I had to do the exact same thing. I had some trouble, but got it to work.

I know this is an old thread, but if anyone comes across it while trying to do this and wants me to post my configuration I'd be happy to.
 
Old 01-15-2011, 08:44 PM   #6
grim76
Member
 
Registered: Jun 2007
Distribution: Debian, SLES, Ubuntu
Posts: 308

Rep: Reputation: 50
Thumbs down

Quote:
Originally Posted by acksys View Post
I had to do the exact same thing. I had some trouble, but got it to work.

I know this is an old thread, but if anyone comes across it while trying to do this and wants me to post my configuration I'd be happy to.
Why not post your config rather than make people re-visit a thread to ask for it?
 
Old 01-16-2011, 01:01 AM   #7
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
I've created a set of RewriteRule directives, like the following:
Code:
RewriteRule ^/instance1$      /instance1/                   [R]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
Note, Guttorm's example lacked the trailing slash in the first case, otherwise it would be fine.

Either use duplicate rules like
Code:
RewriteRule ^/instance1$      https://remote.url/and/path/  [L,P]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
Or, restart the rule matching if a corrective rule matches:
Code:
RewriteRule ^/instance1$      /instance1/                   [N]
RewriteRule ^/instance1/(.*)$ https://remote.url/and/path$1 [L,P]
The [N] means that the entire rule chain is restarted immediately with the result, at the very first RewriteRule. If you create an infinite loop, Apache will get stuck, so I normally recommend the duplicate rules instead.

If the corrective rules are as simple as above, or you are very careful, the restart feature is immensely useful.

Note that corrective rules that restart the chain are best used first, to make it as efficient as possible. If you are careful like me, you can even kill some path trickery at the same time. Consider using these as your very first rules:
Code:
RewriteEngine on
RewriteRule ^([^/].*)$      /$1   [E=redirect:y,N]
RewriteRule ^//+(.*)$       /$1   [E=redirect:y,N]
RewriteRule ^(.*)\.\.+(.*)$ $1.$2 [E=redirect:y,N]
RewriteRule ^(.*)//+(.*)$   $1/$2 [E=redirect:y,N]
RewriteRule ^(.*)\./(.*)$   $1/$2 [E=redirect:y,N]
RewriteRule ^(.*)/\.(.*)$   $1/$2 [E=redirect:y,N]
RewriteRule ^(.*/[^/.]+)$   $1/   [E=redirect:y,N]
RewriteCond %{ENV:redirect} y
RewriteRule ^(.*)$          $1    [R,L]
  1. If the request URL does not start with a slash (/), prepend it.
  2. If the request URL starts with more than one slash (/), keep only the first one.
  3. If there are more than one dot (.) in succession in the URL, replace them with just one.
  4. If there are more than one slash (/) in succession in the URL, replace them with just one.
  5. Replace any ./ in the URL with just /
  6. Replace any /. in the URL with just /
  7. If the last component in the URL is non-empty but does not contain a dot, append a slash /
  8. If any of the above rules were applied, they set the environment variable redirect to y (and restart the entire chain all over again). When they reach this point, all replacements possible have already been made.
    If and only if there were any substitutions made, the environment variable will have a y in it. If so, apply the following RewriteRule.
  9. Use a single visible redirect to redirect the browser to the cleaned up URL right now.
Note that the [E=redirect:y] flag will set the environment variable redirect to value y, and the [N] flag will restart the entire RewriteRule chain immediately from the beginning (using the result, of course) if the rule matches.
Since browsers only allow a small number of redirects before giving up a query, it's best to apply all known fixes first, and then do a single redirect. If these rules are the very first ones, this is extremely efficient -- even a very high load site would not be able to measure the impact (other than the single redirect done).

The end result is simple and safe for your other redirects; you won't need any duplicate rules et cetera. These also increase script security, since scripts never get paths with potentially nasty path walking components (/../ for example).

Hope you find this useful,
Nominal Animal

Last edited by Nominal Animal; 03-21-2011 at 02:57 AM.
 
  


Reply

Tags
apache, rewriterule, slash


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Trailing slash problem in apache... or DNS? Swakoo Linux - Newbie 1 06-07-2005 10:20 PM
Apache trailing slash boondock_saint Linux - General 9 07-07-2004 03:31 PM
trailing slash in Apache gives 404 errors rabbate Linux - General 6 04-30-2004 08:34 AM
Apache trailing slash puzzler tantric Linux - Software 4 04-11-2004 04:18 PM
Necessary trailing slash in apache directories silversky Linux - Software 3 03-03-2004 03:19 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Server

All times are GMT -5. The time now is 09:14 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration