RewriteRule do THIS if image file, or else do THAT - .htaccess

I'm having a hard time having this to work..
I have installed YOURLS wich is a PHP script to shorten urls.
In order to work, it needs to have this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /yourls-loader.php [L]
No problem here.
But I also want to use a directory for image hosting that has nothing to do with the PHP script.
It would check if the requested url ends with .jpg|.jpeg|.gif|.png and RewriteRule would redirect to /imgshare/$1
I've tried the code below but I get a server error when going to mysite.com/img.jpg but not for the url redirection "mysite.com/y4Jd":
RewriteCond %{REQUEST_URI} !(\.jpg|\.jpeg|\.gif|\.png)$ [NC]
RewriteRule ^(.*)$ /yourls-loader.php [L]
RewriteCond %{REQUEST_URI} (\.jpg|\.jpeg|\.gif|\.png)$ [NC]
RewriteRule ^(.*\.(jpeg|jpg|png|gif))$ /imgshare/$1 [L]

This is not the issue, but as a note, your second RewriteCond already matches files with image endings, so there's no need to repeat that match in the RewriteRule. Alternately, there's no need for the RewriteCond since it's redundant to the RewriteRule.
The real issue, however, may be that you have an extra slash in the final rule. $1 will contain the leading slash matched from the original URL so your rule is currently adding two slashes between imgshare and the file name. I would implement the rule like this:
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteRule ^(.*)$ /imgshare$1 [L]

Related

.htaccess Config causing Google Analytics conversions to fail

I have setup my .htaccess to add a trailing slash to each URL, but having done this I can see that my Google Analytics conversions (goal type is 'Destination') do not work.
The page I'm trying to track is:
/thank-you/contact/
And the trailing slash gets added by .htaccess if not already there. In GA I have told it to track 'Begins with' /thank-you/contact, 'Equals /thank-you/contact/' etc. Nothing works.
If I comment out the .htaccess rule that adds the trailing slash the conversion tracking immediately starts working again. Have I got some kind of bad config in my .htaccess?
RewriteEngine On
# add trailing slash
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://mydomain.co.uk/$1/ [L,R=301]
#remove www
RewriteCond %{HTTP_HOST} ^www.mydomain.co.uk$ [NC]
RewriteRule ^(.*)$ http://mydomain.co.uk/$1 [R=301,L]
#remove index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
Try regular expression condition with goal settings
thank-you\/contact.*
trailing .* would match or zero and unlimited characters

GET parameter doesn't work with htaccess rules

So, I have this code in .htaccess:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Every file loses its extension (/index.php -> /index etc) and that works perfectly fine. But later on, I started working with admin panel and I'm using some GET parameters there. For example, problematic URL look like:
example.com/admin?cat=1
As far as I know, RewriteRule gets only string after RewriteBase and is not catching GET parameters, right? So why when I try to go to this URL it rewrites it to this?
http://example.com/C:/OpenServer/domains/example.com/admin/1/
There is also this line in .htaccess(but doesn't look like there is problem with it):
RewriteRule ^admin/(.*)$ admin.php?cat=$1
As answered here, you have to add [QSA] at the end of your RewriteRule line:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [QSA]
Google search query that lead me to that answer: htaccess pass parameters

Adding options to existing .htaccess

I have this .htaccess code which I have put together from different sources and I am having trouble adding a couple of extra options to it.
<Limit GET POST PUT>
order deny,allow
deny from all
allow from XXX.XXX.XXX.XXX
</Limit>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} "/css/" [OR]
RewriteCond %{REQUEST_URI} "/js/" [OR]
RewriteCond %{REQUEST_URI} "/images/"
RewriteRule .* - [L]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)/([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_]+)$ index.php?primary=$1&secondary=$2&tertiary=$3&quaternary=$4 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)/([a-zA-Z0-9-/_]+)$ index.php?primary=$1&secondary=$2&tertiary=$3 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)$ index.php?primary=$1&secondary=$2 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)$ index.php?primary=$1
Firstly I would like to add the forced use of www. in the URL. When I have tried to add this, the resulting URL becomes the output of the current RewriteRules, containing the GET variables. I believe this is because the rules work on a loop?
Another thing I would like to do is catch anything that doesnt meet the criteria of the current rules and send that to something like index.php?primary=error. The way it works now is almost perfect for my use because if there is a malformed URL or illegal character, the site is not going to even attempt to display the page. The site will create all URLs safely, so any bad URLs would be the result of experimenting in the address bar, but it would be nice to have an error page rather than a page not found.
Thanks in advance.. And sorry for the muddle-through use of RewriteRule!
Your regex are incorrect since hyphen can be unescaped only when it appears as first or last symbol in a character class, it needs to be escaped otherwise.
So instead of: [a-zA-Z0-9-/_%]
Use: [\w%/-]
Your complete set of rules:
RewriteEngine On
RewriteBase /
# add www in the URL
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,NE,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} ^/(css|js|images)/ [NC]
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2&tertiary=$3&quaternary=$4 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2&tertiary=$3 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2 [QSA,L]
RewriteRule ^([^/]+)/?$ index.php?primary=$1 [QSA,L]

mod_rewrite - do two redirects - if the first one dosen't match do the second

This is my htaccess file at the moment
RewriteEngine On
# Only redirect if file dosen't exist.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin/(.*) /admin.php
RewriteRule ^([^/]) /index.php [L]
I don't have any idea why this doesn't work. I think I've finally grasped mod_rewrite and then it just does something completely unexpected like this.
Basically if the URL is domain.com/admin/something then I want it to redirect to domain.com/admin.php (including if its just /admin). However if its ANYTHING else I want it to redirect to index.php.
Any idea how to achieve this?
Thank you.
RewriteEngine On
# No redirect, if file or directory exists
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^admin/(.*) /admin.php [L]
RewriteRule ^(.*)$ /index.php [L]
Didnt test it. The interesting part is the L-Flag after the admin-rule, because it prevents the next rule from matching.
I changed the RewriteCond-Statements, because they only apply to the one next RewriteRule and (in your case) doesnt affect the rule to index.php.

Force trailing slash

I'm trying to force a trailing slash to my URLs, but I can't make it work the way I want. This is my .htaccess file:
RewriteEngine on
#Force trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
#Subdomains
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
RewriteCond $1/%1 !^([^/]+)/\1$
RewriteRule ^/([^/]+)? /%1%{REQUEST_URI} [L]
#Point everything to page.php
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond $1 !^(.*).(php|css|js|png|jpg|gif|htm|html)$
RewriteRule ^(.*)$ page.php?q=$1 [L,NC]
If I go to "en.example.com/about" I'm redirected to "en.example.com/en/about/", which is an invalid page.
How can I make this work?
The problem here is that the L flag causes a restart of the rewriting process with the rewritten URL (I’ve already told you that, didn’t I?):
Remember, however, that if the RewriteRule generates an internal redirect (which frequently occurs when rewriting in a per-directory context), this will reinject the request and will cause processing to be repeated starting from the first RewriteRule.
Now when /about is requested, the first rule get’s applied and redirects to /about/. The subsequent request of /about/ is then processed, at first the third rule is applied and the URL path is rewritten to /page.php. So far, so good.
But now the internal redirect takes place and the rewriting process is restarted with the new URL path /page.php. This is then fetched by the first rule again and redirected externally to /page.php/.
The second rule shouldn’t be applied at all as the pattern ^/ should never match as the per-directory path prefix is removed before testing the pattern when using mod_rewrite in an .htaccess file:
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
But these rules should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ /$0/ [L,R=301]
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$ [NC]
RewriteCond %1 !=www [NC]
RewriteCond $0/%1 !^([^/]+)/\1$
RewriteRule ^[^/]* /%1%{REQUEST_URI} [L]
RewriteCond %{HTTP_HOST} !=www.example.com [NC]
RewriteCond $1 !.*\.(php|css|js|png|jpg|gif|htm|html)$
RewriteRule .* page.php?q=$0 [L]

Resources