The usual .htaccess code stopped to work

Marco Gasi
Marco Gasi used Ask the Experts™
on
Hi everybody.
So I have several website. Their structure is:

-admin
-css
-en
  -index.php
-es
  -index.php
-js
.htaccess
index.php
urlrewriter.php

The index.php in the root just redirect to the index in es folder, where are spanish version of the website:

index.php in root
<?php
header("Location: /es/index.php");

Open in new window


I use url rewriter to rewrite urls accordingly to a configuration file. The important thing is that in all websites I have the same code for all these files (what's change is the html template and okay some other things but none of them is related to this question).

In .htaccess  I have this
<IfModule mod_rewrite.c>
RewriteEngine on
Options +SymLinksIfOwnerMatch
RewriteBase /

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$
RewriteRule .* https://www.%1%{REQUEST_URI} [L,NE,R=301]

RewriteCond $1 !^(admin/|witpack/php|auth|.css|.js|.jpg|.png|.gif)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /urlrewriter.php [L]
</IfModule>

Open in new window


in urlrewriter.php I have this code:
<?php
require_once __DIR__ . '/inc_common.php';
$url = strtok($_SERVER['REQUEST_URI'], '?');
$requestedPage = substr($url, 1, strlen($url) - 1);
$safePages = array();
foreach ($config->translation->pages as $langGroup) {
    foreach ($langGroup as $key => $value) {
        array_push($safePages, $value);
    }
}
if (!empty($requestedPage)) {
    if (!in_array(trim($requestedPage), $safePages)) {
        echo "requestedPage: $requestedPage<br>";
        echo "<pre>";
        var_dump($safePages);
        echo "</pre>";
//        header("Location: /403.php");
    } else {
        include($_SERVER['DOCUMENT_ROOT'] . "/$requestedPage.php");
    }
}

Open in new window


So when someone just types the domain name www.website.com, it is redirected to urlrewriter.php. Here the requested page result to be es/index.php. Since this page is in $safePages, it is just included.

Suddenly, in the new website I'm building this proven code stopped to work! Typing the url of the website, the es/index.php page is served but without all php variables initialized in the inc_common.php file included in urlrewriter.php. If I comment the redirection in the root index.php, I just get a blank page. If I play with the .htaccess, the only result I've got is an infinite loop or the list of pages due to the var_dump in urlrewriter.php because the requested url result to be urlrewriter.php itself.
I've got this last result when I I changed htaccess this way:
RewriteCond $1 !^(admin/|witpack/php|auth|.css|.js|.jpg|.png|.gif)
RewriteCond %{REQUEST_URI} !^/(urlrewriter)\.php
RewriteRule .* /urlrewriter [L,R=302]

Open in new window


Any idea? What's puzzling me is that the exact same code works in the same server in other websites...How can I debug such a thing?
Thank you for any help.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
David FavorFractional CTO
Distinguished Expert 2018

Commented:
You might check your Apache + PHP versions, comparing failing site with working sites.

Also, check your Apache + FPM PHP logs for problems.

Your code includes no header generation. Likely this lives in the inc_common.php file.

Very difficult to guess without seeing actual returned headers + HTML.

Be useful for you to post the failing URL for testing.
Marco GasiFreelancer
Top Expert 2010

Author

Commented:
Hello David. Hope you're doing well.

in inc_common.php I have these header generation
header('Content-Type: application/json; charset=utf-8');
header('Content-Type: text/html; charset=utf-8');

Open in new window


This is current .htaccess (I stop to play with it during your tests)
<IfModule mod_rewrite.c>
RewriteEngine on
Options +SymLinksIfOwnerMatch
RewriteBase /

RewriteCond $1 !^(admin/|witpack/php|auth|.css|.js|.jpg|.png|.gif)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /urlrewriter [L,R=302]
</IfModule>

Open in new window


The url is https://toninacruises.codingfix.com
The PHP version is 7.2. For Apache version I should ask to the provider (I'm on a shared hosting).

Thank you
Marco GasiFreelancer
Top Expert 2010

Author

Commented:
Oh, I had to correct the index.php in the root:
header("Location: es/index");

Open in new window

Because the sense of the code in .htaccess is "if file doesn't exist redirect to urlrewriter.php", SInce the file 'index' doesn't exist, the redirect usually works...
How to Generate Services Revenue the Easiest Way

This Tuesday! Learn key insights about modern cyber protection services & gain practical strategies to skyrocket business:

- What it takes to build a cloud service portfolio
- How to determine which services will help your unique business grow
- Various use-cases and examples

David FavorFractional CTO
Distinguished Expert 2018

Commented:
You can discover your Apache + PHP version on any machine by placing this file somewhere on the machine, then navigating to the file.

# phpinfo.php
<?php
print_r (phpinfo());
?>

Open in new window

David FavorFractional CTO
Distinguished Expert 2018

Commented:
Seems to be working now.
Marco GasiFreelancer
Top Expert 2010

Author

Commented:
Hi David. No. That is, it looks like it be working because the es/index page is displayed correctly, but if you hover your mouse over Avistamientos picture, which is a link, in the bottom-left side of the window you'll see there is a Php Notice about Undefined variable pages and about Tryiong to get property sightingsPage of non-object.
$pages is an object built in inc_common.php included at the very top of urlrewriter.php. This object properties is a colletion of pages names. I have a class which get the current selected language and the gets the right page name from a config file. So, $pages->sightingsPage evaluates in es/avistamientos if language is spanish and in en/sightings if language is english, then the correct page is served.
Really strange. And I don't know how to debug: Apache error.log only report the same php notices...
Marco GasiFreelancer
Top Expert 2010

Author

Commented:
Okay, now at least I know it's something at server level: the code works as expected in a website hosted by Hostalia and it doesn't work in a website hosted by IONOS. The latter is toninacruises.codingfix.com, the former is elweb.es: both run PHP 7.2 on Apache 2,0. HAve you some suggestion about where I have to look to understand what's different? I know there are a lot of things but likely not everything can affect this type of redirect... Because it looks like the redirect is just ignored, but not the .htaccess file itself because I put a evidently wrong rule and I've got an Internal Server Error, so I know the .htaccess file is processed but in some different way....
A fundamental thing has been drop the hotlinking prevention code I copied from a tutrial and delete the flags from the rewrite rule:

it works
RewriteRule . /urlrewriter.php

Open in new window


it doesn't work
RewriteRule . /urlrewriter.php[L,R=302]

Open in new window

Freelancer
Top Expert 2010
Commented:
Okay.  
Now it works in both servers.
First, the only issue here is with .htaccess: all remaining code has no effect on this issue.
Second, let me say that in my first .htaccess snippet there was a small mistake the flag in the redirection RewriteRule was not in original working code: any flag must be removed here.
So the finally working code for .htaccess is:

.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
Options +SymLinksIfOwnerMatch
RewriteBase /

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$
RewriteRule .* https://www.%1%{REQUEST_URI} [L,NE,R=301]

RewriteCond $1 !^(admin/|witpack/php|auth|.css|.js|.jpg|.png|.gif)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /urlrewriter.php
</IfModule>

Open in new window

(of course lines 6-9 ara just to redirect any request to www so it is not relevant in this question)

But whats was preventing this code to work on IONOS server was the Options. In IONOS set Options to -MultiViews is mandatory to get the code work. So, the Options which work in both servers is the following one:

.htaccess for both servers
<IfModule mod_rewrite.c>
RewriteEngine on
Options +SymLinksIfOwnerMatch -MultiViews
RewriteBase /

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$
RewriteRule .* https://www.%1%{REQUEST_URI} [L,NE,R=301]

RewriteCond $1 !^(admin/|witpack/php|auth|.css|.js|.jpg|.png|.gif)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /urlrewriter.php
</IfModule>

Open in new window


Any ideaabout why -MultiViews is required in one server and it is not in the other one?

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial