How to serve webp from a different folder using .htaccess - .htaccess

I have a folder /assets/admin/images/products which contains .jpg and .png files and another folder /assets/admin/images/products/webp with the webp version of .jpg and .png files with name filename.webp (jpg and png is not added in file names)
How do i serve webp version of image from different folder using htaccess
I found some information at https://github.com/vincentorback/WebP-images-with-htaccess but it only serves from same folder.
I tried below htaccess code, but it didn't work
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/webp/$1.webp -f
RewriteRule (.+)\.(jpe?g|png|gif)$ %{DOCUMENT_ROOT}/webp/$1.webp [T=image/webp,E=REQUEST_image]

Your code is good but you don't need %{DOCUMENT_ROOT} on the last line with RewriteRule. This is the problem.
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/webp/$1.webp -f
RewriteRule (.+)\.(jpe?g|png|gif)$ webp/$1.webp [T=image/webp,E=REQUEST_image]

Related

Litespeed returns 403 when rewriting the URL of an existing image

My customer is using Litespeed with CPanel v106.0.10.
I have a RewriteRule like this in .htaccess file:
RewriteCond %{HTTP_HOST} ^www.site.com$
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}%{ENV:REWRITEBASE}/img/$1.webp -s
RewriteRule ^img/([_a-zA-Z0-9-]+)\.jpg$ %{ENV:REWRITEBASE}img/$1.webp [B,L]
RewriteCond %{HTTP_HOST} ^www.site.com$
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}%{ENV:REWRITEBASE}/img/$1.webp !-s
RewriteRule ^img/([_a-zA-Z0-9-]+)\.jpg$ %{ENV:REWRITEBASE}webp.php?src=img/$1.jpg [B,L]
The goal is to serve images into WEBP format when the WEBP file exists, if not then call the PHP script to compress the JPG file into WEBP format.
It's working good with Apache but when using Litespeed server I get a 403 error when the WEBP file does not exists.
Also when the URL of the image does not match the real file name (URL rewriting) then it also works.
So I think there is something that blocks URL rewriting when the URL match with a real file.
Who can help?
I found that this is a difference between Apache and Litespeed.
Litespeed does not prioritize the rules defined in .htaccess files in the same way as Apache. Thus PHP files are forbidden in the "/img" directory, when the URL "/img/image.webp" arrives, Apache applies the redirection to the PHP compressor but does not apply the "access denied" on the script because it is not in the "/img" directory, whereas Litespeed applies the redirection to the PHP compressor but blocks access to it (403) because the original URL starts with "/img".
I guess that this is a bug from Litespeed.

webp fallback jpg using htaccess

I use webp format by default in images, I want to show the jpg version in browsers that do not support webp.
I want to do this using htaccess, my code converts jpg to webp, how can I reverse this?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule (.+)\.(jpe?g|png|gif)$ $1.webp [T=image/webp,E=REQUEST_image]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REQUEST_image
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
So you're linking to .webp images and you want to serve the corresponding .jpg image if the user does not support image/webp type images, but presumably testing whether the corresponding .jpg image actually exists first before trying to serve it...
RewriteCond %{HTTP_ACCEPT} !image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.jpg -f
RewriteRule (.+)\.webp$ $1.jpg [T=image/jpeg,E=REQUEST_image]
Testing whether the .jpg image exists maybe unnecessary if the user-agent does not actually support webp images anyway. Which is preferable... some kind of image display issue or a 404? Then again, if the .jpg image always exists then the file check is redundant anyway.

htaccess: serve webp image instead of jpg or png if webp exist results in 404

I generated *.webp files that are named exactly like their png or jpg source. Then I added this to my .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# Does browser explicitly support webp?
RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
# OR Is request from Page Speed
RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
# OR does this browser explicitly support webp
RewriteCond %{HTTP_ACCEPT} image/webp [OR]
# AND does a webp image exists?
RewriteCond %{DOCUMENT_ROOT}/$1\.webp -f
# THEN send the webp image and set the env var webp
RewriteRule (.+\.(?:jpe?g|png))$ $1.webp [NC,L]
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
What I expect:
all jpg files load normal e.g /test/marc.jpg If a webp with the same name exists, serve a webp file via url /test/marc.jpg
This works of the webp file exists. But if I delete a webp file I get a 404 on the jpg or png url. Even old jpg or png urls then give a 404. Example:
/www/media/
.htaccess
marc.jpg
marc.webp
http://domain/marc.jpg serves the webp. I test this from chrome with cache disabled. When I delete the marc.webp I get a 404 on http://domain/marc.jpg Why? RewriteCond %{DOCUMENT_ROOT}/$1.webp -f should fix this, right?
These two lines are not looking for the files you describe:
# AND does a webp image exists?
RewriteCond %{DOCUMENT_ROOT}/$1\.webp -f
# THEN send the webp image and set the env var webp
RewriteRule (.+\.(?:jpe?g|png))$ $1.webp [NC,L]
In both of these, $1 refers to the first captured match in the RewriteRule, which in this case is (.+\.(?:jpe?g|png)). If you request, "marc.jpg", that whole string matches, and will be placed in $1. The two lines therefore evaluate as:
If the file "marc.jpg.webp" exists, respond with "marc.jpg.webp"
Since it doesn't, the rule will not be run.
The condition you wanted was:
If the file "marc.webp" exists, respond with "marc.webp"
So you want $1 to contain only the "marc" part of the requested file; that's just a matter of moving the closing parenthesis:
RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,L]
This doesn't explain why your rule appeared to work, and stopped working when you deleted a file. I suspect you have another rule somewhere else which is confusing the situation.

mod_rewrite change extensions .gif/.jpg to .png

The rule I have been fruitlessly working with doesn't work, I am trying to get all images in 1 directory to load as .png The images in the directory are a mixture of .png, .jpg and .gif
I want to be able to load the file tree.jpg by going to tree.png (no files have the same name). I am sure my mistake is obvious or my entire attempt is wrong, I just can't work it out.
The htaccess file is in the same folder with the images, which is called /thumbs
RewriteEngine On
RewriteRule ^([^.]*)\.gif$ /thumbs/$1.png [R,L,NC]
I tried this also, but it just givens a broken link to both .gif and .png versions
RewriteEngine on
RewriteRule ^(.+)\.gif$ $1.png
I tried this too, but it adds in my server path to the URL for some reason
RewriteEngine on
RewriteRule ^([^.]*)\.gif$ $1.png [R,L,NC]
You can use this rule:
RewriteEngine on
RewriteRule ^([^.]+)\.png$ /$1.gif [L,NC,R]

.htaccess rule stacking and 404 redirect

The user requests a PNG image, say: http://server/myfolder/subfolder/1234.png. If that .png doesn't exist, then I want to show instead a .gif in the same folder of the same name except for the .gif extension, which should exist.
Another addition is that we recently changed the directory structure so the URL that I need to check may have changed. For example, the URL above should be able to be reached by requesting either directly as http:// server/myfolder/subfolder/1234.pngor by http://server/oldfolder/1234.png. The change in the directory structure can be expressed as:
RewriteRule oldfolder/(.*) myfolder/subfolder/$1 [L,QSA]
In both directories, I need to check if the file exists, and use a different image instead if necessary. Any help would be greatly appreciated.
Try adding the following to the .htaccess file in the root directory of your site.
It should work with your changed file structure too.
RewriteEngine on
RewriteBase /
#if the file does not exist
RewriteCond %{REQUEST_FILENAME} !-f
#and is in any of these folders: /myfolder/subfolder or /folder1 or /folder2
RewriteCond %{REQUEST_URI} ^/(myfolder/subfolder|folder1|folder2)/ [NC]
#and its a png, then try to serve the gif instead
RewriteRule ^(.+)\.png$ $1.gif [L,NC]

Resources