Apply htaccess rewrite-rule on rewritten URL - .htaccess

Is it possible to apply a .htaccess rewrite-rule on an already rewritten URL?
Example:
I want to resize my pictures with timthumb.php (most recent version, so there should be no security flaw any more). But the URL should look fine, therefore I created this rewrite-rule:
RewriteRule ^rz/(.*)x(.*)/r/(.*) /themes/Nerdtalk/timthumb.php?src=$3&h=$2&w=$1&q=80
This rule is working fine, but before starting timthumb.php which may re-direct to a cached file, I want Apache to check, if the file exists and let Apache redirect to the cached file, so timthumb.php won't be started.
Therefore I created this ruleset:
RewriteCond %{SCRIPT_FILENAME} timthumb.php
RewriteCond %{QUERY_STRING} src=(.*)\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&q=([0-9]+)
RewriteCond %{DOCUMENT_ROOT}/cache/%1-%4-%3-1-%5.%2 -f
RewriteRule ^.* /cache/%1-%4-%3-1-%5.%2 [L]
Can an already rewritten URL be rewritten a second time?
Is the second part correct?
If there is a possibility to merge these two rulesets, can you please tell me how?

Can an already rewritten URL be rewritten a second time?
Yes. When rewrite occurs (rule with the [L] flag or end of htaccess), mod_rewrite goes to next iteration and starts matching all rules again from start. That's why you need to build your rules with rewrite loop in mind (especially if you use this sort of pattern ^(.*)$ for matching).
If you write a rule without [L] flag, then rewrite continues on the same iteration, so any rules placed below current may rewrite URL again to a completely different.
Is the second part correct?
I would say Yes (although not checking on the actual Apache). I'm just not sure about first rewrite condition (just never used %{SCRIPT_FILENAME} myself so unsure how exactly it works) -- I would use %{REQUEST_URI} timthumb\.php$ or something like that.
The only thing that I would add is ? at rewrite target to get rid of newly created (1 rule above) query string: RewriteRule ^.* /cache/%1-%4-%3-1-%5.%2? [L]. But it should work fine as is now.
If there is a possibility to merge these two rulesets, can you please
tell me how?
Place them one after another in the same order you have here. You cannot make it a single rule as 2nd rule will only work if thumbnail is already cached.
If it will not work straight away (as Apache's variables (%{SCRIPT_FILENAME}, %{QUERY_STRING} etc) may not have proper values straight away) try adding [L] flag to first rewrite rule -- it will force next iteration which populates those variables with proper values for sure, and, depending on the rest of your rules that you may have before this one, it will reach 2nd ruleset where 2nd rewrite will occur.
If you want -- you can rewrite it completely to check and serve cached file straight away (if present) and then (if still nothing) rewrite image to be processed by timthumb.php, but that will do exactly the same job as aforementioned rules, just a bit differently.

Can an already rewritten URL be rewritten a second time?
Yes, it can. It's default behaviour and if you would want to change it, you could use flags like [L]:
http://httpd.apache.org/docs/current/rewrite/flags.html
Is the second part correct?
I'm not sure if you can use %1 etc. in RewriteCond directive
If there is a possibility to merge these two rulesets, can you please tell me how?
I would put cache in the same folder as your original url: ^rz/(.)x(.)/r/
If it exists - just serve it, if not - use php

Related

Htaccess replace one image with another one

So Ive been making a code which replaces one image with another without changing the link.
So heres the code that I found on one of the forums.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
</IfModule>
So this code not only redirects user to another page but also to a random link.
So original link is http://toss.rf.gd/storage/fredShip1.png though it should have replaced the image with http://toss.rf.gd/storage/fredShip2.png(Just an example) but it sends the user here toss.rf.gd/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
I added the image too ->
The image
I am really bad at htaccess so make sure correct me if Im wrong. Also english is not my first language so expect some minor mistakes.
EDIT : So i solved the problem with redirection to a random link. But Im still wondering is it possible to just change the image without changing the link?
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
The code you've posted already does essentially what you require, except that you need to adjust the paths to match your example. The "problem" with the above rule is that it rewrites the request to /fredShip2.png (in the document root), not /storage/fredShip2.png as in your example.
Assuming the .htaccess file is in the document root of the site and you wish to internally rewrite the request from /storage/fredShip1.png to /storage/fredShip2.png then you would do it like this:
RewriteRule ^storage/fredShip1.png$ storage/fredShip2.png [L]
There should be no slash prefix on the URL-path in either argument.
If you have other directives in your .htaccess file then the order of these directives can be important.
Make sure you've cleared your browser cache before testing.
but it sends the user here example.com/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
That's not possible with the directive you've posted. This is most likely a cached redirect due to an earlier (erroneous) experiment with 301 (permanent) redirects. For example, something like the following would produce the above "erroneous" output:
RewriteRule fredShip1\.png$ storage/FredShip2.png [R=302,L]
Note the use of the R (redirect) flag and the lack of a slash prefix on the RewriteRule substitution string (2nd argument). Since the substitution string is "relative", the directory-prefix (ie. /home/vol8_1/[Account info]/htdocs/ in your example) is prepended to substitution and since this is an external redirect (as denoted by the R flag) this then exposes the absolute filesystem path to the user.
NB: The above is a 302 (temporary) redirect - so should not be cached by the browser (at least not by default).

htaccess: act as if files were in another directory, but RewriteRules seem to be mutually exclusive

For files in several subdirectories of /data/, I would like to treat them (and the files inside them) as if they were in the root directory.
So,
1) a request to
/data/foobar/file.png
should redirect the browser to
/foobar/file.png
2) any requests to
/foobar/file.png
should respectively deliver the file /data/foobar/file.png, but without redirection.
For 1) I got the following rule working
:
RewriteCond %{REQUEST_URI} ^(.*)?data/((foobar|and|some|other|subdirs)/.*)$
RewriteRule .* %1%2 [R=301,L,qsappend]
(I took this approach usind a RewriteCond with %x references in order to be subdirectory-agnostic, as in my dev environment the page is located in a subdirectory as opposed to the live system where it's in the root of the domain.)
And for 2) the following rule does the trick:
RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/$1 [L,qsappend]
However, these rules only work if I enable one at a time. If I enable both of them at the same time, the browser will abort the request with a "too many redirects" error. The redirect from /data/* to /* will work, but then end in the aborted request just the same as calling the URL without /data/*.
I'm having a hard time understanding why this is happening. It would be totally logical if both rules actually triggered a redirect. But as far as my understanding of htacccess goes (and the Network tab of the dev console seems to confirm that conception), the client shouldn't even know for case 2) that the file is not actually there. So why does this apparently still count towards the redirection limit?
Is there something fundamental I'm missing? And how can I achieve what I'm trying to achieve?
This is because you first redirect and then rewrite the same Uri . Your second rule is conflicting with with the first one.
You need to match against %{THE_REQUEST} instead of %{REQUEST_URI} to avoid the redirect loop
RewriteCond %{THE_REQUEST} \s(.*)?data/((foobar|and|some|other|subdirs)/.*)\s
RewriteRule .* %1%2 [R=301,L,qsappend]
RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/$1 [L,qsappend]

htaccess reditect if server returns 404

For example I have a page http://www.f1u.org/en/its-interesting/166-cricri.
How to write rule: if that page exists - open it.
If it returns 404, then redirect to http://www.f1u.org/its-interesting/166-cricri
use this line in .htaccess file
ErrorDocument 404$ http://www.f1u.org/its-interesting/166-cricri
It sounds like you want the apache server to look ahead to see if the current URL exists, if not, redirect them. I think you might be able to use mod_rewrite to accomplish this.
My first stab at it would be something like:
RewriteEngine On
RewriteCond %{IS_SUBREQ} false
RewriteCond %{REQUEST_URI} !-U
RewriteRule /en(/.*) $1 [R,L]
I'll note that I haven't tried it so the syntax and effects could be slightly off, and you'd need to be careful that you don't put yourself into an infinite loop, or wind up with too many subrequests (as that could impact the performance of your server). But hopefully it'll give you a starting point to play with. Alternatively mod-rewrite could (depending on server permissions) let you invoke scripts to determine rewrites as well, which could be an option as well.

URL rewrite conditions in htaccess file

I need some help with .htaccess. I've been using URL rewrites, but not conditions, and I'm pretty sure I need them seeing as I can't get this working.
The URL structure I need is -> forum/catnamehere (which shows the page called catnamehere)
and child structure -> forum/catnamehere/fornamehere (which shows the child page of the cat)
However, somehow I fail to do this, making me believe I need conditions.
You should be able to do this with two rules.
Put your .htaccess file in the forum directory, and add the following:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)(/?)$ complexForumPath.php?catName=$1 [QSA]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)(/?)$ complexForumPath.php?catName=$1&subPage=$2 [QSA]
The first rule will grab stuff like forum/abc123_
And the second rule will grab forum/abc123_/abc123_

url rewriting slows down proxy a lot

i have a proxy script which writes very ugly long URL. the proxy script automaticaly rewrites all href links with long ugly URL,
mysite.com/proxy.php?url=somesite.com
mysite.com/proxy.php?url=somesite.com/somedir
mysite.com/proxy.php?url=somesite.com/somedir/somepage.php
to fix this i have done 2 things
edit the proxy script so that all
href links are rewritten as
mysite.com/somesite.com
added a rewrite rule in .htaccess so that short
URLs now rewrite...
mysite.com/somesite.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ proxy.php?url=$1 [L,QSA]
the problem is that, whenever i click a link on a proxy loaded page, it seems to take a lot longer than before i did all this cosmetic work. is something wrong with my rewrite rule ?
The test you've written does two file tests (if 'not-file' and 'not-dir') and if they are true, it will execute your RewriteRule. This test is done for every request. Even if the result would've otherwise only required a HTTP 304 (not modified) response or when the actual files are currently held in memory by Apache.
It's possible that this slows down your site significantly if it contains many (server/client cached) images or other resources. To prevent this, try to filter without the need to access your file system. Filter as much as possible by using a regular expression. The easiest way to do this is by changing the URI path part to something unique, for instance example.com/u=somesite.com or even example.com/p/somesite.com (p for proxy)).
Your tests will be much faster if all you need to do is a regular expression pattern match as opposed to two file-existence tests (example for example.com/p/somesite/etc/....):
RewriteCond %{REQUEST_URI} ^/p/
RewriteRule ....
Update: expanded a bit and added small example
PS: even if you do not want to change your current brief URI scheme, you can use this pattern temporarily to test whether it changes performance for the better.

Resources