mod_rewrite "400 Bad Request" problem - mod-rewrite

I can't seem to get past a Bad Request error while setting up mod_rewrite. I've been trying for a while, so here's what I have.
The url I'm trying to access is:
gordons.local/brewCalc
The page I'd like to see is
gordons.local/index.php?page=brewCalc
Here's my rewrite rule:
RewriteEngine on
RewriteLog /var/www/gordons.com/logs/rewrite.log
RewriteRule ([^/]+)/?$ index.php?page=$1 [L]
I've used a regex tool, and this tool, but no matter what I end up with a page that says:
Bad Request
Your browser sent a request that this server could not understand.
Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request.
Apache/2.2.12 (Ubuntu) Server at gordons.local Port 80
Also, I'm not getting any information in my access, error or rewrite logs.
EDIT: My rewrite rules are in my vhost file. (/etc/apache2/sites-available/gordons.local)

In case anybody ever finds themselves here, my issue was a missing leading slash before the replacement.
RewriteRule ([^/]+)/?$ index.php?page=$1 [L]
Should have been
RewriteRule ([^/]+)/?$ /index.php?page=$1 [L]
Grrrr....

If you see Apache's error.log you would be able to see the actual error. Most likely you are trying to put above rules in .htaccess file and RewriteLog is not allowed in .htaccess file. Also your RewriteRule will redirect more than you intend. So if you comment out your RewriteLog and have your RewriteRule like this then it should work:
RewriteEngine On
RewriteBase /
# request is not for a file
RewriteCond %{REQUEST_FILENAME} !-f
# request is not for a directory
RewriteCond %{REQUEST_FILENAME} !-d
# forward to index.php
RewriteRule ^([^/]+)/?$ index.php?page=$1 [L,QSA,NC,NE]
NC - Ignore case comparison
NE - Do not encode RHS URI
QSA - Append existing Query String into new one
L - Mark it last rule

Related

.htaccess works in local but not on server (but no 404 error)

I have a .htaccess that is supposed to rewrite my URL. My host has told me that it supports URL rewriting, and I verified that by using phpinfo() and checking.
Anyways, this is my .htaccess:
RewriteEngine On
RewriteRule ^([_a-zA-Z0-9]+)$ index.php?page=$1 [R]
It works like a charm in local, but on my server, it doesn't do anything.
I checked this before on the internet and some people had it, but they all had a 404 error, while I don't have a 404 error. It simply doesn't redirect, it doesn't do anything, so I get all kind of error messages.
RewriteRule ^([_a-zA-Z0-9]+)$ index.php?page=$1 [R]
The regex in your rule doesn't match strings with slashes at any position. I am not sure that's acceptable and you don't give any request examples, but I don't think it is.
You may try this rule-set in one .htaccess file at root directory:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule ^([^/]+)/?$ index.php?page=$1 [L]
For permanent redirection replace [L] with [R=301,L].
You can make sure that the file (!-f) or directory (!-d) that you're matching doesn't exist before the rewrite. That way you don't end up with a 500 loop with something like /index.php?page=index. Additionally the ^ character is matching the beginning of the string, so if your original test was in a subdirectory it would not rewrite since you weren't allowing slashes.
This should work for any instance, however it will ONLY make the page variable the last string in the URI.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([_a-zA-Z0-9]+)$ /index.php?page=$1 [R,L]

Redirect URL with htaccess

A third party plugin returns to an incorrect URL from a call to save a change.
The URL is /admin/?page=configure/admin/. The correct return should be to /lists/admin/?page=configure. My attempt to write a redirect failed with a 500 server error.
RewriteEngine On
RewriteRule ^(.*)/admin/(.*)$ $1/lists/admin/$2 [NC,L]
How can I correct this code?
This should work.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^lists
RewriteRule ^(.*/)?admin/(.*)$ $1lists/admin/$2 [QSA,L]
If you want to match a different folder to redirect to admin you will have to declare it literally as a pattern like ^(.*)?/admin would also match lists/admin and cause a loop.

Rewriterules that result in 500 server error

I'm learning how to mod rewrite URLs and I encountered a 500 server error after having this .htaccess file in my root folder:
RewriteEngine On
RewriteRule ^([^/]*)$ /a.php?a=$1 [L]
It would be great if someone can tell me which part I got wrong, thanks
Include at least all basic directives and one condition to prevent loops. Like this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
# Prevent loops
RewriteCond %{REQUEST_URI} !a\.php [NC]
RewriteRule ^([^/]*)/? a.php?a=$1 [L]
Maybe that's what you need, although I did not test it because it is impossible without a sample of the incoming URL, which is missing in the question.

URL Rewrite to redirect a old host to a new host

I know nothing about Url Rewrites, but we have recently changed domain names from oldcompanyname.co.uk to newcompanyname.co.uk.
We have been told that to get oldcompanyname.co.uk to not show up in search results anymore, we need to redirect the old url to the new one.
I have installed ISAPI_Rewrite 3 but have not been successful in getting the re-direction to work.
On our development servers I've tried the following code without success to redirect any request to http://tm-devtest2/tmintranet to http://tm-devtest2/tmintranet.
# Helicon ISAPI_Rewrite configuration file
# Version 3.1.0.94
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*internet*$
RewriteRule ^$ http://tm-devtest2/tmintranet/ [R,L]
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !newcompanyname.co.uk$ [NC]
RewriteRule ^(.*)$ http://www.newcompanyname.co.uk/$1 [L,R=301]
The RewriteCond is only needed in case the same instance will serve both domains.
L means "Last", i.e. stop rewriting
NC means "no case"
R means Redirect
301 means "Permanently Moved"

Mod_Rewrite Difference between [L] and [R]

I am attempting to rewrite any URL with "_excaped_fragment_=/some/directory" to "/some/directory?ajax=1". The code below is working correctly but i would like to do it without the redirect. This is a Wordpress site.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
AddDefaultCharset UTF-8
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule (.*) %1?ajax=1 [L,R=301]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
If I remove "R=301" and just leave the "L" it does not work. I have read about [L] not stopping when from .htaccess, but i actually do not want it to stop. I would like it to just change the URL then go through the regular Wordpress rewrite.
Any ideas? Let me know if you need more information.
Edit:
Wanted to add an answerable question. Why does a redirect work and no redirect not work? Does the URL get changed as it works its way down the file or only on the last rule?
The [L] will stop any further processing in .htaccess if the rule matched.
The way you have this written the [L] will do that, but then you add [R=301] which is a redirect. That will cause the request to be sent back to the "top of the stack" in Apache for processing as if it was a completely new request, since you are doing a redirect. HOWEVER, now on the 2nd time through you've got the modified URL because the rewrite was processed before doing the hand-off.
In other words [L] does the mangling, then says "OK, we are done here, drop out to normal web processing now".
[L,R=301] does the mangling, then says "we are done with THAT, now got tell whomever is next is line that we've done a redirect".
That last part of the [L,R=301] triggers a whole new set of logic to process the "hey, we just got a redirect" rules. In your case, causing the entire rewrite sequence to be processed from the top with the mangled URL this time around.

Resources