.htaccess rewrite - filename.html to /?c=filename - apache

I need it to work with all html URLs (except index), I tried using .htaccess with no luck.
For example... change this link from: http://www.example.com/signup.html to http://www.example.com/?c=signup.
Also if I enter directly to http://www.example.com/?c=signup, it must mirror http://www.example.com/signup.html.
EDIT
I found the way to do that, except for the case that I enter directly to the .html file, in that case, it does not rewrite.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{QUERY_STRING} ^c=([^&]+) [NC]
RewriteRule ^/?$ %1.html [NC,L,QSA]

RewriteRule ^/?$ %1.html [NC,L,QSA]
To redirect (presumably you meant "redirect", not "rewrite") from signup.html to /?c=signup then you can do something like the following before your existing rewrite:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ([^.]+)\.html$ /?c=$1 [R,L]
The condition that checks against the REDIRECT_STATUS environment variable prevents a redirect loop when your existing directive rewrites to the .html file.
Note that this is a temporary (302) redirect. Change the R to R=301 if this is intended to be permanent, but only once you have confirmed it's working OK.
Your existing directives could be tidied, in summary:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# Redirect from signup.html to /?c=signup
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ([^.]+)\.html$ /?c=$1 [R,L]
# Rewrite from /?c=signup to signup.html
RewriteCond %{QUERY_STRING} ^c=([^&]+)
RewriteRule ^/?$ %1.html [QSD,L]
Presumably, you want to discard the c= query string from the rewritten substitution?

Related

I need help placing a 301 redirect in my htaccess file of my new php site

I have a php website and my current .htaccess file is as follows:
<IfModule mod_rewrite.c>
#Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]
Options -Indexes
</IfModule>
Now I want to do a 301 redirect on a URL. From example.com/folder/old-url-london.htm to example.com/new-url-london/
The problem is everytime I try something I get:
www.example.com/new-url-london/?page=folder/old-url-london.htm
Now I can't change this line (RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]) as it is essential to the working of the website.
Any ideas?
I tried the following:
Redirect 301 /folder/old-url-london.htm example.com/new-url-london/
as well as
RewriteRule ^folder/old-url-london.htm$ /new-url-london/ [R=301,L]
Sounds like you are perhaps putting the rule in the wrong place. Or used the Redirect directive. And/or are perhaps now seeing a cached response.
You need to use mod_rewrite RewriteRule to avoid conflicts with the existing rewrite AND the rule needs to be at the top of the file, before the existing rewrite and ideally after the RewriteEngine directive.
For example:
Options +FollowSymlinks -Indexes
RewriteEngine On
RewriteRule ^folder/old-url-london\.htm$ /new-url-london/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?page=$1 [QSA,L]
You will need to clear your browser cache before testing, since any erroneous 301 (permanent) redirects will have been cached by the browser. Test first with 302 (temporary) redirects for this reason.
Don't forget to backslash-escape literal dots in the regex.
I tidied up a few other bits:
<IfModule> wrapper is not required.
Combined Options at the top and re-enabled FollowSymLinks (since it is required by mod_rewrite)
RewriteBase is not required in the directives you've posted.
Removed spurious spacing.
NC flag not required on the rewrite since the pattern .* already matches everything.
The anchors on the pattern ^(.*)$ are not required since regex is greedy by default.

.htaccess RewriteRule with existing file and folder

My web structure looks like this:
public_html/
/images/
/user/
/userimage1.jpg
/userimage2.jpg
/userimage3.jpg
/icons/
/index.php
/user.php
...
I have 2 domains: example.com and images.example.com and I want to use a .htaccess RewriteRule that the images.example.com subdomain leads to the /images/-folder but also to use URLs without the file extension.
My .htaccess looks like this:
<IfModule mod_rewrite.c>
Options +FollowSymLinks +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [NC,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php [L]
</IfModule>
Now, https://example.com/user/ works fine, but when I try to open https://images.example.com/user/userimage1.jpg it says that %{REQUEST_URI} is /images/redirect:/images/user.php/userimage1.jpg
Unfortunately, both, the domain and the subdomain have to be installed with public_html as the root folder.
How do I have to adept my .htaccess file so that both URLs, https://example.com/user/ and https://images.example.com/user/userimage1.jpg work fine?
You have a conflict with MultiViews (which you've enabled at the top). The fact that "https://example.com/user/ works fine" (with a trailing slash) is because of MultiViews, not because of your mod_rewrite directives. (The mod_rewrite directives as written would only "work" with /user - no trailing slash.)
When you request https://images.example.com/user/userimage1.jpg, MultiViews triggers an internal subrequest for /user.php/userimage1.jpg (/user.php with additional path-info /userimage1.jpg), but mod_rewrite has also tried to rewrite the request (an internal "redirect") - hence the seemingly malformed rewrite.
Generally, you need to avoid using MultiViews with mod_rewrite rewrites - a common cause of conflict.
Try the following instead:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Rewrite images subdomain
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [L]
# Append .php file extensions
RewriteCond %{DOCUMENT_ROOT}/$1 !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.*)/$ $1.php [L]
Note that I've included the trailing slash in the RewriteRule pattern and taken this out of the capturing subpattern - this is assuming that the trailing slash is mandatory on your URLs (as in your example).
You don't need the <IfModule> wrapper unless mod_rewrite really is optional? (It's not.)

Re-writing url - apache - htaccess

I am migrating an existing website to a Codeigniter one so need a help with re-writing of the urls.
I need to map old URLs with new URLs so that people visiting site from search engine results get redirected to matching new URLs as otherwise they would get page not found errors.
Most of the old urls in this format e.g.
/page.php?id=5 or /page.php?id=180&t=78
/data.php?token=GH45LK
/faqs.php?k=98#section2
Their matching new URLs are
/page/5 or I will be happy with /page?id=5&whatever=xyz too
/data/GH45LK
/faqs/98#section2
This is my current .htaccess of CodeIgniter
# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
RewriteBase /
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
I tried something like this after RewriteBase / line
RewriteRule ^data\.php\?token=(.*)?$ data/=$1 [R=301,L]
but not sure if I got that right as it's not working.
Could you help me getting it right? Thx
RewriteRule does not work that way: it only test the path part of an URL. For all the other parts (domain, query string, ...), you need to use RewriteCond and the corresponding variable (%{QUERY_STRING}, for the query string/here).
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)
RewriteRule ^page\.php$ /page/%1 [L,R=permanent]
RewriteCond %{QUERY_STRING} (?:^|&)token=([^&]+)
RewriteRule ^data\.php$ /data/%1? [L,R=permanent]
RewriteCond %{QUERY_STRING} (?:^|&)k=(\d+)
RewriteRule ^faqs\.php$ /faqs/%1? [L,R=permanent]
And I think there is an error with RewriteCond %{HTTPS} !=on as you redirect on http://, not https://, this should result in an infinite loop.
Also note that the anchor (#section2 in your example), is not sent to the server (so it can't be rewritten).

Block Access to Entire Folder and Instead Route to index.php

I'm trying to write a .htaccess rewrite rule to redirect all traffic coming to domain.com/system/* back to domain.com.
I've written this so far:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1/ [L]
But it's not working as expected, if I go to:
domain.com/system/inexistent_file
it works. But if I go to:
domain.com/system/existing_file.php
It will open the specified file instead of showing index.php contents.
How should I fix this?
Try this:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
# Match against the host, if you wish
#RewriteCond %{HTTP_HOST} ^domain\.com$
RewriteRule system/(.*) /index.php?/$1 [L,R]
</IfModule>
It works for both existent and non-existent files.
The [R] flag is there because you stated that you want to redirect.

Url renaming using .htaccess file

Most are for redirections and removing file extensions or for dynamic urls.
The problem being I can't get a simple static url to rename
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^fileThathasalongname file.html
What I currently have 'mysite.co.uk/fileThathasalongname.html'
What I want is 'mysite.co.uk/file/' while file = file.html
using:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteRule ^FileIWantToChange.html FriendlyNamed.html
Using this gives me the error multiple Choices
+++++++++++++++++Edit+++++++++++++++++++++++++
Thought i'd add my final version for people to look at, it may help, the anwser below is correct.
Options +FollowSymLinks -MultiViews
DirectorySlash Off
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME}/ -d
RewriteCond %{SCRIPT_FILENAME}.html !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)\.html$ /$1 [R=301,L]
RewriteRule ^FriendlyNamed.html FileIWantToChange.html [L]
RewriteCond %{SCRIPT_FILENAME}.html -f
RewriteRule [^/]$ %{REQUEST_URI}.html [QSA,L]
RewriteCond %{HTTP_HOST} ^www.mysire.co.uk [NC]
RewriteRule ^(.*)$ http://mysite.co.uk/$1 [L,R=301]
all works a charm!
I see multiple issues going on. Firstly the regular expression is matched against the friendly URL the user types in. So you need to swap your friendly url and file path with each other. The friendly or "fake" name goes on the left while the url to redirect to silently goes on the right. Also make sure you've set the directory base to /. Finally it's good to add an [L] to enforce it to be the last rule in case anything in the same file tries to rewrite the path. Due note that other htaccess files lower down, depending on the files location, will also be checked even when enforcing the rule has the last rule. Also junk the options part completely. Give this a try:
RewriteBase /
RewriteEngine On
RewriteRule ^FriendlyNamed.html FileIWantToChange.html [L]
RewriteRule ^fileThathasalongname.html file.html