How to .htaccess pseudo-static + hidden extension? - apache

Why can't I use the following?
RewriteRule ^(.*)$ $1.html [L]
.htaccess file:
RewriteRule ^(.*)$ index.php [L]
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L]

RewriteRule ^(.*)$ index.php [L]
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L]
The first rule rewrites everything to index.php. The directives that follow are effectively ignored.
However, the second rule also rewrites everything (same pattern ^(.*)$ - obvious conflict), that doesn't map to an existing file or directory to append a .html extension. This second rule is more restrictive.
It seems that what you want to do is:
Append the .html extension to URLs that would map to .html files.
Rewrite all other requests that (I assume) do not map to physical files and directories to index.php.
Additional assumptions
The .htaccess file is located in the document root.
Requested URLs that should map to .html files do not contain dots in the URL-path. Therefore, dots in the URL-path indicate file extensions only.
If you literally rewrite everything else to index.php (as you were doing) then it will also rewrite all your static resources (CSS, JS, images, etc.), so I assume you want to make exceptions for static resources and anything that would otherwise map to a file or directory.
Try the following instead:
RewriteEngine On
# Append the ".html" extension if the target file exists
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^([^.])$ $1.html [L]
# Rewrite other requests that don't map to files/directories to index.php
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule !\.(?:css|js|jpg|png|gif)$ index.php [L]

Related

For specific url 'www.example.com/mobile' I want url rewrite to another specific path: 'root_folder/mobile/index.html'

I created a website in Symfony and the mobile version in Ionic.
Now all URLs are redirected to /public/index.php.
I want to add another URL rewrite in .htaccess to redirect all www.example.com/mobile/* to ionic app that is in the root folder /mobile/index.html.
I already tried to add this in root_folder/mobile/.htaccess
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/mobile/.*$
RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
My root_folder .htaccess is:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /public/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.ch$
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|svg|webp|mp4|css|js|txt)$
RewriteRule ^(.*)?$ public/index.php [L]
<If "%{REQUEST_URI} =~ m#/mobile/?#i">
RewriteCond %{REQUEST_URI} !^/mobile/.*$
RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
</If>
RewriteCond %{REQUEST_URI} !^/mobile/.*$
RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
The RewriteRule pattern matches against the URL-path relative to the directory that contains the .htaccess file. So, the above RewriteRule will never match when inside the /mobile/.htaccess file. Likewise, the condition will never be successful, since if the .htaccess is triggered then /mobile/ must already be present in the URL-path.
This is also an external 301 redirect, not an internal rewrite. It needs to be an internal rewrite (just like the rewrite to public/index.php in the root).
However, presumably you also want static assets to be ignored and served directly, so you need exceptions for files (and optionally directories), just as you are doing in the root .htaccess file (when rewriting to public/index.php).
Try the following instead, in the /mobile/.htaccess file:
# /mobile/.htaccess
RewriteEngine On
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
You don't need to specify /mobile in any of the directives since the RewriteRule pattern matches against the relative URL-path (as mentioned above) and the substitution string is (by default) relative to the directory that contains the .htaccess file.
By default, the mod_rewrite directives in the /mobile/.htaccess file completely override the directives in the parent .htaccess file. The directives in the parent .htaccess file are not even processed.
<If "%{REQUEST_URI} =~ m#/mobile/?#i">
RewriteCond %{REQUEST_URI} !^/mobile/.*$
RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
</If>
You should remove this <If> block in the root .htaccess file. (It's not actually doing anything.)

Hiding file extension and redirecting to https

First off, I know there are many questions similar to this one. I've read everything I can find, but the solutions I see elsewhere don't seem to work for me. I'm really hoping someone can give me some insight here.
I am trying to use Apache's .htaccess directives to force specific pages on my server to use ssl. In addition to those directives, I'm also using some rewrites to mask .php and .html extensions.
I created a page, https-test.html. I want that page specifically to always get redirected so it uses https and so that .html gets stripped off, like https://www.example.com/https-test
However, I seem to always end up with a loop. Reading the Apache docs for 6 hours got me closer, but I'm still missing something.
Below is my annotated htaccess file.
RewriteEngine on
# If port is insecure...
RewriteCond %{SERVER_PORT} ^80$
# And requested URI is /https-test...
RewriteCond %{REQUEST_URI} ^(.*/)https-test$ [NC]
# Then point the server to the secure url:
RewriteRule . "https://www.example.com/https-test" [L,R]
# The next few lines try matching extensionless requests to .php files
# If the requested file is not a directory...
RewriteCond %{REQUEST_FILENAME} !-d
# And we CAN find a .php file matching that name...
RewriteCond %{REQUEST_FILENAME}\.php -f
# Then point us to that .php file and append the query string.
RewriteRule ^(.+)$ $1.php [L,QSA]
# These next few lines were added by the previous project owner
# They're supposed to redirect requests like /foo.html to /foo,
# But I suspect these might be the culprit
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)/$ /$1 [R=301,NE,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ /$1.html [NE,L]
# Next few lines are legacy SEO stuff, some pages were linked to as
# php but now are html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} .php$
RewriteRule ^(.*).php$ /$1.html [L,NE]
So that's the code I have in my htaccess. And if I go to http://www.example.com/https-test in Chrome, I get www.mysite.com redirected you too many times.
You should probably just rewrite the code a bit. You are trying to match both extensionless files to php and html and doesn't look like you're accounting for each of the conditions. You should add a condition to make sure they are not tryiing to do the same things.
Backup your code, replace your code with this and give it a try. Clear all your cache before trying.
RewriteEngine on
# If port is insecure... redirect for a specific page
RewriteCond %{HTTPS} !^on [OR]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^http-test/?$ https://www.example.com%{REQUEST_URI} [R=301,L]
# Next few lines are legacy SEO stuff, some pages were linked to as
# php but now are html
RewriteCond %{THE_REQUEST} ^GET\ /(.+)\.php
RewriteRule ^ /%1? [R=301,L]
# The next few lines try matching extensionless requests to .php files
# If the requested file is not a directory and php file exists
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L,QSA]
#remove trailing slash and is not a php file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php !-f
RewriteRule ^([^\.]+)/$ /$1 [R=301,NE,L]
#finally redirect extensionless URI to html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ /$1.html [NE,L]
Note I haven't tested this fully.

how to remove .php extension from the url

there is no .htaccess file on my server website folder so i paste .htaccess file from other website in my website and write the rule as
RewriteRule ^terms-of-use$ terms-of-use.php [L]
RewriteRule ^privacy-policy$ privacy-policy.php [L]
but does not work.
You could try something like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ $1.php [L]
It would make (almost) any of your PHP files to work without the .php extension. The only exclusion is, for example:
If you have a file called index.php, and a directory called index, then it would prefer the directory first (as the RewriteCond %{REQUEST_FILENAME} !-d tells the rewrite engine to only apply this rule, if the target is not a directory).

.htaccess Rewrite Within Directory - Hide PHP extension and force trailing slash

I'm trying to hide the .php extension from my files as well as force a trailing slash on the resulting URLs.
Example: A request to /about.php would become /about/ and requests to /about would go to /about/.
The following rewrite code worked perfectly when I was in the root of my hostdomain:
RewriteEngine On
RewriteRule ^(.*)/$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://edit.mydomain.org/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)\.php\ HTTP/ [NC]
RewriteRule .+ http://edit.mydomain.org/%1 [R=301,QSA]
However, I need to move my files into a directory of this host name. Adding a directory name to the rules and having the .htaccess in the directory itself didn't work at all and seems to cause a endless redirect.
I looked around StackOverflow and other websites and tried numerous examples and ended up with many different errors with the most common being:
Everything is an endless redirect.
Everything except the directory home page is a 500 Error.
about.php redirects to /about but there's no redirect to /about/ and /about/ displays a 500 Error.
Everything working, but the home page (of the directory) index.php when accessed without a filename goes into an endless redirect.
Things redirect to edit.mydomain.org/home/username/public_html/mydomain.org/edit/pagename.php which obviously doesn't exist.
Thanks for any help! I really need to keep these files in a directory although the .htaccess could go into the host name root if its needed.
The directory for this would be edit.mydomain.org/dave/
Save this as a .htaccess and put it in the 'dave' directory
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\..+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ http://edit.mydomain.org/dave/$1/ [R=301,L]
RewriteRule ^(.*)/$ $1.php [L]
This works for me
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

Ignore symlinks in clean URL's in .htaccess

Example URL:
example.com/user
/user is both a symlinked directory and a valid URL to content on my site. I user Horde Routes to request the content and all requests to the site go through index.php.
I currently have a .htaccess file that looks like:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#allow cool urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
#allow to have Url without index.php
But going to /user lists the directory contents rather than the webpage. Is it possible to ignore symlinks?
Additional to that is if you request:
example.com/user/some-css-file.css
That is a valid request that should not be ignored. So is it possible to allow files via symlinks to be requested, but the base symlinks themselves to be ignored and go to index.php?
Thanks :)
The test for !-d will fail when /user/ is requested since it’s actually an existing directory. You might want to use it without that condition and only allow direct access to existing files but not directories:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php [L]
Additionally you could replace the pattern ^(.*) with !^index\.php$ so that a request for the index.php doesn’t require a filesystem lookup:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^index\.php$ index.php [L]
Forget ignoring symlinks just create another RewriteRule. Place it before the "allow cool urls" rule:
RewriteCond %{REQUEST_URI} ^/user/$
RewriteRule (.*) /index.php [L]
So http://www.example.com/user/ or http://www.example.com/user should go to the content. The [L] should prevent further rules from being processed.