homepage Welcome to WebmasterWorld Guest from 54.204.58.87
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Rewrite working but with http status code 500
gasell




msg:4669582
 7:56 pm on May 8, 2014 (gmt 0)

I've got the following rewrites active on my site. What I'm trying to achieve is to redirect requests to a subdir in general but load them straight if single existing file is asked. Also, it should be possible to load php files without extension.

RewriteCond %{REQUEST_URI} [^/]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /subdir/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

Somewhere in there I must've asked for something that doesn't make sense as the request for / currently loads content successfully from subdir but with http status 500. I don't see any errors appearing in error_log files for public_html and subdir that would relate to that.

My rewrite skills are very minimal and I fail to see where I've gone wrong. Any hints or explanations welcome.

 

lucy24




msg:4669620
 10:54 pm on May 8, 2014 (gmt 0)

Hm, odd subject line. If it's getting a 500 response it cannot be said to be "working" ;) Where are you seeing the 500 response, if it's neither in logs nor in the visible page?

RewriteCond %{REQUEST_URI} [^/]$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /subdir/$1 [L]

What's this for? I smell a CMS, but why not put the first condition into the body of the rule?

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ /subdir/$1 [L]


Since the rule by definition isn't intended to apply to requests for the root (which has to be considered a / directory), it should in any case say + rather than *.

Are there a great many URLs that fit this pattern? ("It doesn't exist at its originally requested location, so send them over to /subdir/".) If not, it would be better to list them by name.

A further problem is that the root is either
^$
or
/
or
/somedir/otherdir/hostname/
depending on where you're looking. Are these rules located in htaccess, or loose in the config file?

:: detour to check something ::

Ah. The label %{REQUEST_FILENAME} is misleading; it doesn't actually mean filename (like a <Files> envelope) but the full path. What happens if the file also doesn't exist in /subdir/ ? Don't you get an infinite loop ending in a 500?

Finally, it seems as if the first rule should be constrained to requests for pages, unless you've done a major rearrangement and you also need to redirect search engines. (Nobody else would make a "cold" request for an image.) Is there a consistent extension, or are you extensionless? Does a . period ever occur in a filepath anywhere other than right in front of the extension?

gasell




msg:4669801
 6:13 pm on May 9, 2014 (gmt 0)

Well "working" as in the right content gets loaded and a regular user won't notice a thing. 500 is returned as a http header. I first noticed it because I've got an uptime report which considers status code 500 as "down", but it's also visible if I look at responses with Firebug or similar developer tools. Obviously I'd like to have 200 if there are no serious errors :)

/subdir is where I've got Wordpress installed. Most of the content is served from there. But every now and then I want to have a few exceptions for different things like logging my dynamic ip by a script or similar. I could list each of the exceptions in .htaccess but it would be less convenient because I'd have to change it each time.

I'm not sure what you mean by config file here. It's a shared hosting environment, I only configure .htaccess files. I do have subdomain folders at the same level in the filesystem as subdir.

If I understand you correctly then no, no . in filepaths or directory names. Only as part of domain name or subdomain name or for extensions like .png or perhaps .css.

Could it be that what Wordpress has in .htaccess somehow conflicts top level .htaccess? I have the following in there:
RewriteBase /subdir/

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /subdir/index.php [L]

What is a good place to read up on the rules of applying .htaccess files in different directories along the path? I feel like I don't understand enough to detect loops myself.

phranque




msg:4669833
 8:40 pm on May 9, 2014 (gmt 0)

if you got a 500 status code with your response, you should have a corresponding entry in the server error log file.

lucy24




msg:4669834
 8:43 pm on May 9, 2014 (gmt 0)

RewriteBase /subdir/

This isn't actively harmful, but it isn't needed. The RewriteBase is appended if and only if the target of a RewriteRule ends in a bare file/directory name (no leading slash). If your targets start in a slash-- meaning the root-- you don't need a RewriteBase.

What is a good place to read up on the rules of applying .htaccess files in different directories along the path?

In general, multiple htaccess files don't matter. Since you can't have <Directory> sections, any directory-specific rule (such as special headers, expiration times, index directives etc) has to go in an htaccess of its own. The server will look for htaccess files whether they exist or not; you can't switch off an AllowOverrides directive once it's in effect.

The one exception is...

Could it be that what Wordpress has in .htaccess somehow conflicts top level .htaccess?

YES. WordPress (and also Joomla, Drupal and probably other CMS that I don't know about) relies entirely on RewriteRules. A quirk of mod_rewrite is that it isn't inherited in the way that normal Apache directives are. If you've got RewriteRules in one htaccess, and then additional RewriteRules in a deeper htaccess along the same path, then the original RewriteRules will disappear as if they had never existed. You can add the line
RewriteOptions inherit
to the inner htaccess, but things will still not behave as expected.

Short version: Put all your RewriteRules in the same htaccess file. If the WordPress installation lives in a subdirectory, you'll need to make some adjustments. And you'll have to take extra care to keep backups, because any time you upgrade WP, it will try to overwrite the existing htaccess-- or it will add a new one in an unwanted place.

gasell




msg:4672048
 2:56 pm on May 18, 2014 (gmt 0)

Ahh, finally found a way to resolve this.

I forgot one obvious setting that must be configured somewhere on the server level that I don't have access to (shared hosting). Namely, that if you request / it looks for index.html, index.php etc. What I needed was a special case for index.php which exists at root level for my site but should redirect to WP anyway. If it doesn't exist another error is logged.

I currently have the following rewrites and everything I could think of checking seems to work as I want to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /subdir/$1 [L]

RewriteRule ^index\.php /subdir/ [L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

Let's hope I didn't break anything I didn't check :)

lucy24




msg:4672080
 7:56 pm on May 18, 2014 (gmt 0)

I forgot one obvious setting that must be configured somewhere on the server level that I don't have access to (shared hosting). Namely, that if you request / it looks for index.html, index.php etc.

You mean the DirectoryIndex directive. This can be used in htaccess, though it shouldn't be necessary, because shared hosts will always include "index.php" in their list. (The default is "index.html" alone.) You might need to change the order so it says

DirectoryIndex index.php index.html

where the default has .html first. Got a vague idea there was a pretty recent thread involving a site that sometimes had more than one index.xtn in the same directory.

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

If this is about extensionless URLs, you might want to express the pattern as
^([^.]+[^./])$
That way, the conditions are only evaluated when the request contains no . literal periods and doesn't end in / slash. You may need a supplementary rule covering requests in the form
example.com/directory
(no final slash) because search engines habitually* check these-- even if nobody anywhere has ever led them to believe the URL exists. Normally mod_dir handles these with an explicit redirect, but here your CMS RewriteRule overrides the behavior.


* Underlying assumption: If they do it to me they do it to everyone.

g1smd




msg:4674273
 7:36 pm on May 24, 2014 (gmt 0)

Where rule target is bare $1.php you need a small amendment.

For security reasons you should change that to /$1.php with a leading slash.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved