Why is Apache Permanent Redirect removing the slash between the domain and the path?

13,189

Solution 1

I got it.

The issue did not lay with the rewriting at all, it was the SSLRequireSSL directive under my Directory definition that was causing the problem.

I simply removed this directive, refreshed the cache in all of my browsers, and the site then continued to work correctly. This was discovered through the process of elimination.

The documentation notes:

This directive forbids access unless HTTP over SSL (i.e. HTTPS) is enabled for the current connection. This is very handy inside the SSL-enabled virtual host or directories for defending against configuration errors that expose stuff that should be protected. When this directive is present all requests are denied which are not using SSL.

The emphasis is my own. SSLRequireSSL may have Apache only return a 403 or 404 if HTTP over SSL is not enabled, interfering with the Redirect rule. A rewrite rule such as the one in this answer on Server Fault may be a better alternative depending on your use case:

RewriteEngine On
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]

Solution 2

My issue was related to browser caching.

I tried it in a different browser and it worked and then tried again in a private session in the first browser and it also worked.

Share:
13,189

Related videos on Youtube

Nathan Lutterman
Author by

Nathan Lutterman

I'm a software developer living in the US. I'm a fan of PC gaming, music, and beer.

Updated on June 25, 2022

Comments

  • Nathan Lutterman
    Nathan Lutterman almost 2 years

    I'm using Apache 2.4, and I set up two virtual directories. One requires SSL, and the other one redirects to it.

    If a user attempts to visit https://www.derp.com/derp without /derp existing, they correctly get a 404. But when a user visits http://www.derp.com/derp, Apache incorrectly redirects the user to https://www.derp.comderp, removing the slash between the path and the domain name.

    I have no idea what would be causing this.

    The following is the setup of my Virtual Host.

    <VirtualHost *:443>
        ServerAdmin [email protected]
        ServerName www.derp.com
        ServerAlias derp.com
        DocumentRoot "C:\Users\derp\Documents\Web Projects\derp"
        SSLEngine on
        SSLCertificateFile "C:\Apache24\certs\cert.cer"
        SSLCertificateKeyFile "C:\Apache24\certs\key.key"
    </VirtualHost>
    
    <VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName www.derp.com
        ServerAlias derp.com
        Redirect permanent / https://www.derp.com/
    </VirtualHost>
    
    <Directory "C:\Users\derp\Documents\Web Projects\derp">
        Options Indexes FollowSymLinks Includes ExecCGI
        AllowOverride All
        Require all granted
        SSLRequireSSL
    </Directory>
    

    Why would Apache be behaving this way?

    Bonus Question: Should redirects be handled in my virtual host definition, or should it be handled in the .htaccess file in the web site's physical directory?


    Edit:

    I'm starting a Laravel project, and by default the public folder does contain a .htaccess file, so here's that guy:

    <IfModule mod_rewrite.c>
        Options -MultiViews
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^ index.php [L]
    </IfModule>
    

    Edit Two:

    I tried:

    • adding a slash at the end of the DirectoryRoot path
    • replacing the backslashes with forward slashes in the DirectoryRoot path
    • replacing the backslashes with double backslashes in the DirectoryRoot path

    I also removed the .htaccess file from the directory completely.

    It redirects correctly when you go from http://www.derp.com to https://www.derp.com. It's just when you specify a path and attempt https that it removes the slash between the domain and the path.


    Edit Three:

    I also attempted the following suggestion:

    Redirect permanent / https://www.derp.com/
    
    Try
    
    RedirectMatch permanent /(.*) https://www.derp.com/$1
    
    or
    
    RedirectMatch permanent (.*) https://www.derp.com/$1
    

    ... and instead of redirecting to https://www.derp.comderp, it instead does not redirect, attempts and gives a 404 for http://www.derp.com/derp, but using Apache's 404, instead of throwing a Not Found Exception, as Laravel does without configuration.


    Edit Four:

    I have also tried:

    <IfModule mod_rewrite.c>
        Options -MultiViews
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.php$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
    </IfModule>
    

    In the .htaccess file and the behavior did not change at all.

  • Ortomala Lokni
    Ortomala Lokni over 7 years
    Any explanations of why that?
  • Nathan Lutterman
    Nathan Lutterman over 7 years
    @OrtomalaLokni I edited my answer and it might provide more information. Thanks for asking that.
  • Snackoverflow
    Snackoverflow about 4 years
    Seems like a bug to me, no interference like this is mentioned in the documentation, and the SSLRequireSSL directive is used in most tutorials without mentioning this behavior. How do I know that removing this directive will not break any existing behavior? I mean, it is there for a reason in the first place, to only allow secure connections. If I remove it.. you can pretty much connect with plain HTTP over port 443 or what exactly?
  • Snackoverflow
    Snackoverflow about 4 years
    I have SSLRequireSSL directive removed, but the behavior did not change. The slash is still removed just like you have described in your question. Happens in all devices and browsers. Not related to caching. What would you suggest I try?
  • bermick
    bermick about 4 years
    hey where is the directive listed? what do you mean by "Directory definition"? thanks!
  • Nathan Lutterman
    Nathan Lutterman about 4 years
    If you look in my original question, before the edits, there is a <Directory "C:\Users\derp\Documents\Web Projects\derp">.... That's the "Directory definition". SSLRequireSSL is in there.
  • dmance
    dmance almost 4 years
    Yes, mine too. I did not wanted to add .htaccess.
  • a coder
    a coder about 3 years
    same, worked just fine in another browser for me