1

I've been battling some .htaccess rewrite issues lately for a webserver I provide with code provided to me externally by a consulting company. I've been chasing this issue from the perspective of 'rewrites do not work' however I think I've discovered that the actual problem is that rewrites are causing a white screen of death.

My site

http://it-news.awesome.net/news/it/153/coverstory/

my .htaccess

RewriteRule ^news/(.*)/(.*)/(.*)/$ news.php?department=$1&newsid=$2&newstitle=$3 [NE,L]
RewriteRule ^news/(.*)/(.*)/$ news.php?department=$1&archive=$2 [NE,L]
RewriteRule ^news/(.*)/$ news.php?department=$1&archive=0 [NE,L]

will produce the output URL

http://it-news.awesome.net/news.php?department=it&newsid=153&newstitle=coverstory

which is perfect. I can copy paste this from the rewrite tester tool here

http://htaccess.mwl.be/

into my browser and the articles open fine. Going to the main page and browsing the site (which has pretty URLS turned off currently) will have all these pages displaying and everything is OK.

The minute I try and use the

http://it-news.awesome.net/news/it/153/coverstory/

link, I'm hit with a white screen of death. I've stepped through the .htaccess file and commented out individually the matching lines and once there is no match, then I'm taken to my homepage and can browse normally.

I've further tested this by creating a test.php with the code

<?php     
echo $_GET['var'].' "this is static text" '.$_GET['var2'];
?>

and creating a rewrite rule

RewriteRule ^(.*)/(.*)$ test.php?var=$1&var2=$2 [NC,L]

and this DOES work.

http://it-news.awesome.net/testvariable1/testvariable2/

outputs

testvariable1 "this is static text" testvariable2

as a webpage. I'm forced to conclude that

  1. my webserver rewrites work correctly
  2. php interprets the variables given from rewrites OK in SOME situations

but now I'm hopelessly stuck. I don't know where to begin testing or debugging php and I can't imagine why some php is going to fall down and whitescreen when it seems to be correctly interpreting variables from a rewrite and can open those pages OK without using rewrites.

Anyone come across this? I wonder if it's some PHP server config or something that I've missed.


update after the comments from Mike Rocket

further testing gets me to the following .htaccess. the top 4 lines referencing test.php are for testing only and the bottom 3 are the real hopefully working documents.

RewriteBase /
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^hello\.html$ redir.html
RewriteRule (.*)\.xml(.*) $1.php$2 [nocase]
RewriteRule ^(wordpress|user)($|/) - [L]
RewriteRule ^(mysqladmin|user)($|/) - [L]
RewriteRule ^(admin|user)($|/) - [L]

RewriteRule ^(.*)/(.*)/(.*)/(.*)$ test.php?t1=$1&t2=$2&t3=$3&t4=$4 [NE,NC,L]
RewriteRule ^(.*)/(.*)/(.*)/(.*)/$ test.php?t1=$1&t2=$2&t3=$3&t4=$4 [NE,NC,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$ test.php?t1=$1&t2=$2&t3=$3&t4=$4 [NE,NC,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ test.php?t1=$1&t2=$2&t3=$3&t4=$4 [NE,NC,L]


RewriteRule ^news/(.*)/(.*)/(.*)/$ news.php?department=$1&newsid=$2&newstitle=$3 [NE,L]
RewriteRule ^news/(.*)/(.*)/$ news.php?department=$1&archive=$2 [L]
RewriteRule ^news/(.*)/$ news.php?department=$1&archive=0 [L]

my new test.php contains

<?php

echo 't1: '.$_GET['t1'].'<br/>';
echo 't2: '.$_GET['t2'].'<br/>';
echo 't3: '.$_GET['t3'].'<br/>';
echo 't4: '.$_GET['t4'].'<br/>';

?>

what I'm seeing is that for the test.php lines using http://testsite.website.com/test/test2/test3/test4/

is that the first 2 will produce broken output like this

t1: test.php/test2
t2: test3
t3: test4
t4: 

and hashing out the top 2 lines, the second 2 lines in the test.php relevant section will give me the output I want.

t1: test.php
t2: test2
t3: test3
t4: test4

what I'm finding horrible here, is that my first variable 'test' coincidently has the same name as my php file itself and if that is the case, it's giving through the name of the php file as a variable instead of the word test.

this

http://testsite.website.com/test/test2/test3/test4/ produces

t1: test.php
t2: test2
t3: test3
t4: test4

but this

http://testsite.website.com/test1/test2/test3/test4/

produces this

t1: test1
t2: test2
t3: test3
t4: test4

and I have a feeling this is the root of my issue. In my live situation I have

my.website.com/news/it

calling a news.php file as well. So it's passing in 'news.php' instead of 'news' everytime. I feel like this isn't normal and I should be able to stop this from happening somehow...

dogfish182
  • 35
  • 6
  • Perhaps try `^news/([^/]+)/([^/]+)/([^/]+)/$`. – Mike Rockétt Feb 23 '16 at 17:59
  • the thing is if I remove the matching lines, the server will pass (unmatched) and return the main page. When I hit a match, it white screens on me. This leads me to believe that the rewrite line syntax is not the problem. – dogfish182 Feb 23 '16 at 18:43
  • I also have multiple virtual hosts. could this be a complicating factor? – dogfish182 Feb 23 '16 at 21:24
  • I'm doubting that this is an Apache issue then - could only be PHP. Perhaps turn on error reporting (`E_ALL`) – Mike Rockétt Feb 24 '16 at 04:14
  • I've figured out what is happening now, my rules are good however, the [L] is not preventing processing. it's continuing to process and rules further down the list are further processing and redirecting me to index.php with busted variables. How can I accurately prevent looping with rewrites? – dogfish182 Feb 24 '16 at 13:58
  • That doesn't seem right at all - the flag should stop processing when a rule is matched. Wondering if `END` may fix this, but I'm not entirely sure it would, to be honest. Would you share the remaining content of your `.htaccess` file, please? – Mike Rockétt Feb 24 '16 at 15:50
  • Also, [this](/a/6800150/1626250) may be of help. – Mike Rockétt Feb 24 '16 at 15:53
  • @Mike Rockett this is what I read that made me realise it [link](http://stackoverflow.com/questions/11484739/mod-rewrite-unexpected-behavior-l-flag) and I was seeing a lot of [INTERNAL REDIRECT] in my logs. the condition that seems to curb this behaviour is this `RewriteCond %{ENV:REDIRECT_STATUS} 200 RewriteRule ^ - [L]` however i'm still not there yet... my 'test.php' operates as expected, but my actual page is including the word 'redirect:/' in the rewrites... which is very strange. How can I make a longer comment here to include the code? I'm hitting the limit. – dogfish182 Feb 25 '16 at 08:58
  • @MikeRockett I've updated the original subject to include the progress. Getting there, testing is working as expected, but my syntax is broken for the real rewrites and... it's somehow substituting in the word 'redirect'. amazing! – dogfish182 Feb 25 '16 at 10:04
  • This must be something to do with Multiviews then. Add `Options -Multiviews` at the very top of your `.htaccess` file, and see if it works. For reference, see [this question and answer](/questions/25423141/what-exactly-does-the-the-multiviews-options-in-htaccess). – Mike Rockétt Feb 25 '16 at 13:46
  • THANK YOU! this is the fix. I feel less like a crazy person. Marked as answer. this has really made my day. Thanks again! – dogfish182 Feb 25 '16 at 16:43
  • I can't believe I didn't think of this at first. Glad it worked for you. Adding as answer. – Mike Rockétt Feb 25 '16 at 16:44

1 Answers1

0

You need to turn off Multiviews, which is a content negotiation directive for Apache.

Options -Multiviews

When Multiviews is turned on, Apache does an implicit search for files with names similar to that of the current request, regardless of whether or not you have re-written the request.

In your case, you are rewriting /news/* to /news.php. Multiviews identifies the similarity of these, and decides to serve news.php anyway.

Turning Multiviews off will prevent this behaviour, and your rules will work as expected.

Mike Rockétt
  • 8,947
  • 4
  • 45
  • 81
  • I learned this the very very hard way. I thought my server was broken because I was seeing exactly what you describe but was trying to work around it with more complicated rewrite rules. Thanks so much for getting me there. Server works GREAT now. – dogfish182 Feb 25 '16 at 16:50
  • Yeah, so many people have fallen into the trap of doing that, it seems. It's one of those things where you just wanna bash your head against the wall for a few hours. I must say, though, that I *really* think the Apache developers should have this turned off by default. Any software that is opinionated in any way is, in my books, a bad idea. Other than this silly directive, however, Apache is great. – Mike Rockétt Feb 25 '16 at 16:53