htaccess slash extension - apache

I want to force remove the file extension.
Example: domain.com/sub/index.html
to should be automatically redirected to domain.com/sub/index [With out trailing slash]
The .htaccess code I use is not what I really want. It allows index.html to exist and if typed domain.com/sub/index it automatically redirects to domain.com/index/ [It goes to the root and adds a trailing slash]
Please help. Here is my .htaccess code
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
# Forces a trailing slash to be added
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\im\.[a-zA-Z0-9]{1,5}|)$
RewriteRule (.*)$ /$1/ [R=301,L]

You need to set your base path, before any conditions are set, like so:
RewriteBase /sub
You also need to remove both slashes from your rule. So, /$1/ would become $1

Related

.htaccess redirect based on folder

I need help with .htaccess Rewrite rules.
I have a API which can be accessed over http://api.my.domain/products/all which is working fine and is returning result.
I would like to redirect users coming to http://api.my.domain/admin to admin folder.But it is not working with current rules.
I have added this to .htaccess but it is not working correctly for admin folder.
RewriteEngine On
RewriteCond %{Request_Filename} !-F
RewriteCond %{Request_Filename} !-d
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^admin admin/index.php [QSD,L]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ public/index.php [QSD,L]
This is the result I get when I enter http://api.my.domain/admin and is breaking all my php redirects:
http://api.drezga.hr/admin/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/admin/admin/checklogin.php
Can someone, please, tell me what I'm doing wrong? I have spent hours and I can't see it.
Aside: If /admin is a physical directory then you should be requesting /admin/ (with a trailing slash) to begin with, otherwise Apache/mod_dir will issue a 301 redirect to append the trailing slash.
RewriteCond %{Request_Filename} !-F
RewriteCond %{Request_Filename} !-d
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^admin admin/index.php [QSD,L]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ public/index.php [QSD,L]
The first two conditions (RewriteCond directives) are being applied incorrectly to the first rule only. They need to apply to the last rule (the rewrite to public/index.php) then the rewrite to admin/index.php is not necessary (this should be handled by the DirectoryIndex).
There's no need for the QSD flag since you are checking that the query string is already empty - there is no query string to discard!
You should probably be using the -f operator on the condition, not -F (which uses subrequests and is consequently less efficient).
Try the following instead:
DirectoryIndex index.php
RewriteEngine On
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Optimisation (prevent additional filesystem check)
RewriteRule ^public/index\.php$ - [L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . public/index.php [L]
RewriteRule ^$ public/index.php [L]
The RewriteCond %{REQUEST_FILENAME} !-d directive prevents requests for /admin/ being passed to public/index.php.
The additional RewriteRule at the end is to rewrite requests for the root directory, which would otherwise be omitted because of the condition mentioned above. This could be avoided by extending the DirectoryIndex directive instead, although this could change the behaviour if you have other directories that need to be accessible (or should not be routed to public/index.php). For example:
DirectoryIndex index.php /public/index.php

Remove the subfolder from the url path, given that there is no slash at the end

I have the htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /pages/$1 [L]
it removes /pages/ from the url to the pages
but when i open link without the slash at the end:
site.com/contacts
it is redirected to
site.com/pages/contacts/
Is there a way to fix this?
I've tried different results, most often other options cause a redirect to site.com/index.php ( site.com/pages/index.php)
It is happening because pages/contacts is a directory and Apache mod_dir module is adding a trailing slash after request to a directory.
You can check for directory presence and add a trailing / via a rule before rewrite to pages/:
RewriteEngine On
# add a trailing slash if pages/$1 is a directory
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -d
RewriteRule ^(.*?[^/])$ %{REQUEST_URI}/ [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /pages/$1 [L]
Make sure to use a different browser or remove cache data from your browser to test this rule to avoid old cache.

.htaccess - remove everything after third slash in path

On my website, I only use 3 slashes in my URL path:
https://example.com/this/isatest/
Right now I use .htaccess which makes it possible (as a side effect) to add as many stuff on the URL as you like:
https://example.com/this/isatest/hipperdihopperdus/pizza/bacon/with/cheese
I'd like to automatically remove everything after "isatest" while keeping the trailing slash using .htaccess.
This is what my .htaccess currently looks like:
Options -Indexes
Options +FollowSymLinks
RewriteEngine on
# 301 Redirect all requests that don't contain a dot or trailing slash to
# include a trailing slash
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.
RewriteRule ^(.*) %{REQUEST_URI}/ [R=301,L]
RewriteCond %{THE_REQUEST} /index\.html [NC]
RewriteRule ^index\.html$ /? [R=301,L,NC]
RewriteRule ^listen/$ /console/ [NC,L]
# Rewrites urls in the form of /parent/child/
# but only rewrites if the requested URL is not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
How can I achieve this?
As your first rule, after the RewriteEngine directive, you can do something like the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
This checks if there is anything else (the dot) after two path segments and a slash, and redirects to removed "anything else".
Note that this is a 302 (temporary) redirect. Only change this to a 301 (permanent) redirect - if that is the intention - once you have confirmed that it works OK. This is to avoid the browser caching erroneous redirects whilst testing.
UPDATE: It may be more efficient to simply avoid redirecting files that end in a recognised file extension. Or perhaps exclude known directory location(s) of your static resources. For example:
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|png|gif)$ [NC]
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
OR,
RewriteCond %{REQUEST_URI} !^/static-resources/
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
You can add this rule just below RewriteEngine On line:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+/[^/]+/).+$ /$1 [R=301,L,NE]

Vanity URLs without trailing slashes on Apache

The code below rewrites all URLs in the /profiles/ directory on our site from example.com/profiles/name/ to example.com/name/, but we'd also like to remove the trailing slashes to further simplify the resulting URLs to the prettier example.com/name -- just like on modern social media.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /profiles/$1 [NC,L]
How can this be done (and done safely)? We have seen several solutions on Stumble Upon that if combined possibly could work, but all profiles on our site currently have their own physical directories rather than being assembled on the fly by a script.
Update: #jon-lin offered a solution to a similar situation at How to access directory's index.php without a trailing slash AND not get 301 redirect -- but we didn't figure out how to apply it to ours (described above).
You could try doing
RewriteRule ^(.*)/+$ $1 [R=301,L]
Which should work for any url
You need to disable directory slash
Try :
DirectorySlash Off
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /profiles/$1 [NC,L]
Use the following redirection:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.+)/+$
RewriteRule ^ /%1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /profiles/$0 [NC,L]
By adding part of the code suggested by #jon-lin at How to access directory's index.php without a trailing slash AND not get 301 redirect (internally rewriting the trailing slash back in), we actually made this work:
# Vanity URLs
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /profiles/$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/
The profile for Gucci on FASHION NET (located at /profiles/gucci/) can now be accessed at https://www.fashion.net/gucci -- with no trailing slash! Thank you, #jon-lin!!!!

Apache mod_rewrite query string before page and remove extention

I've scavenged the web for answers to my mod_rewrite woes and I feel I'm at the end of my wits. I will have a URL like such: http://www.website.com/dashboard.php?username=stackoverflow. This url isn't the prettiest of such. So my goal is to do a few things here...
Eliminate the extension of the php file (I've been able to do this so far with the code I'll show below, but I don't know that it will stay according to the other things I need to do)
Eliminate the "www" prefix
Move the username query string (only if it's "username", I don't want to match "id" or such) directly after ".com/"
Move the php filename (without the extension) after query string.
The final URL should look like such: http://website.com/stackoverflow/dashboard or perhaps http://website.com/stackoverflow/profile.
The code I have right now which eliminates the file extension is such:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]
# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# rewrite to FILENAME.php if such file does exist and is not a folder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ /$1.php [L,QSA]
Sadly this only fixes one of my issues and after looking at it, I'm getting the feeling there would be a better way to do this...
(1, 3, 4) As I understand you want to use pretty URLs, but backed by PHP pages. So it should be like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\w+)/profile$ /dashboard.php?username=$1 [L]
It will make http://website.com/stackoverflow/profile working as http://www.website.com/dashboard.php?username=stackoverflow
(2)
# Redirect www.site.com to site.com with 301
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]