Skip a directory with htaccess - .htaccess

RewriteCond %{HTTP_HOST} ^(www.)?example\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
So i have this in my htaccess file to take care of the trailing slash problem . It redirects you every time you add a trailing slash on a url.
The issue here is the fact there is one directory where it needs the trailing slash or it breaks. How do I add a exception for a directory like http://www.example.com/com/ to this rule..

The simplest to understand approach is to use an additional condition:
RewriteCond $1 !=com
RewriteCond %{HTTP_HOST} ^(www.)?example\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
This works because the order of execution is rule.regexp, cond1, cond2, rule.substitution. Hence the $1 variable is available to the (new) cond1. You could also use a negative assertion on your regexp.
Incidentally, the http://%{HTTP_HOST}/ is assumed in the case of a [R=301] for http. Why do you not want to remove / for other host aliases?

Related

.htaccess to redirect to new website structure

I have changed the website URL structure and I want to redirect my users
The problem
The new structure is very different, and more strict.
OLD
1 - https://example.com/serie-tv
2 - https://example.com/serie-tv/1845578-the-walking-dead
3 - https://example.com/serie-tv/1845578-The-Walking-Dead/seasons/1
4 - https://example.com/serie-tv/1845578-the-walking-dead/seasons/1/episodes/1
NEW
1 - https://example.com/browse?type=series
2 - https://example.com/titles/1845578
3 - https://example.com/titles/1845578/season/1
4 - https://example.com/titles/1845578/season/1/episode/1
A redirection from https://example.com/serie-tv/1845578-the-walking-dead/seasons/1
to
https://example.com/titles/1845578-the-walking-dead/season/1 will not work.
Need to redirect just to https://example.com/titles/1845578/season/1
For now I only managed to redirect everything under
https://example.com/serie-tv /.....
to
https://example.com/browse?type=series
with this code:
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^serie\-tv\/?(.*) "https\:\/\/example\.com\/browse?type=series" [R=301,L]
A slight complication comes about because you have seasons and episodes (with an s) in the old URL structure and season and episode (no s) in the new URL structure, so you can't use a general solution that simply copies the URL-path.
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
If you only have a single domain then these conditions are superfluous.
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
For now, we can ignore these as well. cPanel will automatically inject these as required when auto-renewing your SSL certs.
For now I only managed to redirect everything under ...
I assume you don't want to redirect "everything" since your preceding example URLs do not state this?
RewriteRule ^serie\-tv\/?(.*) "https\:\/\/example\.com\/browse?type=series" [R=301,L]
There is unnecessary backslash escaping here that affects readability. There is no need to escape literal hyphens (-) and slashes in the RewriteRule pattern. And in the substitution string (which is an "ordinary" string, not a regex), there is no need to escape the colon (:), slash (again) and dot. These "literal" characters carry no special meaning in the context they are used. (This is typical output having used cPanel's redirection feature - which will often put them in the wrong place as well.)
Try something like the following instead, near the top of your .htaccess file:
RewriteEngine On
# Redirect "/serie-tv"
RewriteRule ^serie-tv$ /browse?type=series [R=302,L]
# Redirect "/serie-tv/1845578-the-walking-dead"
RewriteRule ^serie-tv/(\d+)-[^/]+$ /titles/$1 [R=302,L]
# Redirect "/serie-tv/1845578-the-walking-dead/seasons/1"
RewriteRule ^serie-tv/(\d+)-[^/]+/seasons/(\d+)$ /titles/$1/season/$2 [R=302,L]
# Redirect "/serie-tv/1845578-the-walking-dead/seasons/1/episodes/1"
RewriteRule ^serie-tv/(\d+)-[^/]+/seasons/(\d+)/episodes/(\d+)$ /titles/$1/season/$2/episode/$3 [R=302,L]
\d is a shorthand character class for digits (the same as [0-9]) and \d+ matches 1 or more digits.
$1, $2 and $3 are backreferences to the captured groups in the RewriteRule pattern. It's more efficient to test what you can in the RewriteRule pattern instead of using a preceding condition that checks the REQUEST_URI server variable.
Note that these are currently 302 (temporary) redirects. Only change to 301 (permanent) when you have tested that they work OK - in order to avoid caching issues.
You will need to clear your browser cache before testing.
Aside: The old URL structure, that includes the title maybe better from an SEO / useability perspective?
I think this should do what you need.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} /serie-tv$ [NC]
RewriteRule ^(.*)$ browse?type=series [R=301,L]
RewriteCond %{REQUEST_URI} /serie-tv/([0-9]*)\-([^/]*)/?(.*)? [NC]
RewriteRule ^(.*)$ titles/%1/%3 [R=301,L]

Migration HTTP to HTTPS except 1 directory

I would like to migrate a site from HTTP to HTTPS except one directory.
It's not working .... first of all, is it possible to code this?
#https exept directory dir2
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !dir2[NC]
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_URI} !dir2[NC]
You are missing a space delimiter before the flags argument, so this will never match the intended directory. It should read:
RewriteCond %{REQUEST_URI} !dir2 [NC]
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
You are also missing two spaces surrounding the pattern. So this will again never match anything. So, this should read:
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Spaces are delimiters in Apache config files.
However, this can be improved, as you don't need the additional condition if you just want to exclude a single directory. You should use the RewriteRule pattern instead:
RewriteCond %{HTTPS} off
RewriteRule !^dir2 https://%{HTTP_HOST}%{REQUEST_URI} [NC,L,R=301]

.htaccess redirects with multiple paramenters

I am rebuilding a real estate site and we have completely restructured how the database handles the properties and I am now trying to redirect all of the old property urls to the new ones. The problem that I am having is that the old urls used multiple parameters(including the section and the property id) for a single property and the new urls only use a slug for the property name.
Example:
OLD: https://www.example.com/listings.php?sect=1&view=92
NEW: https://www.example.com/listings/tombstone-ranch
My current .htaccess looks like the following with the last two lines being the rewrites for converting the slugs into clean urls...all of this works fine.
RewriteEngine On
RewriteBase /
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
RewriteRule ^listings/([a-zA-Z0-9-/]+)$ /listings/index.php?s=$1 [L]
RewriteRule ^listings/([a-zA-Z0-9-/]+)/$ /listings/index.php?s=$1 [L]
The Problem that I am having is that neither of the following seems to work:
Redirect 301 /listings.php?sect=1&view=92 /listings/tombstone-ranch
and neither does this:
RewriteRule ^listings.php?sect=3&view=33 /listings/tombstone-ranch
or any other variations that I have tried.
Any thoughts? .htaccess is not my strong suit and unfortuinately I need to get these to work considering the old version of the site and it's urls have been around for almost 8 years now so there is the potential for dead links on about 75 properties.
Could you try this rule. Can't test it at the moment.
RewriteCond %{QUERY_STRING} sect=1&view=92
RewriteRule ^listings\.php$ /listings/thombstone-ranch/? [L,R=301]
Also the rule you added will not work because you must add a backslash
Wrong:
RewriteRule ^listings.php?sect=3&view=33 /listings/tombstone-ranch
Right:
RewriteRule ^listings\.php?sect=3&view=33 /listings/tombstone-ranch
Don't forget since your main URL is a query, you should use the first option that I gave to you. If that doesn't work leave a comment and I'll be glad to help you out

htaccess - forcing trailing slash two directories deep

My website structure has a root /index.php, some files as /directory/index.php and some as /directory/(filename).php
I have the following .htaccess which removes the php extensions and the "index.php" for my URLs, and forces trailing slashes on the first level directories for SEO goodness:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]
so the following are working (they show the correct page):
/
/directory/
/directory/filename/
The only thing that doesn't work, is if I type in:
/directory/filename
It goes to:
http://(mylocalurl)/Users/(myusername)/Sites/(mysitedirectory)/directory/filename/
My question is: How do I make the second level filename rewrite to force a trailing slash like:
/directory/filename/
Thanks for your help!
DirectorySlash on
will add a trailing slash where appropriate.
Not 100% sure, but it could be that it is triggered by your the second RewriteCond, the RewriteRule is run, not replacing anything, and then you have the [L] that makes it not go to the last RewriteCond.
Maybe changing the order of the two might help?
(Or else, you might want to look into Multiviews directive)
When you're specifying a local relative URL path to perform an external redirection on, that path needs to be prepended with a slash. Since the match to your RewriteRule test pattern will not have a leading slash, be sure to put one in the rewrite:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ /$0/ [L,R=301]
If I've understood your problem correctly, that's the only issue you have. If you needed something else though, let me know.

how do i fix this rewrite URL rule?

basically need to convert
with www or not, example.com/[anycharacter]
into
with www or not, example.com/cgi-bin/new-disk.cgi/dir/smooth/[anycharacter]
additinoally...
i would like to redirect ALL www.example.com into example.com
This should work for you:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !cgi-bin/new-disk.cgi/dir/smooth
RewriteRule ^(.*)$ /cgi-bin/new-disk.cgi/dir/smooth/$1 [L]
For the first two lines, it checks to see if you have www in your URL. If so, bounce it to the non-www version.
Note the exclamation mark (!) on the second last line. This is a not operator and in this test, is checking to see if your currently requested file isn't your final rewriting file, in this case:
cgi-bin/new-disk.cgi/dir/smooth
If that's true, shunt it to the actual rewrite script you have as pointed out in the final line.
The character, $1, references the first capture group as marked by the first set of parentheses on the same line.
For part of your answer, I believe you can use this as an example to base off.. hopefully you use a test domain:
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^/(.*) http://example.com/$1 [L,R=301]
Might need to add a (.*) and make it optional for the other part.

Resources