Problems with mod_rewrite in Apache (with WAMP) - apache

The Idea: I want to make it that anything that comes after the domain name and ends with .html is treated as a get variable by index.php
Example: www.test.ro/1/2/3.html should actually be www.test.ro/index.php?var=1/2/3.html.
www.test.ro is setup as a virtual host for development, and AllowOverride has value All.
The .htaccess file seems to be processed, but not all the time. If I write a non-recognized rule like 'BizzareRule', the server works without returning a code 500 error.
If I put correct rules between <IfModule mod_rewrite.c></IfModule>, I get an 500 error, even though I have other vhosts using the same conditions and working perfectly.
Here are the contents of my vhost:
<VirtualHost *:80>
ServerAdmin eu#localhost.com
ServerName www.test.ro
ServerAlias test.ro
DocumentRoot D:/Projects/grabsite/test.ro
Options Indexes FollowSymLinks MultiViews
DirectoryIndex index.php index.html
LogLevel warn
ErrorLog D:/Projects/grabsite/test.ro/error.log
CustomLog D:/Projects/grabsite/test.ro/access.log combined
<Directory "D:/Projects/grabsite/test.ro">
Options -Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
And test content for .htaccess:
RewriteEngine On
RewriteRule ^/?([^/]*)\.html$ /index.php?seo=$1 [L]

It seems that you enters in infinite loop. Try first to simplify the rule:
RewriteRule ^(.*)\.html$ /index.php?seo=$1 [L]
Or just
RewriteRule ^index.html$ /index.php?seo=$1 [L]
Next, it's best to have RewriteCond -f and RewriteCond -d in order not to execute the rule if you are requesting existing file/folder. In some situations, this can prevent an infinite loop in the rule

The problem is in regex pattern. You said: "The .htaccess file seems to be processed, but not all the time".
If you check your pattern^/?([^/]*)\.html$ you will see that this will work for files in root folder ONLY (e.g. /index.html).
Solution: change pattern to ^(.+)\.html$ and all will be fine -- now it will match ANY URL that ends with .html (e.g. /index.html as well as /hello/pink-kitten.html etc).

Related

VirtualHost config causing 301 redirect loop

I am trying to setup a virtual server to host multiple websites,
each site's content is in /var/www/html/site.com/public_html.
There have a VirtualHost config for each site under /etc/apache2/sites-available/site.com.conf as seen here:
/etc/apache2/sites-available/site1.com.conf:
<VirtualHost *:443>
DocumentRoot /var/www/html/site1.com/public_html
ServerName site1.com
<Directory /var/www/html/site1.com/public_html/>
AllowOverride None
</Directory>
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/site1.com/public_html
serverName site1.com
<Directory /var/www/html/site1.com/public_html/>
AllowOverride None
</Directory>
</VirtualHost>
All this config is needing to do is direct the incoming domain request to its root directory, nothing else. however the moment I apply apply this config file it will cause a 301 redirect loop.
As you can see I have disabled AllowOverride to avoid interference from .htaccess to eliminate that variable, by enabling AllowOverride to all it also results in a redirect loop with no change in behaviour. In case needed hear is the httpd.conf file that's not getting applied:
.htaccess:
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
I have also tried completely removing the .htaccess file to eliminate that variable and it still resulted in a redirect loop.
Additionally if I where to manually change the URL to point to a file in the site like /index.php or /wp-admin/ it will result in a 302 redirect loop to that same file or folder.
index.php also does not refer back to itself but rather starts the wordpress program, and php.ini also does not have any redirect config.
I cannot find where the redirects may be happening, some guidance on potential faults in the current config of what other files may be causing redirects would be much appreciated.

Split DocumentRoot using Apache Alias per request path

I'm trying to slowly take over an existing website, route per route. I found Apache's Alias(Match) which seems to allow me to set a different (content) document root per request. But I'm failing with trailing slashes and more complex paths.
My goal now is to have the old website serve everything as it is used to. And to have a new website, serving a first specific request, say /foo and /foo/*.
I have my vhost setup like this:
<VirtualHost *:80>
ServerName example.com
UseCanonicalName on
AliasMatch ^/foo/(.*)$ /www/new/$1
AliasMatch ^/foo$ /www/new/$1
<Directory /www/new/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /www/old
<Directory /www/old/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
In both directories I have an .htaccess with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L]
The index.php's show 'old' or 'new' depending on their directory.
What happens to the different routes I test:
When requesting example.com/bar it shows 'old'.
When requesting example.com/foo it redirects too /foo/, and then shows 'new'.
When requesting example.com/foo/bar it shows 'old'.
I don't want the forced redirect of /foo to /foo/. And I want /foo/bar to show 'new'.
I've been following Apache's mod_alias to get the multiple AliasMatch directives to catch anything after /foo but apparently that's not working correctly. Also, I don't read anything there of the trailing slash being added magically.
Anyone knows the magic tricks?
I've been able to fix this by adjusting the Alias to point to the index.php directly:
AliasMatch ^/foo/(.*)$ /www/new/index.php
AliasMatch ^/foo$ /www/new/index.php
Then /bar and anything else goes to the old website, and /foo, /foo/ and /foo/bar goes to the new website.
There's two downsides to this method:
The .htaccess in the new website is skipped completely. But as I mainly use that for letting the index.php pick up every route, that's fine for now.
Frontend resources like css/js go to the old website. Fix that with another simple alias: example.com/frontend/app.css + Alias /frontend /www/new/public_html/frontend.

"RewriteEngine not allowed here" caused by htaccess in parent directory

Currently I am using OSX Server (Yosemite) to host a bunch of PHP applications, some of which have a sub-directory under the websites document root for subdomains. Since updating to the Yosemite version of OSX Server, these subdomains have been throwing a 500 error with the error log referring to RewriteEngine not allowed here.
Investigating, I have confirmed that both the parent and subdomain sites have AllowOverride All configured, and .htaccess files are working on non-subdomain sites. Also, I have discovered that renaming or otherwise removing the .htaccess file from the parent directory causes the sub-domains to start working again.
/original_site_doc_root <- doc root for regular site
.htaccess
index.php
...
subdomain/ <- configured as a seperate site in osx server as a subdomain
.htaccess
index.php
...
Every bit of googling I do ends up referring to making sure mod_rewrite is installed and AllowOverride is configured properly.
My question is, how can I get Apache to stop throwing a 500 error on the sub-domain sites?
Edit
Here is the .htaccess file for the sub-domain that is causing me grief (with domains, directories and pages fuzzed to protect the innocent)
RewriteEngine On
Options +FollowSymlinks -Indexes
RewriteCond %{HTTP_HOST} ^www\.m\.somesite\.com$ [NC]
RewriteRule ^(.*)$ http://m.somesite.com/$1 [L,R=301]
RewriteBase /
# supress php errors
php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
php_value docref_root 0
php_value docref_ext 0
# enable PHP error logging
php_flag log_errors on
php_value error_log /some/fuzzed/dir
RewriteRule ^$ /index.php [L]
RewriteRule ^home$ /home.php [L]
RewriteRule ^some-page1$ /some-page1.php [L]
RewriteRule ^some-page2$ /some-page2.php [L]
RewriteRule ^some-page3/(.*)$ /some-page32.php [L]
RewriteRule ^some-page3(\/?)$ /some-page32.php [L]
RewriteRule ^some-page4/(.*)$ /some-page4.php [L]
RewriteRule ^some-page4(\/?)$ /some-page4.php [L]
RewriteRule ^some-page5/(.*)$ /some-page5.php [L]
RewriteRule ^some-page5(\/?)$ /some-page5.php [L]
RewriteRule ^some-page6/(.*)$ /some-page6.php [L]
RewriteRule ^some-page6(\/?)$ /some-page6.php [L]
The .htaccess for the parent directory/non-sub-domain-site is more or less similar, with the only real difference of relevance being the top 2 lines:
RewriteEngine On
Options +FollowSymlinks -Indexes -Multiviews
Just ran into this same problem (after recent update Apache2) and found a solution.
Assume your domain is example.com and the directory is /var/www/example/, and you had a subdomain called api.example.com with directory /var/www/example/api/.
Try to use the following:
<VirtualHost *:80>
ServerName api.example.com
DocumentRoot /var/www/example/api
<Directory /var/www/example/>
AllowOverride FileInfo Options
</Directory>
<Directory /var/www/example/api/>
Require all granted
Options +FollowSymLinks +MultiViews +ExecCGI -Indexes
AllowOverride all
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
This should work!
Since updating to the Yosemite version of OSX Server, these subdomains have been throwing a 500 error with the error log referring to RewriteEngine not allowed here.
OS X 10.10 (Yosemite) ships with Apache 2.4, whereas earlier versions of OS X ship with Apache 2.2. An important difference between these versions, and which is probably causing you problems, is that AllowOverride defaults to All in Apache 2.2 and None in Apache 2.4. (See the Apache Docs) You are perhaps relying on this default behaviour.
I have confirmed that both the parent and subdomain sites have AllowOverride All configured
But where exactly are the AllowOverride All directives set? I assume the parent and subdomain sites are configured as separate Virtual Hosts. If AllowOverride All is only set in the parent domain's VirtualHost, for the "parent directory" (of the subdomain), then this will not been seen when you access the subdomain, which is an entirely separate VirtualHost. You will need to redeclare this in the subdomain's own (isolated) VirtualHost as well (as in #benck's answer).
Or, if you don't want the parent .htaccess file to be processed at all then explicitly set the following in the subdomain's VirtualHost:
<Directory /var/www/example/>
AllowOverride None
AllowOverrideList None
</Directory>
.htaccess files work along the filesystem path, regardless of the host being accessed.
Alternatively, if the main domain is configured in the main server config (ie. not in a VirtualHost container) then you shouldn't have this problem, as the VirtualHost will inherit the server's configuration.
Reference:
https://en.wikipedia.org/wiki/MacOS_Server#OS_X_10.10_(Yosemite_Server_4.0)

Multiple Zend framework sites on one server

I'm having trouble setting up my httpd.conf or .htaccess files to recognize multiple zend framework sites on one server.
For development, I have just one server and I'm trying to setup the sites so I can access them like localhost/app1, localhost/app2, etc.
So right now, when I go to localhost/app1 it does successfully redirect to localhost/app1/public/index.php, however when I go to localhost/app1/index/index I get a 404.
Here is my vhosts file:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot "/var/www"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/app1/public">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog logs/error.log
CustomLog logs/access.log common
</VirtualHost>
and here is my .htaccess file from the /var/www/app1 directory:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ /app1/public/index.php [NC,R,L]
If I change the DocumentRoot line in the vhosts file to DocumentRoot "/var/www/app1/public" then app1 does work correctly, but I can only access that one... at http://localhost. Is this possible? What I want to happen is if /var/www is the document root, then if I go to localhost/app1, those requests need to redirect to localhost/app1/public/index.php and if I go to localhost/app2 those requests need to redirect to localhost/app2/public/index.php.
I hope I explained this clearly, any help is appreciated.
In the end
I liked Phil's solution best because I didn't want to have to change my local hosts file and use the ServerName directive. It would be fine in a production environment if you own a separate domain name for each app, but not for development.
In addition to that, I was having a 403 forbidden problem when using an alternate directory for serving up web content. As I stated, the perms seemed correct the problem was with SE_Linux, and the security context of the files not being set to httpd_sys_content_t. I'm posting that solution that i found here, as it deals specifically with the issue. Thanks.
Here's what I'd do...
Install your applications somewhere arbitrary but outside the document root, eg /home/sudol/apps/app1 and /home/sudol/apps/app2. Make sure your Apache user can traverse this path and read the files.
Alias the public directories in your <VirtualHost> section
Alias /app1 /home/sudol/apps/app1/public
Alias /app2 /home/sudol/apps/app2/public
Setup your access and rewrite rules in the appropriate <Directory> sections (one for each app), eg
<Directory "/home/sudol/apps/app1/public">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
RewriteEngine On
RewriteBase /app1
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Directory>
Delete the .htaccess files as you will no longer need them
Addendum
Make sure you set unique session names in your application config. You can also set specific cookie paths but this is optional, eg
; app1/application/configs/application.ini
resources.session.name = "app1"
resources.session.cookie_path = "/app1/"
; app2/application/configs/application.ini
resources.session.name = "app2"
resources.session.cookie_path = "/app2/"
Its better to use subdomain i.e app1.localhost then localhost/app1 . Since the way cookies are stored (including session cookie) can give you problem latter . They will mismatch or can even overlap .
Here is a good tutorial to setup the preferred way
http://www.dennisplucinik.com/blog/2007/08/16/setting-up-multiple-virtual-hosts-in-wamp/

I'm confused with Apache vhost

I am building a web application with Zend Framework, and I need to point my app to the "public" folder of the application:
So basically when I call http://localhost/myapp
it should display http://localhost/myapp/public/
I created a virtual host file called myapp into /etc/apache2/sites-available/:
<VirtualHost *:80>
DocumentRoot /var/www/myapp/public/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/myapp/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
</VirtualHost>
But it doesn't work. When I call http://localhost/myapp, it displays the directory structure of the app, and when I click on the "public" folder, then it displays what I want to be displayed by default...
I never configured vhosts before and that's as far as I got with the tutorials about it.
In your first listing, you had a different value for the Directory tag, leaving off 'public' altogether. There was also a trailing slash after 'public' in the DocRoot value, but removed on your second attempt. Not sure that made a difference, but I believe it's recommended that you don't include trailing slashes.
Also, just wondering...are you running this on a local machine? I had trouble with Skype wanting to use port 80 if I started running that before my apache server. Skype will use a different port if 80 is already used. If not Skype, there may be another app that's using port 80 and interfering. That could be why you had success on another port.
Ok I found a way somehow... I don't think it's necessary the right/best way but...
in httpd.conf (in apache2 folder):
Listen 10089
<VirtualHost *:10089>
DocumentRoot "/var/www/myapp/public"
<Directory "/var/www/myapp/public">
Order allow,deny
Allow from all
AllowOverride all
</Directory>
</VirtualHost>
My app is now accessible via localhost:10089
After enabling the rewrite mod in apache, I added the necessary .htaccess, one at the root of my app, redirecting everything to index.php (Zend framework support friendly url navigation and works that way):
RewriteEngine on
RewriteRule .* index.php
and a second .htaccess file inside my public folder to allow people to access .jpg,.ico,etc files and not being redirected to index for everything:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
Hope this will help some!