url rewriting slows down proxy a lot - .htaccess

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.

Related

Why htaccess not working for mobile browser?

I have website (mzadkm.com) try to RewriteRule short url to app.php page .
So if user browse "mzadkm.com/app" will show "mzadkm.com/app.php" page
RewriteRule ^/app /app.php [L,R=301]
It's work on Computer , but on mobile browser give me 404 page
Any ideas
That probably is what you are looking for:
RewriteRule ^/?app /app.php [L]
The documentation clearly says, that the pattern in a RewriteRule get's applied to the relative path of the request if the rule is implemented inside a distributed configuration file. That means you actually want to match the path app and not /app here. Which is why your rule did not get applied. The ^/?app is a variant to accept both path notations, relative and absolut, which means the same rule can get implemented in the central configuration or likewise in a distributed configuration file (".htaccess").
I took the liberty to also remove the external redirection you showed ("R=301") since that most likely is not what you want, according to the phrasing of your question. Instead you want an internal rewrite .
You need to take care however that you do not implement a rewriting loop. Which would result in failing requests and an "internal server error" (http status 500).
One approach would be that:
RewriteEngine on
RewriteRule ^/?app$ /app.php [L]
Here another one:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?app /app.php [L]
Why things looked fine on your computer, but not on a mobile browser is unclear. Since the same rules get applied and the requests look the same there has to be another reason for that. I suspect you looked at a cached result of a previous attempt somewhere. Remember to always use a fresh anonymous browser window when testing. And to check the response you receive back inside your browsers network console.

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]

Apply htaccess rewrite-rule on rewritten URL

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

removing file extension with htaccess failing

i'm using an htaccess script trying to remove the .php testing the .htaccess on a testing server it runs fine, but on the live server that is a different host it trys rewriting the file based on the absolute path and the rewrite fails
here is the htaccess:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
this is taking a url like this www.example.com/services
and trying to point it to /n/c/example.com/public/service.php
I know the {REQUEST_FILENAME} is suppose to be pulling the full local system path, but i don't understand why it's not finding the file. i know very little about htaccess and mod_rewriting so i'm not really sure what I should try to make it base everything off of just the url path, or if there is a better solution. I'm really open to suggestions.
Any help would be greatly appreciated.
Thanks
Use RewriteRule .* %{REQUEST_URI}.php [L]
It is hard to tell why your rule did not worked for you by having so little info about your Apache setup and any other rewrite rules that you may have.
Quite possible that the [L] flag did the trick for you -- you may have other rewrite rules that were rewriting this URL further, producing incorrect result in the end. I don't think that %{REQUEST_URI} did such a big job on its own, unless you have some symbolic links / aliases or even some transparent proxy in use which could make a difference.
Keep in mind, that the rules you have shown in your question cannot generate this sort of URL to be visible in browser's address bar (example.com//service.php/) -- it has to be a redirect (3xx code) involved .. which suggests that you have other rules somewhere.
Most likely it is a combination of your Apache specific settings & combined rewrite rules logic (where the L flag can make a big difference depending on those other rules).
The only way to give more precise answer will be enabling rewrite debugging and analyzing how rewrite was executed and what was involved.
Have you enabled mod_rewrite on the other server? AddModule mod_rewrite, I think.
Also - more likely - have you enabled .htaccess? You would need to have
AllowOverride All
or
AllowOverride FileInfo
for that.
These directives will need to go in the apache config files (usually /etc/httpd/conf/httpd.conf or one of the files in /etc/httpd/conf.d), and you will need to restart apache to get them to take effect.

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.

Resources