Apache URL Rewriting misbehaving - apache

I have the setup below; a very simple URL rewrite setup with a test setup
// ----- test.php -----
<?php
phpinfo();
// ----- test.php -----
The config for test.local is as below.
<VirtualHost *:80>
ServerName test
ServerAlias test.*
DocumentRoot /var/www/test
</VirtualHost>
<Directory "/var/www/test/">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* test.php/$0 [R,NE]
</Directory>
Now if I make a request GET http://test.local/my-path-info the default phpinfo() page appears as expected, if I add slash in the path info, that works too. But if I add an encoded forward slash %2F into the URL (example GET http://test.local/my-path-info%2fsomething-else), it comes up as 404 Not found. Basically it doesn't get to the php file.
Any idea why this is happening, and how to get around it?
The setup is on Apache 2.2.13, PHP 5.3.8 on Linux (Centos 5.x).
NOTE: What I am trying to do here is to add a forward slash into one of the path-info components, such that it doesn't get interpreted by the router logic in an MVC framework. Without encoding it, the router cannot differentiate between a slash that is a path separator and the one that is part of a path component.

Because of the apache version that doesnt support NoDecode as an option for AllowEncodedSlashes, I ended up using the below combination. I also had to double url-encode the request URI. Not ideal but works for me for the moment.
<VirtualHost *:80>
ServerName test
ServerAlias test.*
DocumentRoot /var/www/test
AllowEncodedSlashes On
</VirtualHost>
<Directory "/var/www/test/">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Option B below was the key!
RewriteRule .* test.php/$0 [R,NE,B]
</Directory>

Related

Apache: Using VirtualHost redirect to URL with RewriteCond applied?

So I have a RewriteCond that turns:
domain.com/view.php?a=1
into:
domain.com/artist/name
I have a shorter domain: dmn.com that I would like to provide shortlinks for artists:
dmn.com/name
How can I get dmn.com/name to redirect to: domain.com/artist/name while keeping the shortlink in tact?
.htaccess:
#rewrite profile requests
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artist/(.*)$ view.php?a=$1 [QSA,NC,L]
httpd.conf:
<VirtualHost *:80>
DocumentRoot /var/www/html/ // <-- ??? not sure what to put here
ServerName dmn.com
ServerAlias www.dmn.com
</VirtualHost>
Since the directory "/artist" doesn't actually exist (since it's being rewritten), I can't seem to put /var/www/html/artist in the DocumentRoot of the VirtualHost config without Apache spitting back:
Warning: DocumentRoot [/var/www/html/artist] does not exist
I think what you want is not an actual redirection, but another rewrite.
You can't do it with a separate VirtualHost. Well, you can if you point it to the same DocumentRoot and duplicate your rules or load them from a common file, either via .htaccess or a Include directive.
You can also add the short domain name to your main domain ServerAlias
<VirtualHost *:80>
# This should point to your current config
DocumentRoot /var/www/artists_profiles/
ServerName example.com
ServerAlias www.example.com ex.com www.ex.com
</VirtualHost>
Then you add the new rules to the top of the file:
RewriteBase /
RewriteCond %{HTTP_HOST} ex.com
RewriteRule ^(^.*) artist/$1
Then your existing rules should pick up. If you want to avoid the shortened domain from responding to the longer urls you could add a similar RewriteCond to the existing rules:
RewriteCond %{HTTP_HOST} !ex.com

Apache mod_rewrite not happening on localhost

I can't seem to get my head around this. I just pulled down my website files from my server to work on them offline. However, my rewrite conditions are no longer working as expected.
I've been googleing for the last 3 hours and keep coming to these solutions:
put garbage in the .htaccess file to make sure it's being read. I did that and got a 500 error so it is.
Make sure mod_rewrite is enabled, and I make sure it was listed in php_info(). That's not the problem.
Other than that, I can't figure this thing out.
Here's my .htaccess. All I want to do is remove index.php from my URLs:
# Rewrite url no index.php
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule . index.php
Here's my virtual host config at the moment:
<VirtualHost *:80>
ServerAdmin xxxx#gmail.com
DocumentRoot "c:/wamp/www/myapp/public_html/"
<Directory "c:/wamp/www/myapp/public_html/">
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ServerName myapp.local
ErrorLog "logs/myapp.local"
CustomLog "logs/myapp.local" common
</VirtualHost>
I'd also like to make it known that rewrite rules seem to work a bit when they're in the virtual host config. So something like this:
<VirtualHost *:80>
ServerAdmin xxx#gmail.com
DocumentRoot "c:/wamp/www/myapp/public_html/"
<Directory "c:/wamp/www/myapp/public_html/">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# ...other settings...
</Directory>
ServerName myapp.local
ErrorLog "logs/myapp.local"
CustomLog "logs/myapp.local" common
</VirtualHost>
I had other problems with this though since I have nested applications (one's at / and the other at /app2/). I also seemed to have problems with the !-f condition being ignored and it would rewrite the URLs of my images and css.
Does anyone have any ideas on how to fix this? Thanks in advance!
You should use your code like this to remove index.php from the URL.
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ /index\.php(.*)\ [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [L,QSA]
And then in your head section of your html add this to fix CSS problem.
<base href="http://myapp.local" />

URL rewrite using Apache

I have an application hosted in Apache
http://www.example.com
The DocumentRoot is set as /var/www/html/myapp
Now, I want to write a rule, such that, if someone triggers the URL http://www.example.com/abc, it should redirect to http://www.example.com
The tricky part is, this redirection should happen only if user directly copy-paste http://www.example.com/abc or refresh the browser when the user is in http://www.example.com/abc
"abc" can be any string.
I got this working with the following addition to httpd.conf
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /var/www/html/abc
<Directory /var/www/html/abc>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
</VirtualHost>

Apache cookie-based transparent proxy / redirect

I have a number of sites running on the same machine, served by httpd. Each of the sites is set up as a VirtualHost on a different subdomain. Furthermore, for each subdomain, there are two VirtualHosts on different ports: one for the 'stable' version, one for the 'beta' version. The stable version is hosted on port 80.
Upon logging into the (stable version of the) sites, a cookie is set if the backend determines the user should be using the beta version.
I'd like Apache to detect this cookie on subsequent requests to the stable version and (without the user being aware) redirect the request to the beta version.
How can I achieve this?
I've tried using RewriteCond / RewriteRule in httpd.conf, but it doesn't seem to have any effect - perhaps Apache ignoring it in favour of the matching VirtualHost, or is sensitive to ordering (I think the VirthalHost definitions are being included first)? Perhaps I should be using mod_proxy, anyway?
Config
I've included (anonymised) snippets of my config below
httpd.conf
Listen 80
NameVirtualHost *:80
Listen 81
NameVirtualHost *:81
Include "/path/to/checkout/config/[stage]/apache2/*.conf" # VirtualHosts of sites
Include "/path/to/checkout/config/common/apache2/*.conf" # My attempted redirect
config/[stage]/apache2/[site]/apache2/[app-stable].conf
<VirtualHost *:80>
ServerName [app.hostname]
ServerAlias [alternative-app-name.hostname]
DocumentRoot "/var/www-application/release-base/current/app/public"
<Directory "/var/www-application/release-base/current/app/public/">
Options Indexes FollowSymLinks
AllowOverride All
</Directory>
<!-- snip -->
</VirtualHost>
config/[stage]/apache2/[site]/apache2/[app-beta].conf
<VirtualHost *:81>
ServerName [app.hostname]
ServerAlias [alternative-app-name.hostname]
DocumentRoot "/var/www-application/beta-release-base/current/app/public"
<Directory "/var/www-application/beta-release-base/current/app/public/">
Options Indexes FollowSymLinks
AllowOverride All
</Directory>
<!-- snip -->
</VirtualHost>
config/common/apache2/common.conf
# !!! This has no effect !!!
RewriteEngine On
RewriteCond %{HTTP_COOKIE} cookiename
RewriteCond %{SERVER_PORT} !8081
RewriteRule ^ https://%{HTTP_HOST}:8081%{REQUEST_URI} [R,L] # (R for debugging)
App .htaccess (in case it's relevant)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
You have two problems:
The redirects in global scope are ignored; move them to vhost scope
The "%{HTTP_HOST}" var includes the port number, so you are redirecting to http://hostname:80:81/foo (hence your "hang")
In order to make this transparent, you need to use the [P] flag on the RewriteRule, and include a ProxyPassReverse directive. Your final directives (in each 'stable' conf file) should be as follows:
RewriteCond %{HTTP_COOKIE} absVersion
RewriteRule ^/(.*) http://hostname:81/$1 [P]
ProxyPassReverse / http://hostname:81/
Note that this requires mod_proxy (and any necessary submodules, e.g. mod_proxy_http) to be enabled.

Using mod_vhost_alias with CakePHP (which uses mod_rewrite)

I am not an apache guru. But I want to configure my server for mass virtual hosting using CakePHP. The idea is that we will be able to easily set up multiple versions of the same application based on directory location:
production.domain.com
testv1.domain.com
etc...
So I know I have mod_vhost_alias working just fine. I have a basic directory set up where I have added a test index.html file (/var/www/htdocs/cake/test/webroot). When I point my browser to the location (test.domain.com), the index.html is displayed in the browser. My vhost is configured to pull %1 from the URL to know what directory to point to:
VirtualDocumentRoot /var/www/htdocs/cake/%1/webroot
But when I point my browser to the cake application, I get a page not found error. I suspect it has something to do with the mod_rewrite in the .htaccess file. Here are the full configs for both:
mod_vhost_alias (in .conf file)
<VirtualHost *:80>
ServerAlias *
UseCanonicalName Off
VirtualDocumentRoot /var/www/htdocs/cake/%1/webroot
<Directory /var/www/htdocs/cake/%1/webroot>
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
.htaccess (in webroot - default as it comes from CakePHP)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
Any ideas how to get them to work together?
Turns out all it needed was:
DirectoryIndex index.html index.php