Htaccess file override with fallback to original - linux

I am trying to understand what an overriding system looks like in apache htaccess. Is it possible to override files in webroot/foo/ with those in webroot/foo/override recursively? For example in a request for webroot/foo/sub/sub3/file.txt i would like to return webroot/foo/override/sub/sub3/file.txt if it exists, or fall back to the original file webroot/foo/sub/sub3/file.txt and ultimately to a 404 error if it's a miss.
Also, is htaccess the best place to do such thing?

Use %{DOCUMENT_ROOT} here like this :
RewriteEngine On
RewriteCond %{THE_REQUEST} /foo/(.*)\sHTTP.*$
RewriteCond %{DOCUMENT_ROOT}/foo/override/%1 -f
RewriteRule ^foo/(.*)$ /foo/override/$1 [L,R]
These rules will capture a part of request after /foo then check if it the request is valid by adding /override otherwise , be as is so, either being correct request or handled as wrong request but, you should add rule to handle a wrong request if not existed in your original rules.
Note: change R to R=301 if the rules above are ok

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 for missing images with wildcards

I have a folder full of product images. And the image file name is something akin to:
/images/product_15_small.jpg
/images/product_15_large.jpg
/images/product_201_small.jpg
/images/product_201_large.jpg
/images/product_47502_small.jpg
/images/product_47502_large.jpg
If there is an error in the upload process and one of the files doesn't get created, say /images/product_201_large.jpg, I'd like Apache to replace that file with this file: /images/missing_0_large.jpg.
And in the case of the smaller image, I want it to be replaced with: /images/missing_0_small.jpg.
I'm not sure how to do conditional RedirectMatch using HT access and a wildcard. Could someone guide me? Here are the rules that I've tried to experiment with but none of them worked:
#TEST 1:
RedirectMatch 404 ^images/product_(\d+)_small.jpg images/missing_(\d+)_small.jpg
RedirectMatch 404 ^images/product_(\d+)_large.jpg images/missing_(\d+)_large.jpg
#TEST 2:
RewriteRule ^images/product_(\d+)_small.jpg images/missing_(\d+)_small.jpg [L]
RewriteRule ^images/product_(\d+)_large.jpg images/missing_(\d+)_large.jpg [L]
From the example above, "TEST 1" doesn't work however it seems to be the most logical format.
"TEST 2" does work, but it always redirects, and I want it to only redirect when the target file is missing (during a 404).
RewriteRule ^images/product_(\d+)_small.jpg images/missing_(\d+)_small.jpg [L]
RewriteRule ^images/product_(\d+)_large.jpg images/missing_(\d+)_large.jpg [L]
You need to check that the requested file does not exist before rewriting the request. These two rules can also be combined into one.
The substitution string (2nd argument) is also erroneous. From your example, it should be 0, not (\d+) (which is a regex and has no place here).
For example:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/product_\d+_(small|large)\.jpg$ images/missing_0_$1.jpg [L]
The $1 backreference contains either "small" or "large" captured from the RewriteRule pattern against the requested URL-path.
Note that this is an internal rewrite. The "missing" image is displayed with a 200 OK response, not a 404.
#TEST 1:
RedirectMatch 404 ^images/product_(\d+)_small.jpg images/missing_(\d+)_small.jpg
RedirectMatch 404 ^images/product_(\d+)_large.jpg images/missing_(\d+)_large.jpg
There are several problems here.
By serving a 404. You are doing just that... serving a 404 only, not "redirecting" to the desired "missing" image. In fact, in this instance, the very presence of the 3rd argument (the target URL) would actually trigger an Internal Server Error (500 response) on Apache. (I assume that's what you mean by "doesn't work"?)
The URL-path matched by the RedirectMatch directive starts with a slash, so these directives will not match the requested images.
Using RedirectMatch it's not possible to determine whether the requested image exists or not (you need to use mod_rewrite, ie. RewriteRule and RewriteCond).
Using RedirectMatch you would need to trigger an external redirect to the required image. (You need to use mod_rewrite to internally rewrite the request.)

Redirects not working as expected

I have an .htaccess file with several lines. It does not work as expected. Mod_rewrite is enabled. RewriteLogLevel is set to 9.
The first two rules are there to forbid uris with a length more then 80 characters:
RewriteCond %{REQUEST_URI} ^.{80}
RewriteRule .* - [F]
It does not seem to get evaluated as every test url passes through and it does not generate an error either.
I also tried:
RewriteRule .{80} - [F]
But that did not do the trick either. The process ends with a 404, not a 403.
This next rule is not working either. It used to work.
RewriteRule ^(\/)?([\w]+)$ /index.php [L]
The URI /Contact was always handled by this index.php.
Whatever URL I type I get a 404. I should get a 403 or a 200. Not a 404. What am I missing?
Apache has on all directories the permission to read, write and execute and on all files the permission to read and write.
The two urls for testing are:
127.0.0.4/asssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssddddddddddddddddddddd?p=s&s=psv
and
127.0.0.4/Contact
The alias for 127.0.0.4 used is considerate.lb.
Try this rule instead:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+\S{80}
RewriteRule ^ - [F]
Using THE_REQUEST instead of REQUEST_URI as that variable might get overwritten due to presence of other rules in your .htaccess
Finally I have found a solution. The problem was not in the coding of the .htaccess. I replaced the file with a previous version, added the new lines to test the request and it worked all fine.
It is not a satisfactory solution, because it can happen again and I do not have any clue what caused the error. If someone knows the error, I would love to hear what might have been the exact cause and how to solve that properly. I would like to change the tags of the question as the current tags might be misleading (although other people might experience the same problem how apache handles a .htaccess file), but I do not know which tags I should use.

.htaccess rewrite rules not working

I am using scssphp for my css preprocessing and right now my styles look like src="style.php/style.scss". What I was wanting is to use a htaccess to just write in the style and then anything ending in .scss would get run through style.php. So I tried putting this in my home directory.
RewriteEngine On
RewriteRule ^(.*)\.scss$ style.php/$1.scss
I even tried
#RewriteEngine On
#RewriteRule ^(.*)\.scss$ style.php/style.scss
Neither work, something is happening, because my style.scss is loading with a 500 internal server error, but I'm not sure where the error is.
Your rules are looping, try adding an additional check to not rewrite when the URI has style.php in it:
RewriteEngine On
RewriteCond %{REQUEST_URI} !style\.php
RewriteRule ^(.*)\.scss$ style.php/$1.scss
The rewrite engine will continue to loop through your rules until the URI stops chanmging. What's happening with your rule is that a request like /path/style.scss is getting procfessed and rewritten to /style.php/path/style.scss, and the the rewrite engine loops. The second time around, the rule gets applied again and it rewrites to: /style.php/style.php/path/style.scss, etc.
a better regex to get requested file name would be [a-z_A-Z]+.scss
try your htaccess using this syntax

.htaccess dynamic to static URL

I'm trying to make my dynamic URL's into static looking URL's.
This is a typical URL that I now have:
http://www.somedomain.com/design/index.php?p=about
I would like it to be: http://www.somedomain.com/about
So far, I've gotten it to look like this: http://www.somedomain.com/design/about.html
This is the Rewriterule I'm using: RewriteRule ^([a-z]+).html$ index.php?p=$1 [L]
How would I modify it so it would look like this: http://www.somedomain.com/about?
Thanks for any/all help!!!
Very much appreciated!
Using rewrite rules to give 'static' URI is NEVER a good idea.
A few other ideas you can use:
Make the 'about' page a directory (folder) with a file called index.php or index.html in it. This way the URL shows http://example.com/about/ and the information you wish can still be displayed as needed.
Use the POST method instead of GET methods. This will display as http://example.com/about.php (Note: there is no ? or other parameters behind that.)
Utilize both methods to give a 'seamless' URI on page transitions.
Rick, you're on the right track. You need to read the Apache rewrite documentation. For your docroot/.htaccess start it with:
RewriteEngine On
RewriteBase /
Then generalised version of your rule:
Rewrite Rule ^(\w+)$ index.php?p=$1 [L]
This will rewrite any requests which are for a word string to index.php. You need to be aware that the rewrite engine rescans the .htaccess file if a match has occured so you need to make sure that you don't create a loop. In this case the replacement string has a "." in it and the pattern doesn't, so this won't occur, but for more complex cases you may need to 'guard' the rules with one or more RewriteCond statements. Again, read the Apache documentation.

Resources