Forum Moderators: phranque

Message Too Old, No Replies

SSL exception with mod rewrite

Trying to make mod_rewrite redirect correctly

         

Pyrrish

9:22 pm on Aug 21, 2009 (gmt 0)

10+ Year Member



I am using the following code to force my "Signup" page to use HTTPS. However, when I'm getting a 404 Not Found when navigating to that page.


# SSL Exception Here
RewriteCond %{SERVER_PORT} !^443
RewriteCond %{REQUEST_FILENAME} signup
#This should redirect, however it doesn't use
#the last rule once it redirects
RewriteRule ^(.*)$ https://www.example.com/signup [R,L]
RewriteRule ^signup$ index.php?p=signup [L]

After it redirects, its not correctly mapping "signup" to "index.php?p=signup", instead its almost as if its looking for a folder named "signup" and ignoring that last rule. I'm probably missing something obvious, but I'm by no means an expert.

jdMorgan

10:47 pm on Aug 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Are you sure that the HTTPS requests resolve to the same directory as the one that this .htaccess file is located in? Frequently, HTTP and HTTPS are implemented as two separate virtual servers, which may or may not share the same DocumentRoot.

Therefore, if your second rule is not located in the filespace assigned for HTTPS requests, it won't be executed for HTTPS requests.

As an aside, you can improve/shorten this code:


# If signup requested using HTTP
RewriteCond %{SERVER_PORT} !=443
# redirect to HTTPS
RewriteRule ^signup$ https://www.example.com/signup [R=302,L]
#
# Internally rewrite signup URL requests to index.php script
# (Not working: It doesn't use this last rule once it redirects)
RewriteRule ^signup$ index.php?p=signup [L]

Jim

Pyrrish

11:34 pm on Aug 21, 2009 (gmt 0)

10+ Year Member



Thanks for the reply. Yes, I am sure that they both resolve to the same directory because if I go to "www.example.com/index.php?p=signup" it works fine. Its just the rewrite rule that doesn't work for some reason.

I will include some more of the file in case something else might be the problem.


RewriteEngine On
# Make wildcard subdomains call publicsite.php
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteCond %{HTTP_HOST} ([^.]+)\.example\.com
RewriteCond %{REQUEST_URI} !^/publicsite\.php$
RewriteRule ^(.*)$ /publicsite.php?domain=%1 [L]
# SSL Exception Here
RewriteCond %{SERVER_PORT} !^443
RewriteCond %{REQUEST_FILENAME} signup
RewriteRule ^(.*)$ https://www.example.com/signup [R,L,S=2]
RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_FILENAME} !signup
### MAIN PAGE RULES ###
RewriteRule ^privacy$ index.php?p=privacy [L]
RewriteRule ^terms$ index.php?p=terms [L]
RewriteRule ^video$ index.php?p=video [L]
RewriteRule ^video/([A-Za-z0-9-]+)$ index.php?p=video&f=$1 [L]
RewriteRule ^support$ index.php?p=support [L]
RewriteRule ^community$ index.php?p=community [L]
RewriteRule ^signup$ index.php?p=signup [L]
RewriteRule ^login$ index.php?login=yes [L]
RewriteRule ^logout$ index.php?p=logout&logout [L]

Thanks again.

[edited by: jdMorgan at 3:29 am (utc) on Aug. 22, 2009]
[edit reason] Please use example.com. See TOS. [/edit]

jdMorgan

3:20 pm on Aug 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Let's reduce this this to optimal form so we can make some progress here. Please upload and test this after reading the notes below:

RewriteEngine on
#
# Pass wildcard subdomain requests to publicsite.php script
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteCond %{HTTP_HOST} ([^.]+)\.example\.com
RewriteRule !^publicsite\.php$ publicsite.php?domain=%1 [L]
#
# Redirect HTTP signup page requests to HTTPS in order to secure signups
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^signup$ https://www.example.com/signup [R=301,L]
#
# Redirect any other extensionless page requests back to HTTP
RewriteCond %{SERVER_PORT} =443
RewriteCond $1 !^signup$
RewriteRule ^(([^/]+/)*[^./]+)$ http://www.example.com/$1 [R=301,L]
#
### MAIN PAGE RULES ###
# Pass common "p=" page requests to index.php with page name in query string "p" parameter
RewriteRule ^(community¦privacy¦signup¦support¦terms¦video)$ index.php?p=$1 [L]
# Handle other page requests
RewriteRule ^video/([A-Za-z0-9\-]+)$ index.php?p=video&f=$1 [L]
RewriteRule ^login$ index.php?login=yes [L]
RewriteRule ^logout$ index.php?p=logout&logout [L]

Notes:

Replace all broken pipe "¦" characters above with solid pipes before use; Posting on this forum modifies the pipe characters.

Whenever you change any server-side code, be sure to completely flush (delete) your browser cache to avoid seeing previously-cached (stale) pages and server status responses.

For testing, I recommend using the "Live HTTP Headers" add-on for Firefox and Mozilla browsers. It allows you to watch all HTTP transactions between your browser and the server. Also, when you encounter an error, look at your server error log file -- It often contains very helpful information about errors.

Jim

Pyrrish

4:54 pm on Aug 22, 2009 (gmt 0)

10+ Year Member



Thanks again for your reply. I changed my htaccess file to what you had in your previous post and I'm getting the same error. Once again I tried navigating to "index.php?p=signup" and it worked. I even tried creating a folder called "signup", and of course it navigated to the folder. In my server error log I simply see several "File does not exist: /var/www/vhosts/example.com/htdocs/signup". It still seems as though the rewrite rule for "signup" -> "index.php?p=signup" is being ignored.

jdMorgan

5:15 pm on Aug 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> I even tried creating a folder called "signup", and of course it navigated to the folder

With the rewrite in place, it should not have gone to that folder unless you added a slash to the end of the URL that you requested. So add


Options -MultiViews

at the top of the code I posted, flush cache, and try again.

Be careful also that you have no other code in any server config or .htaccess file that picks up on 'signup' URL requests, and that there is no redirection from within any of your scripts which would countermand the 'signup' rewrite.

Also, according to your error log entry, the code we're discussing here must be located in /var/www/vhosts/example.com/htdocs/.htaccess in order to affect 'signup' URLs.

Jim

Pyrrish

6:02 pm on Aug 22, 2009 (gmt 0)

10+ Year Member



I added the multiviews line and there was no change. I wrote the code from scratch so I know there is nothing else handling URL requests for this page. The .htaccess file is in the correct place.

I got rid of the lines from .htaccess that handle http/https to see if I could manually navigate to the pages using HTTPS and the only page that didn't give me a File Not Found error was the root page (www.example.com). I checked my https virtual server document root and its pointing to the same place as the normal virtual server's document root. The straight file names still work, however.

For example:
[Without the server_port rules and conditions in .htaccess]
[example.com...] WORKS
[example.com...] DOESN'T WORK
[example.com...] WORKS
http://www.example.com/rewritten WORKS

jdMorgan

8:01 pm on Aug 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Again, this indicates that the HTTPS and HTTP servers are implemented separately.

You may have to ask your host for details.

Jim

Pyrrish

8:07 pm on Aug 22, 2009 (gmt 0)

10+ Year Member



I'm running my own VPS so I configured everything. I'll keep looking through some of the configs.

EDIT: Found the problem. For some reason my SSL virtual host contained "AllowOverride None". I just changed it to "All" and now it works correctly. AllowOverride None basically ignores htaccess files, and I'm not sure why I set it up that way in the first place.

jdMorgan

8:16 pm on Aug 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yeah, after thinking about what I wrote just previously, that's what I expected -- Either that, or that "Options +FollowSymLinks" or "Options +SymLinksIfOwnerMatch" wasn't specified for the HTTPS vHost.

Jim