htaccess, one line does not work - apache

I am using this htaccess file. Everything is working fine except that first RewriteRule.
When I open localhost/music/test/ I get a 404 not found error.
When I open localhost/music/ or localhost/music/a/b/etc/ it works like it should.
Anyone knows what I am doing wrong here?
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\..+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^([^/]*)/$ /music/index.php?id=$1 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3&fid=$4 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3&fid=$4&fiid=$5 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3&fid=$4&fiid=$5&siid=$6 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3&fid=$4&fiid=$5&siid=$6&seid=$7 [NC,L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /music/index.php?id=$1&sid=$2&tid=$3&fid=$4&fiid=$5&siid=$6&seid=$7&eiid=$8 [NC,L,QSA]
Could the apache conf or the virtualhost break the htacces file for one line?
apache conf is the default conf (apt-get apache2)
virtualhost file
<VirtualHost *:80>
ServerAdmin wouter1994_67#hotmail.com
ServerName sites
DocumentRoot /var/www/sites
<Directory /var/www/sites>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Note: the music dir is inside the sites dir

I can't see anything wrong with the htacess file but you could just make it redirect all traffic going to music/test to music/a/b/ect

RewriteCond directives only affect the first immediate RewriteRule, so the 3 conditions you have:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\..+$
RewriteCond %{REQUEST_URI} !/$
Are only applied to the first rule:
RewriteRule ^([^/]*)/$ /music/index.php?id=$1 [NC,L,QSA]
And all the other rules aren't bound by those 3 conditions. The reason why the first rule probably never gets applied is because you have the condition: %{REQUEST_URI} !/$ which says if the URI does not end with a slash. But the rule itself requires that the URI ends with a slash (^([^/]*)/$). I'm going to assume that your conditions are missing a ^ in front of them and that you meant:
RewriteCond %{REQUEST_URI} !^\..+$
RewriteCond %{REQUEST_URI} !^/$
As in, does not start with a . and is not a /. You'll also want to duplicate those conditions for each of the RewriteRule entries that you have if you want them to also be applied to the other rules.

Related

RewriteRule overrides ProxyPass

On a centos 7 machine, I'd like to run a python server alongside an apache server. I figured the easiest way would be to configure apache as a reverse proxy. This is my VirtualHost configuration:
<VirtualHost *:443>
DocumentRoot /home/username/mydomain/src
ServerName mydomain.com
ErrorLog logs/mydomain-error_log
CustomLog logs/mydomain-access_log common
DirectoryIndex index.php
<Directory /home/username/mydomain/src>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
AddOutputFilterByType DEFLATE text/html text/plain text/xml
</Directory>
ProxyPreserveHost On
ProxyPass /mediaproxy http://127.0.0.1:9001/mediaproxy
ProxyPassReverse /mediaproxy http://127.0.0.1:9001/mediaproxy
LogLevel alert rewrite:trace6
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/api/media/(.*) /data/$1 [L]
RewriteRule ^/api/v1/* /api/v1/index.php [L]
RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
RewriteRule ^/* /index.php [L] # problematic rule
// lets encrypt entries
Now, my problem is that rewrite rules takes precedence over ProxyPass. That ism when I visit mydomain.com/mediaproxy/somepage, it serves the content at /index.php, specified with RewriteRule ^/* /index.php [L] . Reverse proxy works correctly if I remove the problematic rule. Unfortunately I need to keep it.
How do I tell apache to use ProxyPass rule first, and use RewriteRule only if there is no match?
RewriteRule ^/* /index.php [L] # problematic rule
Your rule rewrites everything. You could just make an exception for the URL-path you want to proxy. For example:
RewriteRule !^/mediaproxy /index.php [L]
The ! prefix on the RewriteRule pattern negates the expression. So it is successful when it does not match.
This now rewrites everything except URL-paths that start /mediaproxy.
Note that the trailing * quantifier in the regex ^/* repeats the preceding token 0 or more times. The preceding token in this instance is the slash. You are missing the preceding . (dot). Or omit the .* entirely as it's superfluous (and less efficient).
Aside:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/api/media/(.*) /data/$1 [L]
RewriteRule ^/api/v1/* /api/v1/index.php [L]
RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
RewriteRule ^/* /index.php [L] # problematic rule
The two conditions (RewriteCond directives) are not doing anything here. When used in a virtualhost context, REQUEST_FILENAME is the same as REQUEST_URI, since it is processed early, before the request is mapped to the filesystem. Consequently, both (negated) conditions will always be successful and the following rule is always processed. In a vhost context you need to use a lookahead, ie. LA-U:REQUEST_FILENAME, OR construct the file-path using the DOCUMENT_ROOT server variable, OR move the rules into a directory context.
However, those two conditions only apply to the first rule that follows. So all the remaining rules (including the last "problematic" rule) are processed unconditionally anyway. This is generally incorrect for a front-controller pattern (the last rule) and should perhaps be written like this instead:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !^/mediaproxy /index.php [L]
This now rewrites everything except URL-paths that do not start /mediaproxy AND do not map to a directory AND do not map to a file.
Alternatively, if these condtions should be applied to all rules then create a negated rule instead. For example:
DirectoryIndex index.php
RewriteEngine on
# Prevent further processing if root directory or "index.php" requested
RewriteRule ^/(index\.php)?$ - [L]
# Prevent further processing if the request maps to a directory or file
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule ^/. - [L]
RewriteRule ^/api/media/(.*) /data/$1 [L]
# This rule is not required since the DirectoryIndex handles this case (the regex is also "incorrect").
#RewriteRule ^/api/v1/* /api/v1/index.php [L]
RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
RewriteRule !^/mediaproxy /index.php [L]

Redirect if specific URL is given with htaccess

I have a very straightforward url friendly htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(\w+)/?$ index.php?id=$1
So domain.com/something is mapped to domain.com/index.php?id=something.
Every URL can have an additional parameter, so for example domain.com/something can be in the form of domain.com/something?custom_value
Now I need to address this particular situation: If a particular ID is matched, then a custom value must be forced. So, if I go to domain.com/somethingelse I want to be redirected to domain.com/somethingelse?custom_value
I've tried different rules with no luck. This was my last attempt but I get a message that the server is making a rediretion that will never be completed.
RedirectMatch 301 ^/(somethingelse)/?$ /somethingelse?custom_value
Another attempt was this, resulting in a 500 Internal Server Error
RedirectMatch 301 ^/(somethingelse)/?$ somethingelse?custom_value
complete htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RedirectMatch 301 ^/(somethingelse)/?$ somethingelse?custom_value
RewriteRule ^(\w+)/?$ index.php?id=$1
EDIT 1:
Well, apparently this rule works (not always) on local machine, but no online server
RedirectMatch 301 ^somethingelse$ somethingelse?custom_value
EDIT 2:
I've also tried (also works on local machine, but no online server)
RewriteRule ^/somethingelse$ /somethingelse?test [L,R=301]
EDIT 3
These are my virtualhosts:
local virtual host
<VirtualHost vhostname>
DocumentRoot /var/www/path/to/project
<Directory /var/www/path/to/project>
AllowOverride All
</Directory>
</VirtualHost>
server virtual host
<VirtualHost *:80>
ServerName subdomain.domain.com
DocumentRoot /var/www/path/to/project
<Directory /var/www/path/to/project
AllowOverride All
</Directory>
</VirtualHost>
You may use these rules in your site root .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^somethingelse/?$ %{REQUEST_URI}?custom_value [R=301,L,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\w+)/?$ index.php?id=$1 [L,QSA]
Make sure to test this in a new browser or test it after completely clearing your browser cache.

rewritecond not working for existing files

I have a problem with mod rewrite apache seems to ignore the rewrite cond.
The rewrite rule is working as all my pages are working but the problem is with resources like css, imgs and js. In my html I use "href=assets/css/style.css" which is an existing file but i i am redirected on my index.php...
Is there something i did wrong ?
here is my vhost config
<VirtualHost *:*>
ServerAdmin me#local.loc
DocumentRoot "c:/wamp/www/Covoiturage"
ServerName covoiturage.loc
ErrorLog "logs/covoiturage-error.log"
CustomLog "logs/covoiturage-access.log" combined
<directory c:/wamp/www/covoiturage/>
Allow from all
AllowOverride all
</directory>
</VirtualHost>
here is my htaccess :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
RewriteRule ^ index.php [L]
You are adding RewriteCond to wrong RewriteRule. RewriteCond only in effect to very next RewriteRule. Try this code:
RewriteEngine On
## Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

Apache Rewrite Rule httpd-vhosts.conf

I have a VHOST with the following rule
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^.*$ /router.php [NC,QSA,L]
Pretty much just makes every URL go through an advanced routing system
However, its becoming a conflict when trying to set up my news system using WordPress.
All I need help with is creating a new rewrite rule to put all through the router with the exception of one directory, for example named "wordpress."
Its all on my local machine, but here is the entire VHOST config
<VirtualHost *:80>
DocumentRoot "/Users/tyler/Documents/mysite"
ServerName mysite.local
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^.*$ /router.php [NC,QSA,L]
<Directory "/Users/tyler/Documents/mysite">
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
All I need help with is creating a new rewrite rule to put all through
the router with the exception of one directory, for example named
"wordpress."
Based on that criteria, you should add the following rule to the mix:
RewriteCond %{REQUEST_URI} !^/wordpress
Which will make the whole ruleset now be as follows:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/wordpress
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^.*$ /router.php [NC,QSA,L]

Send one subdomain to subdirectory, everything else to file with parameter

Hoo-boy I've been struggling with this one all day.
The redirect from the subdomains to the script files with subdomain passed in as a parameter work fine.
When one particular subdomain is actually a real folder (phpmyadmin), I can't seem to make it work, at least not with the previously mentioned rule in place.
Here's my stuff:
<VirtualHost *.domain.com:443>
ServerName *.domain.com
ServerAlias *.domain.com
DocumentRoot /home/domain/web
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.* [NC]
RewriteCond %{HTTP_HOST} ^(phpmyadmin)\.domain\.com
RewriteCond %{REQUEST_URI} !^phpmyadmin
RewriteRule ^(.*)$ /phpmyadmin [L]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com
RewriteRule ^\/script2$ /public/script2.php?param1=%1 [L]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com
RewriteRule ^(.*) /public/script1.php?param1=%1 [L]
<Directory /home/domain/web>
Options -Indexes IncludesNOEXEC FollowSymLinks -MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
SSLEngine on
SSLCertificateFile /home/domain/crt
SSLCertificateKeyFile /home/domain/key
</VirtualHost>
Any ideas?
2 problems with:
RewriteCond %{HTTP_HOST} !^www.* [NC]
RewriteCond %{HTTP_HOST} ^(phpmyadmin)\.domain\.com
RewriteCond %{REQUEST_URI} !^phpmyadmin
RewriteRule ^(.*)$ /phpmyadmin [L]
In your target redirect, you do not change the domain. By just using /phpmyadmin, you're not directing to www.domain.com/phpmyadmin, you're directing to phpmyadmin.domain.com/phpmyadmin, which is likely to cause an infinite redirect loop since it will keep matching the phpmyadmin subdomain each redirect. Use:
RewriteRule ^(.*)$ http://www.domain.com/phpmyadmin [L]
Unlike RewriteRule where the initial / is not used, RewriteCond %{REQUEST_URI} does need the leading slash like so:
RewriteCond %{REQUEST_URI} !^/phpmyadmin
Failing to do so means its not matching the directed /phpmyadmin, leading to another potential self-matching infinite redirect loop.
Also you don't need
RewriteCond %{HTTP_HOST} !^www. [NC]
since your url would never start with www and also start with phpmyadmin. Matching
RewriteCond %{HTTP_HOST} ^(phpmyadmin)\.domain\.com
automatically implies the NOT www match condition is also true