.htaccess to vhost - apache

Anyone know what to put in vhost.conf for apache to replicate this (from .htaccess):
RewriteEngine on
RewriteCond $1 !^(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Basically I want all requests except those for /images, /scripts or /css to go through /index.php.
It works when I use the .htaccess file but I'd like to know how to do it via vhost.conf as well. Anyone know if it's better to use one over the other as well (vhost.conf vs htaccess) in terms of performance, stability, etc?

It should work when prepending the pattern with /, either:
RewriteCond $1 !^(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^/(.*)$ /index.php/$1 [L]
Or:
RewriteCond $1 !^/(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
The disadvantage of .htaccess files is simply that they virtually need to be interpreted with every request while the virtual host configuration is just interpreted once when the server is started.

Gumbo++
I wrote this article on the httpd wiki to cover questions like this one.
http://wiki.apache.org/httpd/RewriteContext

Related

RewriteRule -or Alias for document_root to subdurectory (not redirect) causes either `Bad Request` or `Internal Server Error`

After exhaustive searching on SO and SF I find this rather concerning. All of the related answers causes Apache 2.4 to just break and I have no idea what I'm doing wrong, it should be really simple.
For brevity, here is the code, though I've tested each separately, not all in 1 go as below:
RewriteRule ^(.*)$ .anon.dir/Repo/data/native/fuse/$1 [L]
## Bad Request
RewriteRule .* .anon.dir/Repo/data/native/fuse/
## Bad Request
RewriteRule ^(.*)$ /.anon.dir/Repo/data/native/fuse/$1 [L]
## Internal Server Error
RewriteRule ^(.*)$ - [E=TRGT:".anon.dir/Repo/data/native/fuse/index.php"]
RewriteRule ^(.*)$ %{ENV:TRGT}
## Bad Request
## Alias / %{DOCUMENT_ROOT}/blah ... for vHost/apache conf only
## Internal Server Error - in htaccess
The actual code is in an <if> block, this exactly:
<If "%{QUERY_STRING} =~ /(^|&)ANONFUSETEST($|&)/">
Options -MultiViews
RewriteEngine on
RewriteRule ^(.*)$ .anon.dir/Repo/data/native/fuse/$1 [L]
</If>
I'm using Apache 2.4 and the target subdirectory has no htaccess in it, only an index.php file with <h1>It Works!</h1> inside it .. This is on a shared host at a respectable hosting company, so there should be no funny business going on elsewhere.
Here are some useful links at ServerFault and StackOverflow and
one more .. although as mentioned, it doesn't work .. or I'm doing something wrong, which is most probably the case.
Does it have to do with the . at the start of the path? -that it may be seen as "hidden"? .. I'm out of ideas :/
Any help will be appreciated and rewarded in kind, thanks in advance.
The working solution is rather simple, have a look, elaboration follows:
RewriteEngine on
RewriteCond %{REQUEST_URI} !/.anon.dir/Repo/data/native/fuse/
RewriteRule ^(.*)$ /.anon.dir/Repo/data/native/fuse/ [L,QSA]
There seems to be some internal safety check that enforces a condition that makes sure the request is not the same as the target, additionally:
the target-path starts and ends with a slash
appending $1 to the target will result in 404, so QSA is used instead
if you want to define the path once, you're out of luck, or so it seems
Assigning the path in a variable and using it this way will cause issues, like the following:
<If "%{QUERY_STRING} =~ /(^|&)ANONFUSETEST($|&)/">
RewriteEngine on
RewriteRule ^(.*)$ - [E=TRGT:/.anon.dir/Repo/data/native/fuse/]
RewriteCond %{REQUEST_URI} !%{ENV:TRGT}
RewriteRule ^(.*)$ %{ENV:TRGT} [L,QSA]
## result is `Bad Request`
</If>
If you know how to make this more "dynamic" e.g: using the path only once, then your answer will be preferable.

check if file exists in subdirectories

I have an include file that contains a Rewrite which checks if a semaphore file exists, if not display a maintenance page.
RewriteCond %{DOCUMENT_ROOT}/maintenance.enable -f
RewriteCond %{REQUEST_URI} !/maintenance.html
RewriteRule ^/ http://mydomain/maintenance.html [L]
Normally it works, but I have now a VirtualHost with several applications answering on different context roots:
mydomain/app1
mydomain/app2
etc.
If I change the rule for each apps is working.. but since the number of applications are already a lot, and may increase, I need to create a single rule for all, something like this, where xxx can be any:
<Location /xxx>
RewriteCond %{DOCUMENT_ROOT}/xxx/maintenance.enable -f
RewriteCond %{REQUEST_URI} !/maintenance.html
RewriteRule ^/ http://mydomain/maintenance.html [L]
</Location>
ps. I'm using latest apache 2.4 version
I found a solution similar to what I wanted initially using a macro like this:
<Macro check_maintenance $context>
RewriteCond %{DOCUMENT_ROOT}/$context/maintenance.enable -f
RewriteCond %{REQUEST_URI} !/maintenance.html
RewriteRule ^/ http://mydomain/maintenance.html [L]
</Macro>
And in the vhost configuration added outside the Location directives:
use check_maintenance app1
use check_maintenance app2

Replicate these AliasMatches within .htaccess?

I recently purchased shared hosting for an app that previously worked well on my local server via Apache Virtual Host configuration. However, my shared hosting provider (like most) does not give customers access to the httpd-conf files, meaning I have to emulate the configuration within an .htaccess file (or multiple). This presents a problem, because .htaccess does not support <VirtualHost> configuration including the very important AliasMatch directive. So my question to the community is how might one replicate the following AliasMatches using RewriteRules or Redirects:
AliasMatch /app/(.*)\.(js|css|rdf|xml|ico|txt|gif|html|png|jpg|jpeg|json|eot|woff|svg|ttf|pdf)$ "c:/wamp/www/siteroot/app/$1.$2"
AliasMatch /i18n/(.*)\.json$ "/wamp/www/siteroot/app/i18n/$1.json"
AliasMatch /(.*)\.(js|css|rdf|xml|ico|txt|gif|html|png|jpg|jpeg|json|eot|woff|svg|ttf|pdf|csv)$ "c:/wamp/www/siteroot/adminApp/$1.$2"
AliasMatch /rest/(.*) "C:/wamp/www/siteroot/rest/$1"
AliasMatch /img/(.*) "C:/wamp/www/siteroot/adminApp/img/$1"
AliasMatch /(.*) "C:/wamp/www/siteroot/adminApp/index.html"
The filepaths will obviously be changed accordingly. It seems too obvious to just do:
RewriteRule {regex} {filepath} [R=301]
Any help is greatly appreciated!
You can just remove the root part out, and use L instead of R=301 (which will externally redirect, causing the browser to request a new URL and change what's in the location bar):
RewriteEngine On
# this is to prevent looping
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^app/(.*)\.(js|css|rdf|xml|ico|txt|gif|html|png|jpg|jpeg|json|eot|woff|svg|ttf|pdf)$ /app/$1.$2 [L]
RewriteRule ^i18n/(.*)\.json$ /app/i18n/$1.json [L]
RewriteRule ^(.*)\.(js|css|rdf|xml|ico|txt|gif|html|png|jpg|jpeg|json|eot|woff|svg|ttf|pdf|csv)$ /adminApp/$1.$2 [L]
# Doesn't look like you need this rule
RewriteRule ^rest/(.*) /rest/$1 [L]
RewriteRule ^img/(.*) /adminApp/img/$1 [L]
RewriteRule ^(.*) /adminApp/index.html [L]

ReWrite Rules Issue

I seem to be having an issue with my Apache Rewrites
RewriteEngine on
RewriteBase /
RewriteRule ^wordpress/?$ / [NC,L,R=301]
RewriteRule ^/$ wordpress/ [NC,L]
I simply need to remove /wordpress from the URL as I have pages within Wordpress I want to be seen as the main directory
At the moment the urls are
domain.com/wordpress/blog
I'd rather not have /wordpress, rather domain.com/blog
Any help?
RewriteEngine on
RewriteBase /
RewriteRule ^wordpress/(.*)$ blog/$1 [L]
At the moment the urls are
domain.com/wordpress/blog
I'd rather not have /wordpress, rather domain.com/blog
So it looks like you want to redirect the browser if someone makes a request for domain.com/wordpress/ to a URL without the wordpress bit, then internally rewrite the wordpress bit back into the URI? That's definitely do-able but if you have wordpress rewrite rules somewhere they're not going to play nicely with each other at all.
Any rules in the /wordpress directory will supercede any rules you put in the document root, which is where these rules need to go, and your remove-the-wordress-from-URI rules will be completely ignored. Even if you have rule inheritance turned on, the rules in the /wordpress directory will get executed first.
If all of your wordpress rules are actually in the document root's htaccess file, then just make sure to put these before the wordpress ones:
RewriteEngine on
RewriteBase /
# redirect the browser if someone makes a request for domain.com/wordpress/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wordpress/
RewriteRule ^/?wordpress/(.*)$ /$1 [L,R=301]
# internally rewrite the wordpress bit back into the URI
RewriteRule %{DOCUMENT_ROOT}/wordpress%{REQUEST_URI} -f [OR]
RewriteRule %{DOCUMENT_ROOT}/wordpress%{REQUEST_URI} -d
RewriteRule ^(.*)$ /wordpress/$1 [L]

Use symfony 1.4 without changing apache configuration

Is it possible to set the /web directory as webroot without changing apache configuration file?
I tried using the following .htaccess code, but if i go to localhost/module/, it displays 404 error. But if i go to localhost/web/module/ then everything works.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule sf/(.*) lib/vendor/symfony/data/web/sf/$1 [L]
RewriteRule ^$ web/ [L]
RewriteRule (.*) web/$1 [L]
</IfModule>
i do like this on the root :
RewriteEngine On
RewriteBase /
RewriteRule (.*) ./web/$1 [L]
And edit web/.htaccess uncommented the 'RewriteBase /' line.
this make all the mysite.com/aaaa/bbbb works like mysite.com/web/aaaa/bbbb
Short answer: no.
Bit longer: you will have to edit the apache config at least to give it permission to access the web/ directory, so even if you symlink your web folder to /var/www, it will not work.
This is quiet similar to my question Symfony on virtual host (document root problem).
This is my .htaccess in the project root directory:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/images/ [OR]
RewriteCond %{REQUEST_URI} ^/js/ [OR]
RewriteCond %{REQUEST_URI} ^/css/
RewriteRule ^(.*)$ /web/$1 [L]
RewriteCond %{REQUEST_URI} !^/web/
RewriteRule ^(.*)$ /web/index.php [QSA,L]
This solved my problem but symfony tries to generate every url (eg. using url_for) from the document root so instead of url like domain.com/my-article it generates domain.com/web/my-article.
I had to slightly modify my PatternRouting class to trim the /web prefix from each url. I think this is not the best solution but it works.
Also if I want to access backend application I have to call always /web/backend.php/ because I don't want to have so many rewrite rules in the .htaccess.
If you want to see my extended PatternRouting class source code I'll paste it here.
Yes, it is possible. Copy everything from web/ up a level to your document root. Edit index.php to reflect the fact that everything it includes is now one level closer to its current directory than it used to be (one less ../). You won't have to edit a single other Symfony file.