mod_xsendfile won't work with CGI and mod_rewrite - php

I am trying to use the apache module xsendfile to get a better performance during file streaming.
The problem is, that it is just working if I DO NOT use PHP as CGI Version AND if I DO NOT USE rewrite rules for my urls.
Problem 1: mod_rewrite
Calling this one in the Browser will work:
http://subdomain.domain.de/image.php
This one will give me a 404:
http://subdomain.domain.de/rewrittenImageUrl
The rewrite rules are working right. The 404 error is triggered by the xsendfile module.
If I add a "R" to the rule in the htaccess (like suggested in this question) it will work again, because I am redirected to the first address given above. But redirecting is not what I want.
I also watched out this post about symlinks, but I think this could not be a solution for my post as long as I use absolute paths generated by using getenv('document_root')? This pathes shouldn't use any symbolic links, do they? Or am I missing something at this point?
Problem 2: CGI
If I switch the PHP mode to the cgi version I will get a 0 byte file. This seems to be the same behaviour like the server would react without any installation of xsendfile.
I have already updated the module to the latest version.
Also tested absolute and relative links without any success.
In addition to that Deactivating the output compression didn't work.
To complete the given information here is the PHP code I am using:
ini_set('zlib.output_compression', 'Off');
$realImagePath = getenv('document_root')."fixedRelativeImagePathNoParamsNeeded.jpg";
$imageInfos = #getimagesize($realImagePath);
header('Content-Type: '.$imageInfos['mime']);
header("X-Sendfile: $realImagePath");
exit();
Anyone has a clue?
Update (2014-01-06)
The second problem is solved:
I don't know why but it's working after turning on xsendfile in the apache config instead of using the htaccess file. (I will add an answer below as soons as the other problem is solved, too.)
In addition to the first one:
First I did not add any options in the httpd.conf as it should be working with the standard configuration. Anyway I now asked my provider to add the absolute project path to the whitelist of XSendFilePath as a global setting. This temporarily solved the 1. Problem with mod_rewrite. But this just seems to be not a real solution for my situation, because I am running many different projects on the server, each with a separated download path. So I would need to ask my provider to add a new path to the config each time I am starting a new project.
I still just can't use x-sendfile with mod_rewrotite although I should have access to the document root without any extra settings.

mod_xsendfile does construct absolute paths from relative paths based on the request URI, which might in fact be a sub-request in some cases. This does not always produce the results you expect.
Therefore, I would always use absolute URIs in the X-SENDFILE header.
The second consequence of the above is that the constructed path, not necessarily being what you expect, auto-whitelist a directory you do not expect, while then of course not whitelisting the directory you would have expected.
Therefore, always white-list URIs.
In short, Apache might not consider the same directory to be the current working directory of a request as you (or a backend *CGI). Rewriting only adds to the confusion.
I actually considered dropping the relative paths/auto-whitelist stuff altogether for this reasons, because it can be admittedly very confusing, and is also under-documented.
I guess it is a little late to drop it entirely, but I should at least mark it deprecated.

In your HT access file of main website try to use [L,R=301] in place of just [QSA,L] or [L].
For instance in place to use:
RewriteRule ^download/(.*)/$ download.php?x=$1 [QSA,L]
Use:
RewriteRule ^download/(.*)/$ download.php?x=$1 [L,R=301]
Tell me if resolved your problem guys !

Related

Trying to set up homepage with .htaccess

So I recently purchased a domain. I know how to make websites, so I uploaded a website that I made onto that domain. The only problem is is that it sends me to my index and then I have to click on some folders to actually get to see my website on my screen. I know what .htaccess is and does, but I'm not sure how to use it.
What I want is that when I go to www.mydomain.com it should open up my home.php file from the website that I made. This is my file order:
project/PHP/home.php
I'm not sure if I've given enough information, but I hope someone can help me out here.
As correctly written by #JimL in the comments above we would recommend that you simply replace home.php to index.php, since that is the default setting really all http servers are configured to use for the index document.
You can however change that, even if you can only use .htaccess style files:
DirectoryIndex home.php
That said I still would recommend to rename the index file instead. .htaccess style files should be avoided whenever possible. They are notoriously error prone, hard to debug and they really slow the http server down, often without reason. They are only offered for cases where you really need to do some configuration tweaks but do not have control over the http servers host configuration. That is for example often the case when using a cheap web space provider.
Considering the additional information you gave in the comment below you could also try to rewrite all requests to point to the php scripts inside that folder project/php. For that you can place such rewriting rules inside a .htaccess style file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/project/php
RewriteRule ^(.*)$ project/php/$1 [L,QSA]
If you also have to handle requests that require different rewriting then obviously you need additional rules.
But as already said in the comments below this is painful, slows the server down and makes things harder to debug.
Put your files in the public_html folder, or /var/www, you don't need the .htacces to do this.

Use slash with get request

I'm in the process of working on an error system for my site (i.e., if MySQL encounters an error, it sends them to an error page). I'm wondering, is it possible to use a "/" instead of "?err=" for a URL?
What I'd like to do is have people sent to the url "/error/404/" but display on page the content at url "/error?err=404". Is there a way to do this with HTAccess, or something of the sort?
My current way is with lots of files and iframes, and it gets really annoying when you have to update one tiny little thing.
Thanks!
What you are looking for is url rewriting. You can set it up using an .htaccess file, given that your installation of apache has mod_rewrite enabled (if not, check this question).
Here is a nice tutorial on how to do it.
Have a try with this:
RewriteEngine on
RewriteRule ^error/(\d+)$ error?err=$1 [L,QSA]
This should not end in a redirection loop, since this requires a trailing number in the URI.
Note that I removed your leading slashes from both the pattern and the result. .htaccess style files work on relative paths.
In general you should always prefer to place such rules inside your http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and the really slow the server down. They are only available as a last option for users who do not have access to the host configuration, for example when using a cheap hosting provider.

Why needed own php files security, when already given .htaccesss security?

In kohana framework, in .htaccess file is writen
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
Ok, But why needed this security in each php file :
<?php defined('SYSPATH') or die('No direct access allowed.');
?
attacker alredy can not open any .php file directly right? (becuase reason is protecte from .htaccess RewriteRule)
Simpy: It's a fallback. Thats all, but I need more characters, to publish this answer
It seems like the developers wanted to make sure no files can be accessed, no matter if the .htaccess works or not (i.e. disabled mod_rewrite).
But for files that only contain class definitions or return/define configuration arrays it is pretty useless anyway, since they don't output anything.
You can't be sure - from a framework developer point of view - that the webserver, that your product will be run with, is correctly set up (e.g. .htaccess/RewriteEngine not enabled by AllowOverride or no mod_rewrite ...).
this kind of « second check » is there to ensure that the framework won't leak sensitive data even on badly set up hosting.
.htaccess works only on Apache with mod_rewrite enabled. If the server does not meet any of these condition those SYSPATH checks comes in handly.
Note: not every user can use Aapche as web-server. And Not every user has access to .htaccess.
There are other alternatives nowadays. Like, nginx.

Enable mod_rewrite On Shared Hosting Apache Server

I have made some changes to a clients website.
The client was continually being attacked using SQL injection, and at the moment the URL contains variables that the website needs (i.e. index.php?filenmae=home.php).
So after securing the site as best I could using mysql_real_escape_strings and stripslashes, I then came to do URL rewriting in Apache.
At the moment, the server the website is currently on doesn't support mod_rewrite (i've checked using phpinfo) and it's not a server belonging to us. Is there anything I can do in my .htaccess file that would enable mod_rewrite for this website?
If mod_rewrite is installed, you can configure it in your local .htaccess file.
Create a file called .htaccess in your site's root folder.
First line should be RewriteEngine On.
Second line should be RewriteBase /.
After that, put in your rewrite rules are required.
If it isn't installed, you're out of luck - no web host will install extra software on a shared hosting box just for one client.
Mick, the best solution for you is to change your code. I'm guessing that in your code you then include the filename specified, e.g.
include $_GET['filename'];
In short, there is no way using mod_rewrite that you can make this secure.
However, you can make it more secure very easily by checking that the filename is valid, e.g.
$valid_filenames = array('home.php', 'foo.php', 'bar.php', /* etc... */);
if (!in_array($_GET['filename'], $valid_filenames)) {
echo "Invalid request.";
exit;
}
include $_GET['filename'];
Just make sure that you validate the requested filename before including it and you'll be much better off.
No, you cannot dynamically load mod_rewrite. Most hosting providers have mod_rewrite enabled on Apache servers. If they do not, you could ask them for enabling it. Otherwise, if you really need mod_rewrite, consider switching hosting providers.
As an alternative, you can rewrite URL's in PHP.
$_SERVER['QUERY_STRING'] can be used for getting the part after the question mark (http://example.com/file.php?this_part).
Split it by your preferred parameter separator (e.g. /, ;) using explode('/', $_SERVER['QUERY_STRING'])
Loop through the values, and split those using a preferred value separator (e.g. '=', ':')
Overwrite $_GET with an empty array, and put the newly generated values in it.
Note: filter_input and related functions do not operate on $_GET. Thus, this method will not work for filter_input.
For Shared Hosting Server , It Really Work.
Create a file called .htaccess in your site's root folder.
First line should be RewriteEngine On.
Second line should be RewriteBase /.
After that, put in your rewrite rules are required.

How can a URL like http://localhost/index.php/articles/edit/1/my-first-article work without an .htaccess?

I don't get this:
http://localhost/index.php/articles/edit/1/my-first-article
This URL is mentioned as an example in the Kohana framework documentation. I poked around in the files of my installation, and there is no .htaccess besides my own one that has nothing to do with that.
So, how can it be that an index.php is called but then, as parameters, the stuff looks like added directories to the URL? That doesn't look "real".
Or is this just how native PHP/Apache/HTTP stuff actually works? As I understand it, / is always telling "hey, a directory!". Makes really zero sense to me... how's that possible? Or do they have somewhere an .htaccess that I just can't see / find?
From the Apache docs:
AcceptPathInfo Directive
This directive controls whether
requests that contain trailing
pathname information that follows an
actual filename (or non-existent file
in an existing directory) will be
accepted or rejected. The trailing
pathname information can be made
available to scripts in the PATH_INFO
environment variable.
For example, assume the location
/test/ points to a directory that
contains only the single file
here.html. Then requests for
/test/here.html/more and
/test/nothere.html/more both collect
/more as PATH_INFO.
So I assume this setting is enabled somewhere like in httpd.conf. Note that this, like mod_rewrite, can be enabled/configured in a number of places - see here.
In PHP you can get the data after the filename with the $_SERVER["PATH_INFO"] variable. This allows you to basically GET information without having to use GET variables, which means Google and co will think you're using static pages. This is basically an alternative to mod_rewrite which is often enabled while mod_rewrite is more often not enabled.
This may be obvious to you, but it wasn't immediately to me, this doesn't work correctly on index pages unless you use the filename. For instance, http://example.com/test/my/get/params will not work, while http://example.com/test/index.php/my/get/params will.
AcceptPathInfo is turned on for your server. :)
I'm not using Kohana, so I don't know if my method will be of any use, but when a server doesn't support .htaccess files (or rewrite rules) my 'framework' generates URI's like this:
http://www.domain.com/?/articles/edit/1/my-first-article (notice the ?)
It's a similar method used by the Frog framework, just parse $_SERVER['REQUEST_URI'] (or $_SERVER['HTTP-X-REWRITE-URL'] on windows servers) and explode on the '/'.
This method is completely rewrite independent and still generates more-or-less SEO friendly URI's
Hope it's of any use to you.
Probably not the case here, and certainly not recommended, and probably not the right answer...
BUT ...
I've seen people use 404 pages to parse the request and then include the right page with that information.
See PATH_INFO in CGI Environment Variables.

Categories