apache2 mod_rewrite based on language then proxy - apache

I am trying to redirect a user that visits www.server.com to the browser's preferred language setting.
When a user types in www.server.com/<lang>, /es for spanish in the case below, they are correctly proxied to the smartling translation servers. However, when a user has their language preference set in their browser, they experience a redirect loop.
I have the following config:
<VirtualHost *:8008>
ServerName www.server.com
ServerAlias www
ProxyPreserveHost On
RewriteEngine On
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule ^/$ es/ [R=301,L]
<Proxy http://server.sl.smartling.com/*>
Allow from all
</Proxy>
<LocationMatch "/es">
ProxyPass http://server.sl.smartling.com/es
ProxyPassReverse http://server.sl.smartling.com/es
Header add Host "www.server.com"
RequestHeader set Host "www.server.com"
</LocationMatch>
DocumentRoot /www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/www-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/www-access.log combined
</VirtualHost>
I've tried stopping the loop with additional RewriteCond but can't seem to get it right. Any suggestions appreciated.
Thanks

You'll need to add another condition to negate the locale condition. The locale condition will always be true if it is set in the user's browser. Try adding a condition like this
RewriteCond %{REQUEST_URI} !^/es

Related

Subdomains Always Redirect To Main Domain - Apache2 VirtualHosts & Debain

I want to set up a main site, and a sub-domain for development, using apache2 VirtualHosts. This is what my site.conf virtual host file looks like:
<VirtualHost *:80>
ServerName dev.mysite.com
DocumentRoot /var/www/site/subdomain
<Directory /var/www/site/subdomain >
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel debug
CustomLog ${APACHE_LOG_DIR}/sub.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName www.mysite.com
ServerAlias mysite.com
DocumentRoot /var/www/site/main
<Directory /var/www/site/main >
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
The problem is that every time I visit dev.mysite.com, I just get mysite.com.
There's no htaccess for the main site, and the .htaccess for the sub-domain looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I've tried all the other solutions I could find (using literal IPs, re-ordering things, using ports instead of named hosts)... I'm totally stuck now. The site is enabled of course. Anyone got any ideas?
Wordpress Was The Problem
Or rather, me not knowing that I had to configure the Wordpress site url to be the subdomain, otherwise it would just redirect to the domain given...
So the solution: open the wp_options table and edit the site_url to include the subdomain.

URL rewrite doesn't work in a Symfony2

I have a web site under Symfony 2 and want to have a basic URL rewrite.
Apache mod rewrite is enabled. Apache has been restarted multiple times.
# a2enmod rewrite
Module rewrite already enabled
Virtual host seems ok
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
DocumentRoot /home/www/mydomain/web
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /home/www/mydomain/web>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And here's my .htacess
<IfModule mod_rewrite.c>
RewriteEngine On
#<IfModule mod_vhost_alias.c>
# RewriteBase /
#</IfModule>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
But http://mydomain.com/ gives the "index of" page and I have to pass through http://mydomain.com/app.php/ to access my web site.
What am I missing ?!!
You need to change AllowOverride None to AllowOverride All
When this directive is set to None and AllowOverrideList is set to
None .htaccess files are completely ignored. In this case, the server
will not even attempt to read .htaccess files in the filesystem.
When not specified, AllowOverrideList is set to None
http://httpd.apache.org/docs/current/mod/core.html#allowoverride

Simple mod_rewrite rule is not working

In my main public directory, I have this .htaccess file, however when visiting /register I get a 404 error.
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^register$ register.php
With this, I want to make anyone who visits /register to use /register.php. I am certain that mod_rewrite is enabled and AllowOverride All is present in my virtual host file.
Does anyone know how I can troubleshoot this? All I get is The requested URL /register was not found on this server.
Virtual host:
<VirtualHost *:80>
ServerAdmin my#email.com
ServerName my.site.com
DocumentRoot /home/mark/public
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /home/mark/public>
Options All MultiViews ExecCGI
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog /home/mark/logs/public_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /home/mark/logs/public_access.log combined
</VirtualHost>
<Directory /home/mark/public>
Options All MultiViews ExecCGI
AllowOverride All
Order allow,deny
allow from all
</Directory>
You need to turn off MultiViews:
Options All -MultiViews ExecCGI
It's messing with optional content negotiation. From the apache documentation:
If the server receives a request for /some/dir/foo and /some/dir/foo does not exist, then the server reads the directory looking for all files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements, and returns that document.
If you're going to have a rule to rewrite /register to /register.php, you don't want MutliViews mucking things up before it even gets to your rewrite rules.
This works for me:
/etc/apache2/sites-enabled/000-default
<VirtualHost *:80>
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
....
</VirtualHost>
/var/www/.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/register$
RewriteRule ^(.*)$ register.php [NS,L]
EDIT: added DocumentRoot /var/www

Redirect non-existent dynamic virtual host folders with Apache

Is it possible to redirect to a certain URL if the directory for the virtual host doesn't exist? I have a VirtualHost setup below that lets me host a domain just by creating the folder, and pointing DNS to my server.
Here is my configuration for the VirtualHost
<VirtualHost *:80>
ServerAdmin webmaster#localhost
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*) http://%1/ [R=301,L]
VirtualDocumentRoot /var/www/%0
<Directory /var/www/%0>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature On
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
You can manage it using rewriting rules.
Just after you rewriting rule to skip www :
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteCond /var/www/%1 !-d
# I think just /var/www/%{HTTP_HOST} works :|
RewriteRule .* http://example.com/nonexistant.php/$0 [L,R]

Apache2 DirectoryIndex Issue

I am a little stuck and am sure that this is a trivial problem, but just can't seem to find the right solution.
I have a local development server running apache2 w/mod_ssl & mod_rewrite.
I created a self-signed cert and added the respective virtual host directive for *:443.
The issue I seem to be having is that now that I have the SSL side of things working properly. And when I say properly, I mean that I can go to the https url of my site (e.g. https://dev.mysite/) without adding index.php and it pulls up the index.php just fine.
But when I go to the regular http url of the site, I have to type in the index.php to see the site. (e.g. http://dev.mysite/index.php)
I tried adding a DirectoryIndex directive to the *:80 block, but this still doesn't appear to work.
Below is the virtual host file contents if that helps at all;
ServerName dev.mysite
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/vhosts/bsah_dev/mysite
<Directory />
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/vhosts/bsah_dev/mysite/>
DirectoryIndex index.html index.htm index.php
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/vhosts/bsah_dev/mysite
SSLEngine On
<Directory /var/www/vhosts/bsah_dev/mysite>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !^on$ [NC]
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L]
</IfModule>
</Directory>
SSLOptions +StrictRequire
SSLCertificateFile /etc/apache2/ssl.crt/server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server.key
</VirtualHost>
A few comments on your configuration, which may help you fix this problem:
<Directory />
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride None
</Directory>
That's quite unusual: normally, you wouldn't grant access to anything for the root directory (of your machine, not your document root). See the Directory documentation, which suggests using this:
<Directory />
Order Deny,Allow
Deny from All
</Directory>
This should work as expected in your configuration:
<Directory /var/www/vhosts/bsah_dev/mysite/>
DirectoryIndex index.html index.htm index.php
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
(This being said, index.php will only be used if there's no index.html or index.htm found first.)
The DirectoryIndex documentation says it can be placed in "server config, virtual host, directory, .htaccess" (see "Context"). It also works within the Directory directive (and such values will override the values you'd find at the VirtualHost or server level).
This rule, in the HTTPS section doesn't make sense:
<Directory /var/www/vhosts/bsah_dev/mysite>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !^on$ [NC]
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L]
</IfModule>
</Directory>
You're using a rewrite rule to redirect to the equivalent https:// URL. However, this rule is in the section where SSL is enabled, so you're redirecting from https:// to https://, not from http://.