htaccess check for one place then another after rewrite - apache

After fiddling around with htaccess for hours upon hours I can't seem to get this just right.
What I need to do is when I try and grab an image (say example.jpg) from /images/, it should firstly be redirected to images/e/example.jpg and if it is not found there it should be redirected back to images/example.jpg.
What's strange is I can manage the other way round (i.e check for it in images/example.jpg first then go to images/e/example.jpg)
I would imagine it would be something like this:
#This redirects to images/{first letter}/image.jpg
RewriteRule ^images/([^/])([^/]*)$ /images/$1/$1$2 [L]
#Checks to see if it exists, if not redirect it back to the original request
RewriteCond images/e/example.jpg -f
RewriteRule ^(.*)$ $1 [L]
Obviously the rewrite condition should be dynamic for the first letter of the file but I don't know how to do that.
Any help is kindly appreciated, thank you.

You can use this rule in your root .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/images/$1/$1$2 -f [NC]
RewriteRule ^images/(\w)([^/]+?\.jpe?g)$ /images/$1/$1$2 [L,NC,R=302]

Related

.htaccess rewrite for category with pagination

I'm trying to write a mod-rewrite rule to handle pagination links on my site.
I'd like my URL structure to be this https://example.com/category.php?name=category-link to https://example.com/category/category-link [without pagination]
and https://example.com/category.php?name=category-link&page=2 to https://example.com/category/category-link/2 [with pagination]
I've tried the following:
RewriteRule ^category/([0-9a-zA-Z-]+)/([0-9]+) category.php?name=$1&page=$2
https://example.com/category/category-link isn't working
https://example.com/category/category-link/1 is working
2. am i able to redirect localhost/article/4/ to localhost/article/4 [here 4 is an id]
Any guidance would be much appreciated.
Could you please try following, based on your shown samples only. Please make sure you clear your browser cache after placing these rules into your htaccess file.
RewriteEngine ON
RewriteCond %{REQUEST_URI} ^/category/([0-9a-zA-Z-]+)/?$ [NC]
RewriteRule ^(.*)$ category.php?name=%1 [L]
RewriteRule ^category/([0-9a-zA-Z-]+)/([0-9]+)/? category.php?name=$1&page=$2 [L]
OR you could use it without RewriteCond too. Make sure you are putting either of these NOT both of them please.
RewriteEngine ON
RewriteRule ^category/([0-9a-zA-Z-]+)/?$ category.php?name=$1 [L]
RewriteRule ^category/([0-9a-zA-Z-]+)/([0-9]+)/? category.php?name=$1&page=$2 [L]

Mod Rewrite, Unexpected Results

We are trying to redirect everything from one domain to another with the following
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .? http://www.example2.com%{REQUEST_URI} [R=301,L]
When we visit http://www.example.com/v2sc
We are being redirected to http://www.example2.comv2sc
We would like to be redirected to http://www.example2.com/v2sc considering www.example2.comv2sc is not a valid hostname
Any ideas on how we can accomplish this?
Thank you!
It seems like you're using a .htaccess file for this. In that context the leading slash is not present in %{REQUEST_URI} so it's up to you to put it back in.
RewriteEngine On
RewriteCond %{HTTP_HOST} !=www.example.com
RewriteRule ^ http://www.example2.com/%{REQUEST_URI} [R=301]
Please also note that solutions like this should be used only if you cannot edit the main server configuration file. Doing so would allow you to use a cleaner combination of vhosts and Redirect directives that would run much more quickly.

How do I make .htaccess do what I want? :) (appending query string to url)

Currently my .htaccess looks like this...
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1.php [L,QSA]
It currently changes any /xxx.php file into /xxx. This is great for SEO. However, I also want Mr. htaccess to convert certain URLs into a URL + query string. For instance when user goes to
/specific/somerandominfo
Then somerandominfo is passed to the specific.php file. I normally have no problem doing this using rewrites, but because of my fancy catchall rewrite, I can't figure out how to do it.
For example if I add
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC]
to my .htaccess, then hitting up /specific/somerandominfo just serves me a big fat 500 Internal Service Error.
Any help from you apache gurus out there would be so, so cool.
Thanks!
p.s. anybody want to also throw in any other cool SEO tricks that they like? I'll bake you cookies.
You are getting 500 error because your rules are creating an infinite cycle. Check apache error log to see if it is true. So you should design your rules properly. Maybe like that:
RewriteRule ^([^/]*)$ $1.php [L]
RewriteRule ^(.*)/(.*)$ $1.php?var=$2 [L]
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC]
This is mostly correct. I'd just add the B flag, like this:
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC,B]
This causes the capture group $1 to be properly escaped for use in query strings. Note that you can still use QSA to retain the query parameters used in the original request (in addition to somerandominfo).
Perhaps you'll want to post your actual RewriteRule.

htaccess reference problem

I have this htaccess code:
RewriteEngine on
RewriteBase /xm/
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^([a-z0-9]*)\.php$ index.php?page=$1
And I want that when the user goes to, for example, main.php, that this htaccess redirects to index.php?page=main, but every time, and with every page, it redirects to index.php?page=index, and page is equal index no matter what. What am I doing wrong?
EDIT: works fine with numbers (eg 4.php) but not with letters :/
It's rewriting again on the subrequest. Put [NS] to the right of it so it'll only get rewritten once.
Try this:
RewriteCond $1 !^index$
RewriteRule ^([a-z0-9]+)\.php$ index.php?page=$1

Why is Apache mod_rewrite not behaving as expected

I want to redirect URLs from an old site that used raw URL requests to my new site which I have implemented in CodeIgniter. I simply want to redirect them to my index page. I also would like to get rid of "index.php" in my URLs so that my URLs can be as simple as example.com/this/that. So, this is the .htaccess file I have created:
RewriteEngine on
Options FollowSymLinks
RewriteBase /
RewriteCond $1 ^assets
RewriteRule ^(.*)$ example/production/$1
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ index.php? [R=301]
RewriteCond $1 !^(index\.php|example|robots\.txt)
RewriteRule ^(.*)$ index.php/$1
It should also be noted that my index.php is actually a symlink to example/production/index.php.
Now, the first rule works as expected - all my styles and images show up just fine, it's the second two rules I'm having trouble with. The second rule is basically to destroy the query string and redirect to my index page (externally). So, I found this in the Apache manual:
Note: Query String
The Pattern will not be matched against the query string. Instead, you must use a RewriteCond with the %{QUERY_STRING} variable. You can, however, create URLs in the substitution string, containing a query string part. Simply use a question mark inside the substitution string, to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine a new query string with an old one, use the [QSA] flag.
However, when I try to access one of the old pages, instead of redirecting to my index page, I get a 404 page not found error. I have figured out a workaround by making it an internal redirect, but I would really like it to be external.
The next problem, and the one that has been baffling me the most is with the third rule. I would expect this to do something like the following. If I type in:
http://example.com/this/thing
I would expect it to re-route to
http://example.com/index.php/this/thing
Unfortunately, this does not work. Instead, no matter what I type in, it always routes to my index page as if nothing else was in the URL (it just goes to http://example.com/).
Furthermore, and even more confusing to me, if I replace that rule with the following:
RewriteCond $1 !^(index\.php|example|robots\.txt)
RewriteRule ^(.*)$ index.php/this/thing
If I type in a URL such as http://example.com/other/thing, then it will go to http://example.com/index.php/this/thing as expected, BUT if I type in http://example.com/this/thing it goes to http://example.com/ (my index page). I can't make heads or tails out of it. Any help would be greatly appreciated.
This should solve your index.php problem and it will simply detect if a robots.txt is available:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
hmmm - this doesn't seem to work either. The problem is my URLs aren't really asking for a filename or directory anyway. For example: example.com/index.php/this/thing should call the 'thing' method of the 'this' controller. – Steven Oxley
The condition is: If request is NOT a file and NOT a directory, so that was right, what you should have done is combine the appending of the request string:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]