htaccess rules dont work on linux server - linux

On my development server running xampp on windows my .htacess rewrite rules are working fine. Once we went to our live server which is running Linux core 3.8.0-21-generic #32-Ubuntu SMP Server version: Apache/2.2.22 (Ubuntu), our rules which do not contain parameters no longer work, yet rules which do have parameters are working.
Options -Indexes
<filesMatch "\.(html|htm|txt|js|htaccess)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
ErrorDocument 404 /404.php
RewriteEngine On
#Main site rules
RewriteRule ^login/?$ login.php [NC,L]
RewriteRule ^contact/?$ contact.php [NC,L]
The above rules which go to contact.php and login.php do not work. But, this more complicated rule with parameters is working:
RewriteRule ^game/([a-zA-Z0-9]+)/?$ handles/handle-game-select.php?name=$1 [NC,L]
Is there differences between the two server environments which is causing this to occur?
Also, it appears that if we do something strange such as: RewriteRule ^contact.x contact.php [NC,L] we are able to reach contact.php...
Very confused on this one.
Thank you for any help.

I suspect that is due to enabling of MultiViews option. Add this line on top to disable it:
Options -MultiViews
Option MultiViews is used by Apache's content negotiation module that runs before mod_rewrite and and makes Apache server match extensions of files. So /file can be in URL but it will serve /file.php.

Related

Htaccess cookie+browser language redirection

We are trying to solve language redirection "the right way" over at https://guestbell.com/. Some idioms first:
a) Each route has a starting URL parameter that identifies the language. e.g. https://guestbell.com/en for English and https://guestbell.com/es for Spanish. There are also https://guestbell.com/en/pricing etc.
b) You can also omit this parameter, e.g. https://guestbell.com/pricing . The language is then detected (cookie, browser-language, qs param or URL param) and added to the URL. Page is SPA in react, the detection is done by i18next library.
c) Every possible page is pre-rendered in HTML files that are served via static server.
Note that because the routes are pre-rendered, routes like https://guestbell.com/pricing doesn't in fact exist in the folder structure (because it's impossible to guess the language prior to front end detection)
What works so far:
You navigate to guestbell.com
You are redirected to https via htaccess
If the file is found, serve it.
If the file is not found, serve a PHP file that is written as follows:
<?php
$cookieName = "i18next";
$path = rtrim(strtok($_SERVER["REQUEST_URI"], '?'), '/');
$supportedLangs = [
'en',
'es',
];
$defaultLang = $supportedLangs[0];
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if(isset($_COOKIE[$cookieName])) {
$lang = $_COOKIE[$cookieName];
}
$finalLang = $lang;
if (!in_array($lang, $supportedLangs)) {
$finalLang = $defaultLang;
}
$newPath = $finalLang . $path . '.html';
if (file_exists($newPath) || empty($path)) {
$newPath = $finalLang . $path;
header("Location: $newPath", true, 302);
} else {
$newPath = $finalLang . '/404';
header("Location: $newPath", true, 302);
}
?>
As you can see, it attempts to detect via cookie or browser language (we know that by this point, the URL param is not present)
This approach works fine but there is one issue.
When navigating to guestbell.com (as most people would), this results into 2 redirects:
HTTP => HTTPS
/ => /en
Ideally, I would like to eliminate this added overhead and do it in one redirect. The only way (that I can imagine at the moment) is to do it via htaccess. The issue is I have no idea if this is possible.
This is the current htaccess for completion sake:
ErrorDocument 404 /404.html
#This is extremely important as it disables rewriting route from en => en/ and then 403-ing on directory
#https://stackoverflow.com/questions/28171874/mod-rewrite-how-to-prioritize-files-over-folders
DirectorySlash Off
# BEGIN WWW omit
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ %{REQUEST_SCHEME}://%1%{REQUEST_URI} [R=301,L]
</IfModule>
# END WWW omit
# BEGIN HTTPS redirect
<IfModule BEGIN HTTPS redirectfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>
# END HTTPS redirect
# BEGIN Omit extension
<ifModule mod_rewrite.c>
#remove html file extension-e.g. https://example.com/file.html will become https://example.com/file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
</ifModule>
# END Omit extension
# BEGIN File detection
<ifModule mod_rewrite.c>
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.php - that file then takes care of language redirection
RewriteRule ^ /index.php
</ifModule>
# END File detection
# BEGIN Compress text files
<ifModule mod_deflate.c>
<filesMatch "\.(css|js|x?html?|php)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
# END Compress text files
# BEGIN Cache
<ifModule mod_headers.c>
<filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|svg|mp4)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(css)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(js)$">
Header set Cache-Control "max-age=31536000, private"
</filesMatch>
<filesMatch "\\.(xml|txt)$">
Header set Cache-Control "max-age=2592000, public, must-revalidate"
</filesMatch>
<filesMatch "\\.(html|htm|php)$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
<filesMatch "sw.js$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
</ifModule>
# END Cache
An alternative would be to leave the language detection to front-end in such cases, and thus losing the prerendering altogether. I don't like this too much as majority of people would navigate to root of the page instead of /en and therefore lose performance. But what worries me is that the performance will be lost anyways due to multiple redirect.
My question stands:
Is it possible to do cookie and browser-language redirection combined with HTTP => HTTPS inside htaccess? If so, could you provide any help in achieving such functionality? If not, could you share the best way of achieving this, or optionally verify that our approach using PHP is "good enough"?
Many thanks.

Htaccess Font Face and Material Icons Css Not working after URL Rewrite

Hi I've got a wierd issue after a htaccess url rewrite... it works fine for the homepage but if i use the format subdomain.domain.com some fonts don't work, some do. The icons don't work it just shows a placeholder icon. It can't load the woff files etc. I think it may be the htaccess directoryindex disabled but i've put a special rule to allow the homepage to be displayed. How do I do the same for the \img\font\ folder which has the fonts. Also more importantly is disabling directoryindex best practice (i did this to avoid index.html being appended to the url's otherwise the rewrite subdomains doesn't work as it always encounters trailing index.html. Is there a way to set directoryindex to empty "" so that the second query works and I don't have to keep adding rules to allow specific folders?
DirectoryIndex disabled
#rewrite homepage to index.php to allow homepage as directoryindex is disabled
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^/?$ index.php [L]
#Rewrite subdomains
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP_HOST} ^(^.*)\.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/index.php?sub=%1 [P,NC,QSA,L]
Thanks!
P.S The earth really is flat.
I'm getting CORS errors in the console but it's the files are on the same server and domain.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://example.com/img/icon/fonts/materialdesignicons-webfont.woff2?v=2.0.46. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). (unknown)
downloadable font: download failed (font-family: "Material Design Icons" style:normal weight:normal stretch:normal src index:1): bad URI or cross-site access not allowed source: http://example.com/img/icon/fonts/materialdesignicons-webfont.woff2?v=2.0.46
Adding this to htaccess fixed everything
<IfModule mod_headers.c>
#allow corrs access from subdomains
SetEnvIf Origin ^(https?://(?:.+\.)?example\.com(?::\d{1,5})?)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
</IfModule>

htaccess condition user-agent

What I'm trying to do is define a rule in my htaccess file that only applies to Internet Explorer:
Header set Connection close
I want this to only apply to Internet Explorer Users (ideally only IE11), I googled this but found no solution and I'm not that experienced when it comes to htaccess. How can I do this? Any hints?
you can just do something like this
RewriteCond %{HTTP_USER_AGENT} "MSIE 11" [NC]
<IfModule mod_headers.c>
Header set Connection "close"
</IfModule>
Make sure mod_headers is enabled though

.htaccess 301 http:// redirect to https:// not being indexed by Google

We recently moved 2 websites to full SSL as we know Google ranks better for secure websites. But it's been over two months and our website is not getting indexed as SSL.
For example;
Within a week of putting ssl on our Joomla site all our urls have changed in Google as https:// which is what we want - this is because we set up a 301 redirect in the Joomla htaccess.
But on our Opencart website which has a differently configured htaccess file it's still displaying only non SSL results on Google. The SSL is working properly on our website and has been crawled dozens of time since by Google but for some reason Google won't index us as a https website.
I am thinking that there's not a proper 301 redirect set up in our htaccess. I have attached it below:
#gzip starts
<ifModule mod_deflate.c>
<filesMatch "\.(js|css|txt|woff)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
#cache starts
<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf|woff|txt)$">
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 14 days"
</IfModule>
Header unset ETag
FileETag None
</FilesMatch>
#domain rewrite starts
RewriteCond %{HTTP_HOST} !^(www\.|$) [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.gomobility.ie/$1 [R=301,L]
# 1.To use URL Alias you need to be running apache with mod_rewrite enabled.
# 2. In your opencart directory rename htaccess.txt to .htaccess.
# For any support issues please visit: http://www.opencart.com
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini|log)">
Order deny,allow
Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
# If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
### Additional Settings that may need to be enabled for some servers
### Uncomment the commands by removing the # sign in front of it.
### If you get an "Internal Server Error 500" after enabling any of the following settings, restore the # as this means your host doesn't allow that.
# 1. If your cart only allows you to add one item at a time, it is possible register_globals is on. This may work to disable it:
# php_flag register_globals off
# 2. If your cart has magic quotes enabled, This may work to disable it:
# php_flag magic_quotes_gpc Off
# 3. Set max upload file size. Most hosts will limit this and not allow it to be overridden but you can try
# php_value upload_max_filesize 999M
# 4. set max post size. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value post_max_size 999M
# 5. set max time script can take. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value max_execution_time 200
# 6. set max time for input to be recieved. Uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value max_input_time 200
# 7. disable open_basedir limitations
# php_admin_value open_basedir none
Any help would really be appreciated.
Your canonical links are still not ssl. OpenCart generates canonical links (view your source). These links are generated through OpenCart and won't be affected by your htaccess.
There are a couple ways to change this. First you could find each instance where you call the link function and add SSL as the 3rd argument.
Replace this:
$this->url->link('example/path');
With this:
$this->url->link('example/path', '', 'SSL');
Or you could change the link funciton to handle all links as SSL links by default. Go to system/library/url.php and change this line.
public function link($route, $args = '', $connection = 'NONSSL') {
To this:
public function link($route, $args = '', $connection = 'SSL') {
Your canonical tag is the http version, I would change that to https to avoid sending conflicting signals.
Just two points which you may of course know. First, make sure your sitemap is indexing https and not http. Second, you have to set up a new website in Google webmaster with the new https website address - do not delete the old one. You will then see the new site being indexed.

Htaccess basic help needed

I'm trying to install friendica on my webhost (hourb, similar to 000webhost but with ssh).
I'm installing it to a directory/subdomain imoppen.domain.com (domain.com/imoppen)
But it says: Url rewrite in .htaccess is not working. Check your server configuration.
and i can't continue the installation.
I think it's something that has to do with directory's with the rewritebase part, but i don't know how to fix it.
It also gives a error in php, but that is not a very big deal for me;
Warning: set_time_limit() has been disabled for security reasons in /home/username/public_html/imoppen/boot.php on line 290
My first .htaccess (domain.com) contains:
# DO NOT REMOVE THIS LINE AND THE LINES BELOW ERRORPAGEID:yLaNyW
ErrorDocument 404 /404.html
# DO NOT REMOVE THIS LINE AND THE LINES ABOVE yLaNyW:ERRORPAGEID
RewriteBase /
My second .htaccess (domain.com/installationdirectory) contains:
Options -Indexes
AddType application/x-java-archive .jar
AddType audio/ogg .oga
<FilesMatch "\.(out|log)$">
Deny from all
</FilesMatch>
SetEnv PHP_VER 5_3
<IfModule mod_rewrite.c>
RewriteEngine on
# Protect repository directory from browsing
RewriteRule "(^|/)\.git" - [F]
# Rewrite current-style URLs of the form 'index.php?q=x'.
# Also place auth information into REMOTE_USER for sites running
# in CGI mode.
# If you have troubles or use VirtualDocumentRoot
# uncomment this and set it to the path where your friendica installation is
# i.e.:
# Friendica url: http://some.example.com
# RewriteBase /
# Friendica url: http://some.example.com/friendica
# RewriteBase /imoppen/
#
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
</IfModule>
As you can see I've tried to use the rewritebase part, which unfortunately did not work.
My overall php version is set to 5.3
It seems like you are on hourb hosting (so am I) I solved it by going to settings -> htaccess -> Allow URL rewriting

Resources