.htaccess for missing images with wildcards - .htaccess

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.)

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 301 redirect keep sending to the wrong page

I am trying to redirect an old page from a website I have redesigned, to the new one, but it's not working.
Here's my 2 lines of code in the .htaccess file regarding that domain:
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
RewriteRule ^/deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L,QSA]
If go on the solutionsgtr.ca/deaneco/contact URL, it gives me the following page:
http://solutionsgtr.ca/fr/deaneco/accueil.html/contact
The first rule works though (deaneco/ to solutionsgtr.ca/fr/deaneco/accueil.html).
I feel like both lines are being mixed together and are giving me the wrong page, that doesn't exist so I get a 404 error.
There are a couple of issues here:
The Redirect directive (part of mod_alias) is prefix-matching and everything after the match is appended on the end of the target URL. This explains the redirect you are seeing.
The RewriteRule (mod_rewrite) pattern ^/deaneco/contact will never match in a .htaccess context since the URL-path that is matched does not start with a slash. So, this rule is not doing anything currently.
You should avoid mixing redirects from both modules since they execute independently and at different times during the request (mod_rewrite executes first, despite the apparent order of the directives).
Either use mod_alias, ordering the directives most specific first:
Redirect 301 /deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
NB: You will need to clear your browser cache, since the erroneous 301 (permanent) redirect will have been cached by the browser. Test with 302 (temporary) redirects to avoid potential caching issues.
OR, if you are already using mod_rewrite for other redirects/rewrites then consider using mod_rewrite instead (to avoid potential conflicts as mentioned above):
RewriteEngine On
RewriteRule ^deaneco/contact$ http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L]
RewriteRule ^deaneco$ http://solutionsgtr.ca/fr/deaneco/accueil.html [R=301,L]
The QSA flag is not required, since the query string is passed through to the substitution by default.
The order of the RewriteRule directives are not important in this instance, since they match just that specific URL.
If go on the solutionsgtr.ca/deaneco/contact URL
If you are redirecting to the same host then you don't need to explicitly include the scheme + hostname in the target URL, since this will default.

Htaccess file override with fallback to original

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

Htaccess - Detecting the URL

For my family members I was giving each person their own subdomain
(sister1.mydomain.com, sister2.mydomain.com, etc...)
I was using PHP to detect the domain, and then I'd load information related to the subdomain dynamically.
I'd like to get rid of the subdomains and use the power of .htaccess
My goal is to give the same URL:
www.mydomain.com/sister1
www.mydomain.com/sister2
www.mydomain.com/mommy
www.mydomain.com/daddyo
Obviously, I don't plan to have literal working directories for each person.
I'd pass the "sister1" portion to a process.php script that takes care of the rest.
I've figure out how to do it by manually typing each RewriteRule in my htaccess file:
Options +FollowSymLinks
AddDefaultCharset UTF-8
RewriteEngine on
RewriteBase /
RewriteRule ^/?sister1$ process.php?entity=sister1 [L]
RewriteRule ^/?sister2$ process.php?entity=sister2[L]
RewriteRule ^/?mommy$ process.php?entity=mommy[L]
RewriteRule ^/?daddyo$ process.php?entity=daddyo[L]
I feel this is the long way of doing it.
Is there a more universal way of extracting the text after the first "/" forwardslash, and passing it to process.php?entity=$1 ?
I tried it this way:
RewriteRule ^/([A-Za-z0-9-]+)/?$ process.php?entity=$1 [NC,L]
I'm getting the apache 404 error: "Not Found".
It is because you have a mandatory / in the beginning of your rule, i.e., you are always looking for something like /sibling in the URL. Your first examples have that first forward slash as optional due to the question mark after it.
You do not need a beginning forward slash - normally the rewrite rule picks up stuff after the domain name
www.example.com/string/mod/rewrite/gets/is.here
So just remove the starting slash and it should work.

htaccess Rewrite subdirectory to php page

I've successfully rewritten
RewriteRule ^alphabetical alpha.php
So that when anyone comes to www.example.com/alphabetical it loads alpha.php. However, I'm having problems creating a rule so that when someone comes to www.example.com/alphabetical/a it should loa alpha-a.php. This is the rule I've tried that isn't working:
RewriteRule ^alphabetical/a alpha-a.php
put your second more specific rule on top of the the first rule.
RewriteRule ^alphabetical/a alpha-a.php
RewriteRule ^alphabetical alpha.php
further, you can use a $ at the end to denote an end of url, saying urls ending with 'a'.

Resources