RedirectMatch 301 to change part of URL - .htaccess

There are bad links left over from a previous error, and I'm trying to clean up my mess with 301 RedirectMatch.
Correct URLs are the following format:
http://www.example.com/aaa-directory/page
http://www.example.com/bbb-directory/page
http://www.example.com/ccc-directory/page
(etc.)
But, previously there were bad links that linked to the pages at:
http://www.example.com/aaa-directory//page
http://www.example.com/bbb-directory//page
http://www.example.com/ccc-directory//page
(double backslash // when should be single / )
I've fixed the bad links, but I still get external links and/or robot crawls that go to those bad URLs.
I'd like to use a RedirectMatch 301 so that any link with the text "-directory//" will redirect to the same link with "-directory/".
So, http://www.example.com/ccc-directory//page would be redirected to:
http://www.example.com/ccc-directory/page
I'm struggling with the syntax. Any help would be appreciated!
(not sure if this is needed, but my current HTACCESS file is as follows):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

Keep redirect rules before internal rewrite ones and have another rule to take care of //
RewriteEngine on
RewriteBase /
RewriteCond %{THE_REQUEST} \s/+(.*?)/+(/\S*) [NC]
RewriteRule ^ %1%2 [R=301,L,NE]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

Related

HTACCESS Rewrite, remove .php and redirect working for one rule and not the other

I have the following example urls, there are many possible parameter values
http://www.example.com/area-codes.php?code=0000
http://www.example.com/search.php?number=00000000000
Which I wish to rewrite to the following, respectively.
http://www.example.com/area-codes/0000
http://www.example.com/number/00000000000
Currently, the second url is rewriting and redirecting perfectly.
However the top one is causing an Internal server error
Here's my htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} \.(jpg|css|js|gif|png)$ [NC]
RewriteRule ^ - [L]
#unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
#resolve .php file for extensionless php urls
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
#redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.#?\ ]+\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php /$1 [R=301,L]
RewriteRule ^area-codes/([^/]*)$ /area-codes.php?code=$1 [L,QSA]
RewriteRule ^number/([^/]*)$ /search.php?number=$1 [L,QSA]
I am assuming there's something wrong with my flag?
Commented out these two lines and it's worked.
#resolve .php file for extensionless php urls
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

How to let htaccess distinguish between files and ids

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d # not an existing dir
RewriteCond %{REQUEST_FILENAME} !-f # not an existing file
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f # and page.php exists
# redirect to the physical page
RewriteRule ^(.*)$ $1.php [L]
# otherwise, redirect to serve.php
RewriteRule ^ /serve.php [L]
RewriteRule ^(\w+)$ ./serve.php?id=$1
So in the first part of the code I just turn http into https. My aim is that I can use urls without an .php but in my old code I had the problem that if I did so, it was used as an id for my serve.php page. So if use https://example.com/contact it was like https://example.com/serve.php?id=contact but I want it to work as https://example.com/contact.php but on the other side I want that ids that arent directions or file should still work as ids. My old code was...
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(\w+)$ ./serve.php?id=$1
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
You can use these rules in your site root .htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# skip rules below this for files and directories
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# rewrite to the physical php page
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# otherwise, redirect to serve.php
RewriteRule ^/?$ serve.php [L]
RewriteRule ^(\w+)/?$ serve.php?id=$1 [L,QSA]

Multiple rewrite rules and conditions in htaccess file

In my .htaccess file i have already some rewrite conditions and rules, and its working normal.
Now i need to add "http to https redirect" to my htaccess file.
Here is my old .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteRule ^([a-z0-9_-]+)$ pages/$1.php [L]
RewriteRule ^([a-z0-9_-]+)/([-a-zA-Z0-9_]+)$ pages/$1/$2.php [L]
RewriteRule ^([a-z0-9_-]+)/([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)$ pages/$1/$2/$3.php [L]
I attempted to add below code to file but it doesnt work properly.
For example if i write the url direct to browser its work (only with www). But if click my any backlinks or google search result links it doesnt work.
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
Where do i wrong? Where should i put the code? Any help would be great. Thanks.
your htaccess could look like this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.yoursite\.com [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteRule ^([a-z0-9_-]+)$ pages/$1.php [L]
RewriteRule ^([a-z0-9_-]+)/([-a-zA-Z0-9_]+)$ pages/$1/$2.php [L]
RewriteRule ^([a-z0-9_-]+)/([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)$ pages/$1/$2/$3.php [L]
At least, it works for me, in my own implementation
You can use the following htaccess :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)/?$ $1.php [L]
Clear your browser's cache before testing this

.htaccess vanity urls and clean urls together

I've been able to set up .htaccess to enable vanity urls on my website. However, I'm encountering into a problem when I try to clean other urls on my website. I would give the scenario and my current .htaccess below:
Currently wwww.mywebsite.com/john redirects to profile.php?user=john. In profile.php I check to see user john exist in my database if false I redirect to a custom 404.php page. This work very well. The problem arises when I try to have wwww.mywebsite.com/photo/abcdefg be interpreted as www.mywebsite.com/photo.php?m=abcdefg. For some reason it believes photo is the name of the user and then rewrites it as if its a vanity url. Please see my .htaccess file code below:
ErrorDocument 404 http://www.mywebsite.com/404
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC]
RewriteRule ^([^\.]+)$ profile.php?username=$1 [L]
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^(.*)\.(.*)\. [NC]
RewriteRule ^ HTTP%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
You need to do your redirect before any internal routing. Then, you need to explcitly match against /photo before you route to profile and change the .php -f:
ErrorDocument 404 http://www.mywebsite.com/404
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^(.*)\.(.*)\. [NC]
RewriteRule ^ HTTP%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^photo/(.+)$ /photo.php?m=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^\.]+)$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ /profile.php?username=$1 [L]

strange htaccess query parameters

I have searched some on this site but couldn't find a right answer to my question.
I am trying to force a www redirect and forcing an endslash on each url.
I have the following lines in my htaccess:
# enable rewriting
RewriteEngine on
# if not a file or folder, use index.php
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
# force www
RewriteCond %{HTTP_HOST} !^www
RewriteRule .? http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# force endslash
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule (.*) %{REQUEST_URI}/ [L,R=301]
My www redirect is working fine, it will go like:
http://example.com
to
http://www.example.com
But now the strange part is, my end slash line is adding the url parameter which I don't want.
So this will go like:
http://www.example.com/path/without/endlash
to
http://www.example.com/index.php/?url=path/without/endslash
Why is it that my defined url parameter is used in this case, and how can I prevent this.
Thanks in advance
EDIT:
thanks to icrew
Only added no-file/no-dir before the endlash entry because otherwise it would redirect my assets.
Final code:
RewriteCond %{HTTP_HOST} !^www
RewriteRule .? http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule (.*) %{REQUEST_URI}/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
This part of .htaccess
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
is responsible for http://www.example.com/index.php/?url=path/without/endslash redirection. So basicly if you do not want url parameter in query string remove those three lines.
Edit: I figure out what you wanted. Bellow is correct code
# enable rewriting
RewriteEngine on
# force www
RewriteCond %{HTTP_HOST} !^www
RewriteRule .? http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# force endslash
RewriteCond %{REQUEST_URI} !(.*)/$
#next row prevent redirection if final rewriting is done
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule (.*) %{REQUEST_URI}/ [L,R=301]
# if not a file or folder, use index.php
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
#QSA because I suppose you dont want to discard the existing query string. Remove QSA if you want to discard
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Resources