regex in my RewriteRule is OK, but .htaccess does not work - regex

I'm having a lot of trouble getting my .htaccess ReWrite to work on my apache web server. I've read several tutorials and tested my regex matching with Grep.
Here is the code:
RewriteRule \?action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])$ essays/$1 [R=301,L]
here is a url I'm trying to match:
http://mysite.com/?action=viewArticle&articleId=15&categoryId=1
and change to
http://mysite.com/essays/15
UPDATE: Solution! with a very excellent tutorial from Jon. It was very important that I put <base href="/"> in my header file to get the css to work correctly.
Final rewrite looked like this:
RewriteCond %{THE_REQUEST} /?action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])
RewriteRule ^$ /essays/%1? [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^essays/([0-9]+) /?action=viewArticle&articleId=$1&categoryId=([0-9]) [L]

You can't match hosts or query strings inside a RewriteRule, you need to match against the %{HTTP_HOST} and %{QUERY_STRING} variables in a RewriteCond directive:
RewriteCond %{HTTP_HOST} mysite\.com$ [NC]
RewriteCond %{QUERY_STRING} ^action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])$
RewriteRule ^$ /essays/%1? [L,R=301]
This redirects the browser (changing the URL in the address bar) when someone goes to http://mysite.com/?action=viewArticle&articleId=15&categoryId=1 to http://mysite.com/essays/15
You don't need the %{HTTP_HOST} condition if your htaccess file only serves a single host.

Related

.htaccess redirect URLs with specific path to 404 and exclude some URLs with the same path as exception

I have an application on Codeigniter(3.1.11). Basically, I want a 404 redirect of URLs which have dashboard in URI. Like these:
dashboard/foo/bar
dashboard/foo-2/bar-2
dashboard/something
...
Also, I want to keep some exceptions in redirect rule so, some of the specific URLs which have dashboard as path URI should be excluded from this redirect. Let's say I want to exclude some URLs like:
dashboard/new-foo/new-bar
dashboard/one-thing/abc
dashboard/another-thing/xyz
I have given a few tries but the exclude rule is not working. It redirects all URLs to 404. This is what I have in my .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(dashboard/new-foo/new-bar) [NC] # Exclude this url (this condition is not working)
RewriteRule ^(.*)$ dashboard/$1 [R=404,L]
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
It can be done in a single rule with negative lookahead conditions like this:
RewriteEngine on
RewriteRule ^dashboard(?!/new-foo/new-bar|/one-thing/abc|/another-thing/xyz) - [R=404,NC,L]
RewriteCond $1 !^(index\.php|resources|robots\.txt) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
I'm not expert with htaccess but I am pretty sure you need 2 RewriteCond lines, one to include all the dashboard urls and then the second to exclude the new ones. Each RewriteCond is implicitly joined with an "AND" so if you have many different patterns to exclude and you need a 3rd RewriteCode then you will need to join the 3rd with an "OR" on the 2nd condition.
e.g.
RewriteCond %{REQUEST_URI} ^/dashboard/(.*) [NC]
RewriteCond %{REQUEST_URI} !^/dashboard/new-(.*) [NC]
RewriteRule ^(.*)$ 404-page/$1 [R=404,L]
There are a couple of other things I'd like to mention: 1) Your RewriteRule redirects back to a /dashboard URL so you could possibly end up in a continuous look here. 2) You don't need to turn on Rewrite engine twice, once at the top is enough.
If the rewrite rules in htaccess are getting complicated then perhaps you could use your index.php file to handle it (or some other method within Codeigniter).

.htaccess rewrite w/ regular expression and ?lang=en parameter

I need a hand with creating a regex rewrite rule for my .htaccess.
Here's the problem. My previous URLs structure was:
http://example.com/whatever-the-url-is/?lang=en
now I turned it into
http://example.com/en/whatever-the-url-is/
I'd like to create an .htaccess URL that 301 redirects all the URLs from the previous structure to the new one.
Also the .htaccess is shared between different domains, and so there should be
RewriteCond %{http_host} !^example.com$ [NC] condition at the beginning...
Is it possible? Do you have any suggestions?
You can use:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteCond %{QUERY_STRING} (?:^|&)lang=(.+?)(?:&|$) [NC]
RewriteRule ^(.*)$ /%1/$1? [R=301,L]
You can add the RewriteRule after RewriteCond %{HTTP_HOST}:
RewriteCond %{REQUEST_URI} !^/(?:en|fr|sp)/ [NC]
Where you test if langcode is already in the url.

Using RewriteRules on query strings from root of domain

I'm trying to rewrite the URLs on my site (to improve SEO, its an AJAX site) so that they go from
http://www.domain.co.uk/?section=home
http://www.domain.co.uk/?section=contact
to
http://www.domain.co.uk/home
http://www.domain.co.uk/contact
respectively.
This is my first time using .htaccess for rewriting, and I'm finding that I end up just guessing with my expressions/copying answers from other questions and trying to make them work.
The closest I've gotten is from adapting this answer here
RewriteEngine on
RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)section=([^&\s]+)&?([^\s]*)
RewriteRule ^(.*)$ /section/%3?%1%4 [L,R=301]
RewriteRule ^section/(.*) index.php?section=$1 [L]
which gives me the result
http://www.domain.co.uk/section/contact
however this also breaks all my other links, and leaves the site without CSS or javascript etc.
Furthermore, one of the sections of my site has URLs that look like this
http://www.domain.co.uk/?section=blog&post=post-name-one
http://www.domain.co.uk/?section=blog&post=post-name-two
which I wanted to rewrite to
http://www.domain.co.uk/blog/post-name-one
http://www.domain.co.uk/blog/post-name-two
However, I'm am very unsure about how to approach this in RegEx.
Could anyone help in getting this right? If there are good references for writing these rules, I'd be happy to hear about them as well. So far the things I have read have been helpful in explaining what is happening, but I haven't been able to write my own yet.
You can use these rules in your root .htaccess:
RewriteEngine on
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+)&post=([^\s&]+) [NC]
RewriteRule ^ /%1/%2? [R=302,L]
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=302,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /?section=$1&post=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ /?section=$1 [L,QSA]

Apache Rewrite Issue. Unable to figure out query string

So I have been struggling on finding the rule to match this rewrite. I am working on a client website and it is a nightmare with the number of duplicate title tags. I have managed to resolve most of them by enforcing forward slash, redirect non www. to the www. version and disallow crawling of https version of the website.
The issue I am having at the moment. I have over 1000 URLs that are duplicate content, each product has two different URLs with the exact same content. An example is:
http://www.example.co.uk/product/widget1/
http://www.example.co.uk/widget1/
http://www.example.co.uk/product/widget2/
http://www.example.co.uk/widget2/
Now the following URLs have the same content:
http://www.example.co.uk/product/widget1/
http://www.example.co.uk/widget1/
I want to redirect any URL that contains "/product/" to the URL version without "/product/" in the URL if that makes sense. I honestly don't know where to start and would really appreciate the help.
Thanks in advance
EDIT: The recommended rule:
RewriteEngine On
RewriteRule ^/product/(.*)$ /$1 [R=301]
does not work. It may be conflicting. These are the other rules:
RewriteEngine On
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ /$1? [R=301,L]
RewriteRule ^/product/(.*)$ /$1 [R=301]
RewriteCond %{HTTP_HOST} ^example\.co [NC]
RewriteRule (.*) http://www.example.co.uk/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301]
I dont know if there are any conflicts here. Please help
Have your full .htaccess like this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.co [NC]
RewriteRule (.*) http://www.example.co.uk/$1? [L,R=301]
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ /$1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?[^/])$ /$1/ [L,R=301]
RewriteRule ^product/([^/]+)/?$ /$1/ [R=301,L]
Assuming the URLs always start with product, this should work:
RewriteEngine On
RewriteRule ^/product/(.*)$ /$1 [R=301]
It'll need to go in your main site conf or .htaccess

Remove /index.php/ from the URL with .htaccess

To note, I've found similar questions on StackOverflow but they have not worked as I need.
I have a URL such as:
http://www.example.com/index.php/test
I'd like to remove the index.php directory, so if the above is entered it would go to:
http://www.example.com/test
This appears to work
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,L]
However if the url is:
http://www.example.com/index.php?option=example
It turns into
http://www.example.com/?option=example
So index.php should only be removed if it's a directory like in my first example.
Also if you type in for instance:
http://www.test.example.com/index.php/index.php/dfd
It should go to
http://www.test.example.com/dfd
the rules below will:
not apply for /index.php?o=a
redirect /index.php/index.php/dfd to /dfd
redirect /index.php/index.php/dfd?a=b to /dfd?a=b
redirect /index.php/index.php?a=b to /index.php?a=b
.
RewriteCond %{QUERY_STRING} .+
RewriteRule ^index\.php(/index\.php)+/?$ /index.php [R=302,L,QSA,NC]
RewriteCond %{QUERY_STRING} ^$ [OR]
RewriteCond %{REQUEST_URI} !index\.php/?$
RewriteRule ((^|/)index\.php)+/?(.*)$ /$3 [R=302,L,QSA,NC]