1

I'm not 100% sure if this should be on server fault or stack overflow, though I'm leaning towards server fault.

Most PHP frameworks utilize Apache redirects to funnel all request to /index.php and then the framework handles the routing from there. The issue I'm having is that our old site did not use this methodology and /index.php really was our home page. Now that we released a new site, we want to redirect all direct requests to /index.php to /home.

I feel like I remember there being a switch or something in Apache which only performs a redirect if the current request is not the result of another 301 redirect. I can't seem to find anything like this though. Am I making this up? If I am, is there some way to handle this situation?

I've stripped out my Apache configuration file to the absolute bare minimum to eliminate the chance of unknown redirects. Here it is (though the domain name has been redacted):

##
# Some LoadModule includes
##

## Set the IP and ports for this server
Listen 10.0.15.246:80

## zend fastcgi
AddType application/x-httpd-php .php
AddHandler fastcgi-script .php

<VirtualHost *:80>

    ## Set various vhost values
    ServerName www.example.com
    DocumentRoot /www/www.example.com/htdocs/public
    DirectoryIndex index.php

    ##Set development environment
    SetEnv WEB_ROOT /www/www.example.com/htdocs/public
    SetEnv APPLICATION_ENV development

    RewriteEngine On

    ## My attempts to redirect /index.php to either / or /home
    #RewriteRule /index.php$ /home [R=301,NC,L]
    #RewriteRule /index.php$ / [R=301,NC,L]

    <Directory /www/www.example.com/htdocs/public>
        DirectoryIndex index.php
        AllowOverride All
        Order allow,deny
        Allow from all

    </Directory>

</VirtualHost>

I have an .htaccess file located at /htdocs/.htaccess which is completely blank.
I also have an .htaccess file located at /htdocs/public/.htaccess which contains the following and nothing else:

RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]

What is currently happening:

What I want to change is:

  • When a user goes to http://example.com/index.php they end up on my homepage.

  • When a user navigates to http://www.example.com/<anything else> it goes to the appropriate page (or a 404 error if it doesn't exist).

d.lanza38
  • 327
  • 1
  • 5
  • 13
  • That last bit that you edited in is probably causing you all sorts of problems. You only need the ErrorDocument part of that; the rewrite is redundant (and broken). – Michael Hampton Aug 08 '18 at 16:51
  • Okay, I removed the rewrite, but I'm still getting the same behavior. – d.lanza38 Aug 08 '18 at 16:55
  • @MichaelHampton Quick question though. It seems obvious to me, but I know I have to be missing something, but wouldn't this line `RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]` redirect `/home` to `/index.php`? And then wouldn't this line `RewriteRule ^/index.php$ /home [R=301,NC,L,QSA]` redirect `/index.php` to `/home` resulting in a loop? Is it the fact that only one of them is a 301 redirect which should prevent the loop? – d.lanza38 Aug 08 '18 at 17:26
  • No, we talked about that one already. It rewrites, not redirects. – Michael Hampton Aug 08 '18 at 17:28
  • What's the distinction between a rewrite and a redirect? Is it the 301 flag? – d.lanza38 Aug 08 '18 at 17:29
  • One tells the browser to redirect, the other doesn't. The rewrite you pointed out here loads `/index.php` but the URL in the browser is `/home` - and the URL passed to `/index.php` is _also_ `/home`. – Michael Hampton Aug 08 '18 at 17:31
  • Do you even _have_ an index.php file?! What sort of application is this? How is it getting loaded? – Michael Hampton Aug 08 '18 at 17:32
  • Yep, I have an index.php file. It's a Zend Framework 2 application, so everything goes to the index.php file which bootstraps the applications and routes it to the appropriate controllers. – d.lanza38 Aug 08 '18 at 17:35
  • @MichaelHampton Hi Michael, turns out my "solution" wasn't a solution after all. As a troubleshooting process I've stripped my httpd.conf file to the absolute bare minimum to try to eliminate any chance of unknown redirects occurring. I updated my question to include the httpd.conf file in it's entirety plus the `.htaccess` files in the path as well. Maybe I was leaving something out which I didn't think was relevant, but was. Do you see anything? – d.lanza38 Aug 09 '18 at 15:48

1 Answers1

0

I couldn't find a flag/switch in Apache which prevented a redirect on an existing request which was previously redirected.

Instead, I looked to implementing a solution within the application itself.

For example, since my application was a Zend Framework 2 application, my solution was adding this to the /htdocs/public/index.php file:

if(trim($_SERVER['REQUEST_URI']) === '/index.php'){
    header("Location: /home",TRUE,301);
    die();
}

It's not the cleanest of solutions. But I only include the pieces of ZF2 I need rather than the whole package, so I don't have to worry about the file being overwritten due to an update.

d.lanza38
  • 327
  • 1
  • 5
  • 13