Rewrite logic breaking? - mod-rewrite

I have the following rewrite logic in my vHost and everything seems to be working in regards to redirecting subdomains, but as soon as I add a path to the URI I'm getting an error in my apache_error.log.
Here is the rewrite logic:
RewriteEngine On
# Remove the www alias
RewriteCond %{HTTP_HOST} ^www\.13labs\.net$ [NC]
RewriteRule ^(.+)$ http://13labs.net$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^.+$
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|png|js|css|swf|php|ico|txt|pdf)$ [OR]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} !^www\.13labs\.net$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.13labs\.net$ [NC]
RewriteRule ^(.+)$ /index.php?subdomain=%2&kohana_uri=$1 [PT,L,QSA]
RewriteRule ^(.+)$ /index.php?kohana_uri=$1 [PT,L,QSA]
I am trying to hit admin.13labs.net/login, which should be rewriting to 13labs.net/index.php?subdomain=admin&kohana_uri=/login. However, in my apache_error.log I am receiving the following:
[Mon Aug 30 23:56:06 2010] [error] [client 74.63.151.37] File does not exist: /var/www/13labs.net/html/login
Any clues? I've been playing around with this for about an hour now and I'm stumped...
Regards,
Andrew

Your second rewrite rule (with its corresponding conditions) looks like it'll stop rewrites for any URL. It matches if the file doesn't have the right extension, OR isn't a file, OR isn't a directory, OR isn't a link. No resource can be a file and a dir and a link at the same time, so all URLs will match -- and they'll all get passed as is, since your [L] flag prevents any subsequent rewrites.
If your intention is to prevent rewrites for URLs that correspond to existing files, links, or directories, remove the !'s from your conditions and remove the [OR] from the condition that checks the file extension.

Related

Why isn't this mod_rewrite re-directing?

I'm sending every request through an index.php except for pages in my blog subdirectory. I've been able to do this using mod_rewrite in my parent folder and;
RewriteCond %{REQUEST_URI} !^/blog
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
]
However, I'd also like to send requests to my blog folder if they have the form:
documentation/some-file.
I've tried:
RewriteRule ^/documentation/(.+)$ https://www.some_domain.com/blog/documentation/$1
but it looks like my request isn't getting sent to the blog folder in this case. My full code is below:
RewriteEngine On
#redirect to index.php as appropriate
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^/documentation/(.+)$ https://www.some_domain.com/blog/documentation/$1
RewriteCond %{REQUEST_URI} !^/blog
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
Edit:
I've used a slightly modified version of #Rijul's suggestion below and after moving the RewriteRule to before the RewriteCond, it works as I had hoped. In other words, the re-write for documentation performs the re-write to the blog subfolder. And, all other requests go through my index.php file. At this point, I would like to understand why.
RewriteEngine On
RewriteRule ^documentation/?(.*)$ /blog/documentation/$1 [R=301,L]
#redirect to index.php as appropriate
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
From what i know
RewriteEngine On
Without this all the rewrite rules and condition will be ignore
RewriteRule ^documentation/?(.*)$ /blog/documentation/$1 [R=301,L]
Rewrites documentation to blog/documentation
RewriteCond %{REQUEST_FILENAME} !-d
This rewrite condition checks whether the requested directory name doesn't exits. If it doesn't exits. Then proceeds to the next condition
RewriteCond %{REQUEST_FILENAME} !-f
This rewrite condition checks whether the requested file name doesn't exits. If it doesn't exits. Then proceeds to the next condition
RewriteCond %{REQUEST_FILENAME} !-l
This rewrite condition checks whether the requested symbolic link doesn't exits. If it doesn't exits. Then proceeds to rewrite rule
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
Rewrite to index.php?url=
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
writing rewrite condition like this produces an and operation.
(no file exits in that name) and (no directory exits in that name) and
(no symbolic link exits in that name)
If this is true then rewrite to php file. (no directory exits in that name) will go false in the case for /blog (since such a directory exits)

Mod_rewrite to switch HTTP to HTTPS

I am trying to use a Bluehost supplied SSL wildcard certificate to switch one subdomain to HTTPS.
The web root contains many subdomains, and I only want to affect the test. subdomain.
Going into the web root, I've written the following .htaccess file:
RewriteCond %{SERVER_NAME} ^test.mydomain.com
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}$1
Yet hitting http://test.mydomain.com/admin/index.php does not redirect me to https://test.mydomain.com/admin/index.php.
Even cutting out the Condition of SERVER_NAME, it still doesn't work.
Is my rewrite rule bad?
Well, in the first place I was in the wrong .htaccess file. I needed to go to the directory for my subdomain.
Then, simply switching it from HTTP to HTTP apparently causes some kind of redirect to www. behavior.
I had to
A) Preserve the existing rules that were not intended for test.
B) Add the test. rules.
It added up to a lot.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^test.example.com$
RewriteRule ^index\.php$ - [L]
RewriteCond %{HTTP_HOST} !^test.example.com$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{HTTP_HOST} ^test.example.com$
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{HTTP_HOST} ^test.example.com$
RewriteCond %{REQUEST_URI} !^/test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /test%{REQUEST_URI}
RewriteCond %{HTTP_HOST} ^test.example.com$
RewriteRule ^(/)?$ test/admin/index.php [L]

Why am I getting a Redirect Loop for the following RewriteRules?

I'm getting a Rewrite Loop error for the following:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^mysite.com [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/(apps|site).* [NC]
RewriteRule .* http://site.mysite.com/ [R=301,L]
Why is this happening, what am I missing?
I've tested the following URLs, and they seem to redirect ok:
www.mysite.com/
www.mysite.com/apps
www.mysite.com/apps
mysite.com/
mysite.com/apps
mysite.com/apps/about
mysite.com/site
BUT
www.mysite.com/site
does not want to redirect, the rest all redirects to http://site.mysite.com as expected?
It turns out we had a site folder in our public, which somehow got the action before the .htaccess. Not sure why this happened, but upon removing this redundant folder, everything is working 100%

Friendly URL for images

Please suggest me what to put into .htaccess file.
I have PNG, GIF, JPG images on server http://domain.tld/images/anyimage.anyextension
Want to make URLs more friendly like a http://domain.tld/anyimage.anyextension
This I have now. First two strings change links as described. But last string doesn't change it back for server.
RewriteCond %{REQUEST_URI} ^/images/(.+)(\.gif|\.jpg|\.png)$ [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /images/$1 [L]
If I add
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/image/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /image/$1 [L,NC]
Right after previous query string rule then images don't open. If before there's no problem. What it could be? Do you have an idea how to fix it? The last string RewriteRule ^/?(.+)$ /?$1 [L] cause this conflict
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /\?([^\ ]+) [NC]
RewriteRule ^$ /%1? [R=301,L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.+)$ /?$1 [L]
Not sure how that makes it more friendly, aside from it being shorter. You can try adding this to the htaccess file in your document root:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/images/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /images/$1 [L,NC]
Then you can change all of your links from http://domain.tld/images/anyimage.anyextension to http://domain.tld/anyimage.anyextension
The first condition checks to make sure the request is for anyimage.anyextension, as long as the extension is a case-insensitive png, gif, or jpg.
The second condition checks to make sure the requested image actually exists in the /images/ directory.
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /images/(.+)(\.gif|\.jpg|\.png) [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
This redirects the browser to the non-/image/ URL. There's 2 completely different things going on here. One deals with the browser and the other deals with content on the server. See the top part of this answer that explains how they are different.
The rules that you have won't work. First:
RewriteRule ^/(.+)$ /images/$1 [L]
will never match. URI's used to match against the regex of a RewriteRule in htaccess files have the leading slash removed, so no URI is going to start with a /. You need to get rid of it.
Secondly, once you do, you'll get a 500 internal server error because your rules will cause an internal infinite loop. You need to match against %{THE_REQUEST} to ensure that a browser is actually requesting a URL with the /images/ path in it, not what has been internally rewritten.

How do I write a custom mod_rewrite .htaccess file for CakePHP routing?

I've rewritten my web app using CakePHP, but now I need to have my old formatted urls redirect to my new url format. I can't seem to add my own custom mod rewrite rule. I've added it above the main cakephp rewrite rule, but I'm getting an infinite redirect loop. I just want http://mysite.com/index.php?action=showstream&nickname=user to redirect to http://mysite.com/user before the cakephp rewrite happens.
EDIT: Ok, so now when the condition is met it's redirecting but it's appending the original query string to the end. I'm assuming that's due to the QSA flag in CakePHP rewrite rules, but I was under the impression the "L" in my rule would stop that from executing...
RewriteEngine On
RewriteCond %{QUERY_STRING} ^action\=showstream&nickname\=(.*)$
RewriteRule ^.*$ http://mysite.com/%1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
When you do a capture inside the RewriteCond line instead of the RewriteRule, you have to reference the capture with %N instead of $N. That is, your RewriteRule line should be:
RewriteRule ^index.php$ /%1 [R=301,L]
Try to test the request line (THE_REQUEST) to see what URI originally has been requested:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /index\.php
RewriteCond %{QUERY_STRING} ^action=showstream&nickname=([^&]*)$
RewriteRule ^index\.php$ /%1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php?url=$0 [QSA,L]
But maybe it would be easier to do this with PHP.

Resources