Slashes with Apache URL Rewrite - apache

.htaccess file with mod-rewrite rules exists at the .htaccess in the public_html folder
User goes to the URL http://www.thedomain.com/download/myfile
Mod-Rewrite rules should actually tell the server to access the URL: http://www.thedomain.com/download.php?index=myfile
How can I do this on an apache server without creating another directory named "download"?
I am getting problems with the normal procedure because of the slash.

Make sure you have multiviews turned off, mod_rewrite is loaded, and then add these rules to the htaccess file in your document root:
Options -Multiviews
RewriteEngine On
RewriteRule ^download/(.*)$ /download.php?index=$1 [L,QSA]
You can also add that in your vhost config but with a leading slash right after ^:
Options -Multiviews
RewriteEngine On
RewriteRule ^/download/(.*)$ /download.php?index=$1 [L,QSA]

Related

htaccess shows 404 error rather than finding index.php

I'm having some issues with a shady URL rewriting
I want to turn http://localhost:81/es/index.php into http://localhost:81/index.php?lengua=es with my .htaccess in order to help the page SEO
This is my current .htaccess
<FilesMatch ".*\.(log|ini|htaccess)$">
deny from all
</FilesMatch>
Options -Indexes
RewriteEngine On
RewriteBase /
FallbackResource "index.php"
RewriteRule ^(en|es|pt)?/?(.*)?$ $2?idioma=$1 [QSA,L]
I have checked that they work with htaccess tester and they're working as expected but when I browse the page it shows a "File not found." error (I do have a index.php, I do not have a es/index.php)
Since my output URL is http://localhost:81/index.php?lengua=es I don't understand why is it not working
I would suggest breaking this in four rewrite rules:
RewriteEngine on
# Redirect to add the trailing slash to language directory
# http://example.com/es > http://example.com/es/
RewriteRule ^/?(en|es|pt)$ /$1/ [R=301,L]
# Redirect to remove `index.php`
# http://example.com/es/index.php > http://example.com/es/
RewriteRule ^/?(en|es|pt)/index\.php$ /$1/ [R=301,L]
# Handle requests for the base language directory
# http://example.com/es/ > http://example.com/index.php?idioma=es
RewriteRule ^/?(en|es|pt)/$ /index.php?idioma=$1 [QSA,L]
# Handle requests for php files within the language directory
# http://example.com/es/foo.php > http://example.com/foo.php?idioma=es
RewriteRule ^/?(en|es|pt)/(.+\.php)$ /$2?idioma=$1 [QSA,L]
I would remove RewriteBase / because I believe that is the default in the root .htaccess file anyway.
I would remove FallbackResource "index.php" because you shouldn't need it based on the examples you have provided. If you keep it, the examples in the documentation show it starting with a slash: FallbackResource /index.php. You should also test without it because it has the potential to conflict with the rewrite rules.
I always like to start rewrite rules with an optional slash ^/? (rather than just ^) so that they can be used both in .htaccess and in httpd.conf without modifications.
The rule in the question makes everything optional including the language code. Rather than (en|es|pt)? my rules use (en|es|pt) so that they don't match if the language code isn't in the URL.
Rather than make the slash after the language directory optional, my rules do different things when it is present and when it is not.
In your rule (.*)? is exactly equivalent to the simpler (.*). I changed it to (.*\.php) so that it only matches PHP files.

AllowOverride and RewriteCond/RewriteRule interactions

I'm trying to set up a site running on Apache 2.4.16 to redirect all www URLs to non-www URLs. I'm using HTML5 Boilerplate's Apache configs to do this (as well as everything else they provide).
https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess
This happens on line 380, seen below:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ %{ENV:PROTO}://%1%{REQUEST_URI} [R=301,L]
</IfModule>
I'm using Include to add the whole file to my vhost config for the site, as well as an AllowOverride All for another .htaccess file at my doc root (same one that comes with Laravel 5):
production.vhost.conf (relevant part)
<Directory /var/www/hostname/production>
AllowOverride All
# Include H5BP server configs
Include server-configs-apache/dist/.htaccess
</Directory>
.htaccess (at doc root)
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Now, almost everything from H5BP's .htaccess was working, except for the redirect from www to non-www. After poking around I noticed that the redirect was only working when I'd remove AllowOverride All from the <Directory> block in the vhost. So the doc root .htaccess was somehow overriding the rewrite conditions.
I've actually already fixed my initial issue by moving the doc root .htaccess contents into the vhost file and removing the AllowOverride, but I'm more curious as to why this was happening; more specifically how AllowOverride interacts with RewriteCond and RewriteRule.
My hunch is that the .htaccess in my doc root was overriding the www to non-www redirect, but I'm not sure why that one specifically. For example, the http -> https redirect worked without issue (line 352 of H5BP, uncommented out in mine), it seemed to be just that one redirect. I didnt even think that those rules could be overridden since RewriteCond/RewriteRules feel unique to me.
If there are any, what are the rules that determine how an .htaccess can override a rewrite rule?
If there are any, what are the rules that determine how an .htaccess
can override a rewrite rule?
Conditions and rules don't dictate how .htaccess works. AllowOverride is what allows .htaccess usage. If you have AllowOverride All then .htaccess is allowed, if you have AllowOverride None, then it's not and it will be ignored. In 2.4 None is the default.
.htaccess is per directory so it will take precedence if it's located in a directory that has rules applied as long as .htaccess file usage is allowed there. Which is confgiured in the server config in VirtualHost or Directory directives.
Also using an include for .htaccess in a vhost is a very bad configuration. If you have access to the vhost file or the config, you should create another config and include it with the .htaccess contents.
You should not be using .htaccess files at all actually with access to the server config. See this apache recommendation on not using .htaccess.
https://httpd.apache.org/docs/2.4/howto/htaccess.html#when

Remove '/home' directory from URL

People i got 'www.domain.com/home'. I want delete from name '/home'. Just on url should left 'www.domain.com'.
I tested .htaccess but this not works. I see server automatic delete 'index.html' from URL. Some rules works in my htaccess but the replacing a names in URL - not.
Somebody know how to delete '/home'? I just spent all morning to find solution, but nothing working...
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteRule ^home/?$ / [L,R=301,NC]

Rewrite requests to a directory (w/o a trailing slash) to index.php in .htaccess

I've seen similar requests for this but was not able to find a hard and fast answer that worked. Essentially I want to internally rewrite requests to a directory (where the requested URL does NOT contain a trailing slash) to the index.php contained in that directory:
http://example.com/foo => http://example.com/foo/index.php
Right now if a request is made to http://example.com/foo apache will do an externally visible 301 redirect to http://example.com/foo/, which in turn will result in the index.php being rendered, but I want to avoid this external redirect and extra request.
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
DirectorySlash On
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (?!^.+?/$)^(.+)$ /$1/index.php [L]

How to use mod_rewrite in a subdomain's .htaccess?

I have a domain (let the name be) mydomain.com.
I added a subdomain, sub.mydomain.com. (It's an other site, the two sites don't have anything to do with each other)
I have mapped the subdomain (with godaddy.com's tool) to /sub directory. It works well with static file paths, ex. http://sub.mydomain.com/js/script.js.php.
However, I would like to be able to use the rewrite module to get http://sub.mydomain.com/js/script.js
My .htaccess files:
.htaccess in the root directory:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^sub.mydomain.com$
RewriteRule ^.*$ http://mydomain.com/sub%{REQUEST_URI} [L,P]
.htaccess in the /sub directory:
RewriteEngine on
RewriteRule ^js/script\.js$ js/script.js.php [L]
(I tried adding RewriteBase /sub/, I didn't succeed).
It seems as if Apache didn't notice the /sub's .htaccess
How can I get the rewrite work on the subdomain's paths?
SOLVED!
After a long, exhausting debugging and googling I found an Apache setting that made the trouble:
I added Options -MultiViews and voilá, it works!
/////////////////////////////////////////////
Now my configuration:
-no .htaccess in the root.
-.htaccess in the root/sub:
DirectoryIndex site/index.php
Options -MultiViews
RewriteEngine on
RewriteRule ^site/js/script.js$ /site/js/script.js.php [L]