Forum Moderators: phranque

Message Too Old, No Replies

RewriteRule generates 404 over HTTPS connection

         

max4

5:43 am on Jun 26, 2010 (gmt 0)

10+ Year Member



Hi,

I have been using htaccess to change dynamic urls into static urls. This has been working fine until recently, after I installed an ssl certificate and loaded the page up in https, and now when I load up a page where the dynamic url is converted into a static one, I receive a 404 Not Found. The dynamic url loads just fine under https; the issue is with the dynamic -> static conversion. Here is the relevant code:


rewriteEngine On

RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

RewriteRule ^([A-Za-z0-9_]+)/?$ profile.php?username=$1 [L]
RewriteCond %{THE_REQUEST} ^[A-Z]\ /profile\.php\?username=([^&]+)\ HTTP/
RewriteRule ^profile\.php$ http://www.example.com/%1? [R=301,L]


Any suggestions? Thanks.

g1smd

6:39 am on Jun 26, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You need to list rewrites after redirects. That is, the final line of code is in the wrong place.

Your first line of code generates a 302 redirect. Add the [L] flag to every rule too.

There should be some symmetry to your code. There should be a block that works with https "on" and a block that works with https "not on".

You might also find that detecting SERVER_PORT is "443" or is "not 443" might be more reliable than testing the state of "HTTPS".

max4

3:21 pm on Jun 26, 2010 (gmt 0)

10+ Year Member



Thank you for your help g1smd, I am attempting to implement your advice.

max4

5:12 pm on Jun 26, 2010 (gmt 0)

10+ Year Member



Hi g1smd,

I was under the impression that we should internally rewrite the static url to a dynamic one first; it is possible that I misread "Changing Dynamic URLs to Static URLs"

[webmasterworld.com...]

Indeed, both methods run without error on standard Hypertext Transfer Protocols. That is:


RewriteRule ^([A-Za-z0-9_]+)/?$ profile.php?username=$1 [L]
RewriteCond %{THE_REQUEST} ^[A-Z]\ /profile\.php\?username=([^&]+)\ HTTP/
RewriteRule ^profile\.php$ http://www.example.com/%1? [R=301,L]


AND


RewriteCond %{THE_REQUEST} ^[A-Z]\ /profile\.php\?username=([^&]+)\ HTTP/
RewriteRule ^profile\.php$ http://www.example.com/%1? [R=301,L]
RewriteRule ^([A-Za-z0-9_]+)/?$ profile.php?username=$1 [L]


Regardless, neither method seem to work over Hypertext Transfer Protocol Secure. I attempted to implement your advice on creating a check for whether or not https is on:


RewriteCond %{HTTPS} =on
RewriteRule ^(.+)$ - [env=ps:https] [L]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.+)$ - [env=ps:http] [L]

RewriteCond %{THE_REQUEST} ^[A-Z]\ /profile\.php\?username=([^&]+)\ HTTP/
RewriteRule ^profile\.php$ %{ENV:ps}://www.example.com/%1? [R=301,L]
RewriteRule ^([A-Za-z0-9_]+)/?$ profile.php?username=$1 [L]


The result remains the same. Over http, the static url points to the proper location and dynamically loads the page; over https I receive a Not Found without redirect to my custom error page, i.e. I get the generic apache 'Not Found' page.

This only happens when I attempt to reach the static url; example: www.example.com/user, where user is a valid username.

If I do: www.example.com/profile.php?username=user, the page loads up correctly under https.

If I do: www.example.com/profile.php?username=invalidUser I correctly receive my custom error page.

It is evident my knowledge is lacking in this matter, because I otherwise can't see what is wrong here. Perhaps a link to proper manual page? Or some advice on this issue? Thank you very much for your help in this matter.

jdMorgan

9:12 pm on Jun 26, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Shorter:

RewriteCond %{HTTPS}s>%{THE_REQUEST} ^(on(s)|[^>]*s)>[A-Z]+\ /profile\.php([^&]*&)*username=([^&]+)
RewriteRule ^profile\.php$ http%2://www.example.com/%4? [R=301,L]
#
RewriteRule ^([a-z0-9_]+)/?$ profile.php?username=$1 [NC,L]

The ">" character has no special significance. It serves simply as an unambiguous delimiter between the combined variable values, to make them easy to parse.

I suspect, however, that the problem is that your .htaccess code is not being executed at all in the HTTPS case -- Be sure that HTTPS requests resolve to the same filespace in the server -- This is often not the case.

Look at your HTTPS server error log to see if it gives you a clue...

Jim

max4

4:05 pm on Jun 27, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Thank you for your guidance in this matter. Taking your advice into consideration and looking beyond the htaccess file I noticed a few things wrong with my configuration. The ScriptAlias directive in my example-ssl.conf file was missing so I wrote it in; my ports.conf file did not contain reference to 443, so I added it in; I finally found the cause of the NameVirtualHost error I kept getting (NameVirtualHost *:80 was in both ports.conf and in example.com.conf) and corrected it by removing that line from example.com.conf.

I doubled checked to ensure both example.com.conf and example-ssl.conf were enabled (and I even disabled and re-enabled them to be sure). I could not find any fault in my apache2.conf file (which basically defined the behavior of certain unrelated modules) and my httpd.conf file only has one line, which I added, that is the ServerName definition.

I did find one typo in my ssl.conf file, but I corrected that as well. As far as I can tell, everything is in order; but I still receive the 404 Not Found. Could it be the way I defined the virtual hosts? Currently I have two 'sites-enabled' one being my example.com.conf which is set to port 80; that is <virtualhost *:80> and the other being example-ssl.conf which is set to port 443; that is <virtualhost *:443>

Though I don't know why this configuration would be a problem. My Apache error log only indicates one issue: "File does not exist: /var/www/User" and only throws that when accessing the static url with https. If not in the files I mentioned above; ie, sites-enabled/example.com.conf, sites-enabled/example-ssl.conf, apache2.conf, httpd.conf, ports.conf; then what other files exist that contain configuration details which could be leading this is error?

Thank you very much for your insight into this, and for those lines of code. It is evident that you understand these concepts very well.

g1smd

4:29 pm on Jun 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The "example" files are just that, examples.

The system is not actually using them for anything.

max4

4:33 pm on Jun 27, 2010 (gmt 0)

10+ Year Member



Hi g1smd,

Thank you for your response. I wrote in example to replace my domain name in compliance with the forum rules. Indeed example.com.conf is domain.com.conf - I apologize for the confusion. Both files were enabled using $ sudo a2ensite domain.com.conf and $ sudo a2ensite domain-ssl.conf respectfully.

jdMorgan

4:53 pm on Jun 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> Currently I have two 'sites-enabled' one being my example.com.conf which is set to port 80; that is <virtualhost *:80> and the other being example-ssl.conf which is set to port 443; that is <virtualhost *:443>

Right, and the 'focus' of my question was whether both of these files point to the same DocumentRoot and whether that DocumentRoot is where the .htaccess code is located. If not, then the code will only be executed when one or the other vHost is accessed (as selected by http or https in the request). If the code doesn't run, then you're left with no RewriteRule to map the 'virtual' URL to the actual/existing file.

Could be something else of course, but that's one of the first things to check.

Jim

max4

5:05 pm on Jun 27, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Thank you for your response. Indeed, both files point to the same DocumentRoot where the .htaccess file is located and both files define the behavior of that directory. That is, both contain the following:


DocumentRoot /var/www/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>

max4

5:53 am on Jun 28, 2010 (gmt 0)

10+ Year Member



This issue has been resolved. In the ssl.conf file we set AllowOverride None for <Directory /var/www/>; changing that to AllowOverride All corrected the problem.

Thank you Jim and g1smd for your insight in this issue. Guidance is always appreciated.