why does my ReWrite rule not rewrite? - .htaccess

I want to rewrite the urls like
site.com/eng?sentence=a-sentence
to be like:
site.com/eng/a-sentence
I only want the text shown in the brower url to change, I dont want a redirect.
RewriteCond %{THE_REQUEST} ^GET\s/+eng?sentence=([^/?&\s]+) [NC]
RewriteRule ^ /eng/%1 [NC,L,NE]
I have fiddled with it, comparing other rewrite rules i found for a long time, but just cant get it to work, And i really can't figure out why. I tried removing all other rewrite from my htaccess everytime i tested.
here is my htaccess file:
# Use PHP5.3 Single php.ini as default
AddHandler application/x-httpd-php54s .php
AddType application/x-httpd-php .htm .html
Options -Indexes -MultiViews
ErrorDocument 404 /404.php
ErrorDocument 500 /500.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteCond %{THE_REQUEST} ^GET\s/+eng?sentence=([^/?&\s]+) [NC]
RewriteRule ^ /eng/%1 [NC,L,NE]
<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
preferably, if you could fix my rule rather than write your own one that I won't likely understand, that would be great.

I only want the text shown in the browser url to change, I dont want a
redirect.
To change URL in browser you need external redirect using R flag.
Also ? is special regex symbol and to match a literal ? you need to escape it like \?. Also you would need a ? in the target URI's end to strip off query string.
Your complete .htaccess:
RewriteEngine On
# actual oneto pretty URL - external redirect
RewriteCond %{THE_REQUEST} \s/+eng\.php\?sentence=([^&\s]+) [NC]
RewriteRule ^ /eng/%1? [L,NE,R=302]
# pretty URL to actual one - internal rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^eng/([^/]+)/?$ /eng.php?sentence=$1 [L,QSA,NC]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]
I highly recommend you to read: Apache mod_rewrite Introduction

Related

How do I hide a /public/ directory in htacess

My website is website.com/public/login.php. That looks a bit ugly. How do you rewrite htaccess to say website.com/login.php?
I've tried
RewriteEngine On
RewriteBase /public/
RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC]
RewriteRule ^ %1 [L,NE,R=302]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]
The RewriteRule that strips off the /public/ path is currently an external redirect, because of the R=. Since you want the result of that rule to be hidden, it should rather be an internal redirect (also called URL forwarding), and that is written without the R=302 option.
While you're at it, you could also hide the .php from the externally visible URLs since a simple /login looks much cleaner than /login.php.
Solved. It hides /public/
website.com/login.php instead of
website.com/public/login.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /public/$1 [L]
</IfModule>

Why is a / at the end of my URLs giving me a 500 error and why is .htaccess not working

I am running a simple HTML site, with a .htaccess edit. I have several issues.
If I don't put https then - www.example.com/apply will redirect to https www.xyz.com/apply.html - I understand I have the https redirect on. However, I also have it so .html is removed.
https www.xyz.com/apply will load fine
https www.xyz.com/apply/ will give a 500 error because there is a / at the end
.htaccess code is as follows
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(([A-Za-z0-9\-]+/)*[A-Za-z0-9\-]+)?$ $1.php
<IfModule mod_headers.c>
<FilesMatch ".(js|css|xml|gz|html)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
Any ideas? I wrote the code from memory so hopefully I'm not missing something.
Your problem is that you consider all wrong requests without / then you handle them like that , so you should check first whether a wrong request has / or not , then remove it internally , if you want a file look like directory,then handle it by the next rules , priority will be for html then to php so , your rules should look like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
#as per your comment that all css files under /css directory i added the
#following rules
RewriteCond %{REQUEST_URI} !^/css
RewriteCond %{REQUEST_URI} \.css$
RewriteRule ^(.+)/css/(.*)$ /css/$2 [L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^ %1 [L,QSA]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L,QSA]
NOTE: Clear browser cache the test .
Update:
If you want CSS files work while you adding / to files , there is a workaround , for example you put all CSS files in cssfolder directory , so when the request come to either html or php files without trailing slash , css will load normally like /cssfolder/file.css , but with trailing slash the path will be different /file/cssfolder/file.css , you could add rule to remove any request end with css that has any thing before cssfolder directory .
Like that :
RewriteCond %{REQUEST_URI} !^/cssfolder
RewriteCond %{REQUEST_URI} \.css$
RewriteRule ^(.+)/cssfolder/(.*)$ /cssfolder/$2 [L]
These rules above should be after RewriteEngine On at you rules above.

mysterious exception in htaccess rewrites

My htaccess files contains only a few lines that firstly remove the www and then add ".php" to the slug to get the correct php file, so
www.kalicup.fr/seo
should rewrite to
kalicup.fr/seo
and then display the file seo.php (without the .php extension displaying in the url itself)
at the moment
kalicup.fr/seo
correctly displays seo.php without showing the file extension.
however, when I try
www.kalicup.fr/seo
it rewrites to
kalicup.fr/seo.php
adding the .php extension in the url
so there's abviously a problem in my htaccess but I can't see it !
here's my code
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
ErrorDocument 404 /404.php
# redirect the url with www to url without
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?kalicup\.fr)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?kalicup\.co\.uk)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
# add .php to urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
can anyone see the problem ?
Use that in your .htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
ErrorDocument 404 /404.php
# redirect the url with www to url without
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?kalicup\.(?:fr|co\.uk))$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# add .php to urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
Only one test for .fr and .co.uk.
And -MultiViews: http://httpd.apache.org/docs/2.2/en/mod/core.html#options
The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.
http://httpd.apache.org/docs/2.2/en/content-negotiation.html

forcing a rule of a url .htaccess static website

I am developing a static website that contains only .html files under the root folder (/public_html)
I am trying to force an URL rewriting rule here.
All Urls must be like : http://www.domain.com/file #rule 1
Other forms of writing must be rejected and treated as errors such as
http://www.domain.com/file.html #rule 2
http://www.domain.com/file/ # rule 3
Would you please help me on this code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
I succeed in the rules #1 and #3
Please help me on the rule #2, so when a visitor of my site type the url #2 he will be denied and never knows that ithis is a html file
Here is the code that you can use:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html\s [NC]
RewriteRule ^ /%1 [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+?)/?$ /$1.html [L]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.

combine two .htaccess rewrite files

I have two different .htaccess files each doing different things and when i combine them they won't work together.
the first one allows me to enter www.mydoman.com/test and have it mean www.mydomain.com/index.php?page=test
RewriteRule ^([A-Za-z0-9-_]+)/?$ index.php?subclass=$1 [NC,L]
RewriteRule ^.* index.php [NC,L]
The second file cuts off the extension from .html and .php files so can use www.mydomain.com/about insted of www.mydoman.com/about.php
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /cl_clone
## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
## To internally redirect /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
# e.g. example.com/foo will display the contents of example.com/foo.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
Is there a way to allow both of these to work together in one .htaccess file?
You have a redirect rule at the top, and then 2 sets of rules to add either the php or html extensions to the end of the request, if such a file exists. Then your other rule does routing for index.php.
Some things you'll need to work out. You have the rewrite base /cl_clone which doesn't seem like it's going to work at all, in either of the cases, because your URLs don't have cl_clone in the request (e.g. they are simply www.mydomain.com/about, no cl_clone).
So you probably want to remove that.
Otherwise, you can simply add the index.php routing rules at the very bottom of the other rules that you have. You may need to add additional tweaking, perhaps:
RewriteRule ^([A-Za-z0-9-_]+)/?$ index.php?subclass=$1 [NC,L]
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^.* index.php [NC,L]
Or changing your RewriteBase /cl_clone to RewriteBase /

Resources