How to do URL rewriting in Apache through Chef? - apache

I've made a cookbook in Chef to install a web application, Apache and PHP.
This web application has a PHP document that clients access in this URL:
http://localhost/www-app/ClientFE
With this I have a problem. By default PHP will only interpret documents that have a PHP extension, and as my URL doesn't have it, it gets interpreted as text. I can't change the file's extension because the client (which is also software) should not be modified.
What I want to accomplish is to make PHP interpret that document, and for what I've investigated it can be accomplished in three ways at least: configure appropriately PHP, create an alias, create a rewrite rule.
First: I could configure PHP to interpret the desired document:
<FilesMatch "/www-app/ClientFE">
SetHandler application/x-httpd-php
</FilesMatch>
Second: I could do it through mod_write (I would have to rename the fill in the web app, which is also acceptable for me):
RewriteCond ^/www-app/ClientFE /www-app/ClientFE.php
Third: I could do it with mod_alias in a similar fashion than mod_rewrite.
The 3 are good for me, but my problem is: how to do them with Chef ? I haven't been able to find useful docs about it, and I have already tried to put this in my recipe (I found them around the Internet but they haven't worked):
apache_rewrite do
source "/www-app/ClientFE"
target "/www-app/ClientFE.php"
end
and this
apache_module "alias" do
source "/www-app/ClientFE"
target "/www-app/ClientFE.php"
end

Some people in my company suggested 2 valid solutions:
Put the configuration in a .htaccess inside my web application. This works for me and allows to use the alternatives I mentioned above.
Do nothing! It happens that the Multiviews option in the Apache2 cookbook is enabled by default, and it allows Apache to resolve URL http://localhost/A as http://localhost/A.php .... I mean, if Apache is asked about file A, and it doesn't find it, then it will search for A.php instead.
From the two, I chose the later, and yes, it works. It wasn't working before because in my many attempts I created both A and A.php and in that case the Multiviews has no effect.

Related

apache .htacces configuration

I'm following the symfony create your own mvc tutorial and I'm at a loss as to how to configure my apache server to point to the web directory.
Following the tutorial. My file structure has pages in the src folder, composer in the vendor folder and my front.php in the web folder with the associated routes. If I go to web/front.php all works fine.
How do I configure the .htaccess file?
Generally it is recommended not to use dynamic configuration files (".htaccess"), but to place rewriting rules inside the host configuration itself (performance and maintainability reasons). You will find tons of examples for such internal rewritings here on SO, your best starting point to read into that however certainly is the official documentation. It comes with great examples: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
This is a simple example that should point you into the right direction:
RewriteEngine on
RewriteRule ^/?projectname/(.*)/?$ /web/front.php?variable=$1 [L]
That will take care to internally rewrite the request so that you can access the variable value as $_GET['variable'].
The example uses a pattern that will work likewise in dynamic configuration files (".htaccess") and in the real http servers host configuration. If you really want to use dynamic files, then you also need to enable their interpretation by means of the AllowOverride directive. Again take a look at the official documentation for that: https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

How can i know if my apache server is using .htaccess or not?

I want to know if my Apache server uses .htaccess files or not. If it uses them, then why and how?
How can I know if my Apache server is using .htaccess or not?
Thank you.
As for why, it's a convenient way for shared-hosting providers to give some access to users who would like to set some configuration options. You obviously wouldn't want everyone to have access to the main configuration file for security purposes. It's also useful for development purposes since you can set different options for different directories.
As for how Apache uses the file, I recommend reading the documentation.
As for how to know if Apache is using .htaccess files, it most likely is. I've yet to meet a shared hosting provider that doesn't. And if you are running your own server, I assume you would know how you set it up. Worst case scenario, you could follow this advice from the docs:
A good test for this is to put garbage in your .htaccess file and reload the page. If a server error is not generated, then you almost certainly have AllowOverride None in effect.

Prevent Non-Existent Directories From Loading Wildcard Files

I am looking to prevent URLs for directories that don't exist from loading files with the same basename. For example http://domain.com/test/ is loading test.php. The test directory does not exist, but the file test.php does. I can see how this would be useful in most cases, but I am looking to disable it for my project.
I am on an Apache server. Is there a way to disable this option through an .htaccess file?
If there is an actual name for this type of feature, maybe "wildcard filename helper" or something like that, I'd like to know the official term too. Thanks!
This happens because MultiViews is enabled on the server.
If the apache configuration allows you to do so, you should be able to disable it by putting the following in .htaccess:
Options -MultiViews

Aliases on Dreamhost, general management of http request / server errors

I had a hard time deciding how I should manage these errors (404, 500, ...) and when I finally decided, I am encountering problems. This is a reeeeeally long question, I appreciate anyone's attempt to help!
Let me first describe how I decided to set it up. I have several sites hosted on a shared Dreamhost account. In the folder structure that I see, everything of mine on the server is under /home/username, and for example, site1.com's web root is at /home/username/site1.com
I am creating a generic error handler (php script) for errors like 404 not found, 500, etc. that I want to store above the web roots of my sites at /home/username/error_handler/index.php so that I can use an .htaccess file at /home/username/.htaccess which includes something like the following:
ErrorDocument 404 /error_handler/index.php
ErrorDocument 500 /error_handler/index.php
...and many more
When these errors occur on any of my sites, I want it to be directed to /home/username/error_handler/index.phpThis is the problem I'm having a hard time figuring out. The ErrorDocument directives above will actually cause Apache to look for /home/username/site1.com/error_handler/index.php
Anyway, the errors should be redirected to my error handling php script. The script will use $_SERVER['REDIRECT_STATUS'] to get the error code, then use $_SERVER['REDIRECT_URL'] and $_SERVER['HTTP_HOST'] to decide what to do. It will check if an error handler specific to that site exists (for example: site1.com/errors/404.php). If this custom page doesn't exist, it will output a generic message that is slightly more user-friendly and styled, and perhaps will include some contact info for me depending on the error.
Doing it this way lets me funnel all these errors through this 1 php script. I can log the errors however I like or send email notifications if I want. It also lets me set up the ErrorDocument Apache directives once for all my sites instead of having to do it for every site. It will also continue to work without modification when I move the site around, since I already have a system that scans the folder structure to figure out where my site roots are when they really aren't at the web root technically speaking. This may not be possible with other solutions like using mod_rewrite for all 404 problems, which I know is common. Or if it is possible, it may be very difficult to do. Plus, I have already done that work, so it will be easy for me to adapt.
When I am working on sites for which I don't have a domain name yet (or sites where the domain name is already in use at the moment), I store them temporarily in site1.com/dev/site3.com for example. Moving the site to site3.com eventually would cause me to have to update the htaccess files if I had one for each site. Changing the domain name would do the same.
Ex: a site stored at site1.com/dev/site3.com would have this in its htaccess file:
ErrorDocument 404 /site1.com/dev/site3.com/error/404.php
And it would have to be changed to this:
ErrorDocument 404 /site3.com/error/404.php
Obviously, this isn't a huge amount of work, but I already manage a lot of sites and I will probably be making more every year, 95% of which will be hosted on my shared DreamHost account. And most of them get moved at least once. So setting up something automatic will save me a some effort in the long run.
I already have a system set up for managing site-relative links on all my sites. These links will work whether the site exists in a subdirectory of an existing site, or in their own domain. They also work without change in a local development server despite a difference in the web root location. For example, on the live server, the site-relative http link /img/1.jpg would resolve to the file /home/username/site1.com/img/1.jpg while on my local development server it would resolve to C:\xampp\htdocs\img\1.jpg, despite what I consider the logical site root being at C:\xampp\htdocs\site1.com. I love this system, and it is what gave me the idea to set up something that would work automatically like I expected it to, based on the file structure I used.
So, if I could get it to work, I think this seems like a pretty good system. But I am still very new to apache configuration, mod_rewrite, etc. It's possible there is a much easier and better way to do this. If you know of one, please let me know.
Anyway, all that aside, I can't get it working. The easiest thing would be if I could have the ErrorDocument directive send the requests to folders above the web root. But the path is a URL path relative to the document root. Using the following in /home/username/.htaccess,
ErrorDocument 404 /error_handler/index.php
a request for a non-existent resource causes Apache to look for the file at
site1.com/error_handler/index.php
So I thought I should set up a redirection (on all my sites) that would redirect those URLS to /home/username/error_handler. I tried a few things and couldn't get any of them to work.
Alias seemed like the simplest solution, but it is something that has to be set at server runtime (not sure if that is the right terminology - when the server is started). On my local server, it worked fine using:
Alias /error_handler C:\xampp\htdocs\error_handler2
I changed the local folder to test that the Alias was functioning properly. (On the local server, the URL path specified by the ErrorDocument directive is actually pointing to the right folder, since in my local server the web root is technically C:\xampp\htdocs and I store the error handler I want to use is stored locally at C:\xampp\htdocs\error_handler\index.php)
Dreamhost has a web client that can create what I am guessing is an Alias. When I tried to redirect the folder error_handler on site1.com to /home/username/error_handler, it would seem to work right if I typed site1.com/error_handler in the browser. But if I typed site1.com/test1234 (non-existant), it would say there was a 404 error trying to use the error handler. Also, I would have to login through the web client and point and click (and wait several minutes for the server to restart) every time I wanted to set this up for a new site, even if I could get it to work.
So I tried getting it to work with mod_rewrite, which seems like the most flexible solution. My first attempt looked something like this (stored in /home/username/site1.com/.htaccess for now, though it would eventually be at /home/username/.htaccess:
RewriteEngine On
RewriteRule ^error_handler/index.php$ /home/username/error_handler/index.php
The plain english version of what I was trying to do above is to send requests on any of my sites for error_handler/index.php to /home/username/error_handler/index.php. The mis-understanding I had is that the subsitution will be treated as a file path if it exists. But I missed that the documentation says "(or, in the case of using rewrites in a .htaccess file, relative to your document root)". So instead of rewriting to /home/username/error_handler/index.php, it's actually trying to rewrite to /home/username/site1.com/home/username/error_handler/index.php.
I tried including Options +FollowSymLinks because in the Apache documentation it says this:
To enable the rewrite engine in this context [per-directory re-writes in htaccess], you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewrite engine. This restriction is required for security reasons.
I searched around for a while and I couldn't find anything about how Dreamhost handles this (probably because I don't know where to look).
I experimented with RewriteBase because in the Apache documentation it says this:
"This directive is required when you use a relative path in a substitution in per-directory (htaccess) context unless either of the following conditions are true:
The original request, and the substitution, are underneath the DocumentRoot (as opposed to reachable by other means, such as Alias)."
Since this is supposed to be a URL path, in my case it should be RewriteBase /, since all my redirects will be from site1.com/error_handler. I also tried Rewrite Base /home/username and RewriteRule ^error_handler/index.php$ error_handler/index.php. However, the Rewrite Base is a URL path relative to the document root. So I need to use something like an alias still. The implication in the quote from the documentation above is that it is possible to use mod_rewrite to send content above the web root. One of the many things I don't know is what the 'other means' besides Alias might be. I believe Alias might not be an option on Dreamhost. At least I couldn't make sense of it.
Why not use error pages in the site root, then include the actual file from the shared section?

Popular techniques to debug .htaccess

I'm a self-taught coder and I like to debug by echoing suspicious variables and commenting out code.
Lately, I've had to learn more about the .htaccess file. I need it to do things like interpret php scripts as php5, url rewriting, limit file upload size etc.... I have a lot of trouble debugging a .htaccess file. I often have to migrate PHP applications from one shared hosting environment to another. Sometimes this breaks the .htaccess file (or instead, something in the .htaccess file breaks the site). I check to make sure domain names are updated.
Are there popular techniques for debugging a .htaccess file? Is it just look in the apache logs? Anything else?
Looking in the apache logs is the easiest way to debug .htaccess imho (adding rewriteLog Directive if necessary)
About migrating: if you are not using any physical file paths inside .htaccess (i.e. /var/www/site/script.php) they should be working without problems. If this is not the case, first try to remove all options and leave only redirect directives, in this mode you can see if it's problem with server configuration which denies rewriting of default settings.
Some reference