minc Posted September 4, 2007 Share Posted September 4, 2007 Is there a way to call the Apache error documents from PHP? At the moment, I would like to be able to send back the content of one of the error files. I figure I should be able to do this, rather than have to regenerate an identical document in PHP. The /HTTP_NOT_FOUND.html.var file is an Apache SSI file I believe. So should I be able to get its output using the PHP virtual() function. For example, at the moment I have tried calling: $result = virtual( '/var/www/error/HTTP_NOT_FOUND.html.var' ); echo $result; For some reason it doesn't work, and I don't get any output back. Has anyone tried this and had success? I'm out of ideas for what to try. Many thanks, Max Running Apache 2.2.0 Fedora and PHP 5.1.2 Quote Link to comment Share on other sites More sharing options...
effigy Posted September 4, 2007 Share Posted September 4, 2007 Are you using ErrorDocument? Quote Link to comment Share on other sites More sharing options...
d22552000 Posted September 4, 2007 Share Posted September 4, 2007 just send the header error to the server instead. the server will interprest it ans send whatever ErrorDocument says to send: cexec('HTTP/1.1 404 FILE NOT FOUND"); or header("HTTP/1.1 410 GONE"); but dont take my answer on the http/1.1 part, i dont know if that is correct syntax. Quote Link to comment Share on other sites More sharing options...
minc Posted September 5, 2007 Author Share Posted September 5, 2007 Effigy, thanks for the suggestion. This is what I've tried so far. ErrorDocument In my main Apache config these are commented out, so the default hard coded error messages would be generated. I have uncommented them and verified that the error documents do work. So the main block of the config looks like this: Alias /error/ "/var/www/error/" <IfModule mod_negotiation.c> <IfModule mod_include.c> <Directory "/var/www/error"> AllowOverride None Options IncludesNoExec AddOutputFilter Includes html AddHandler type-map var Order allow,deny Allow from all LanguagePriority en es de fr ForceLanguagePriority Prefer Fallback </Directory> # ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var # ... etc, I've deleted the other ErrorDocument lines. </IfModule> </IfModule> I've also mapped the Error Documents to a PHP file in the web space: E.g. ErrorDocument 404 /http/HTTP_404_NOT_FOUND.html I can fetch this page directly from the browser at http://www.test.com//http/HTTP_404_NOT_FOUND.html. Also, because the file is built using php classes I can simulate the same response. I have an Authentication system, and if someone requests a page they aren't authorized to view then I can send back a response that is identical to the 404 not found response. Hence, from a security point of view, I'm not giving away any information about what resources exist on the server. The person requesting the page has no idea if the page doesn't exist, or if it does exist but they don't have the right privileges to access it. Rather than do this, which means I've got to duplicate the built in Apache responses, I want a way to be able to call the Apache responses directly. At the moment this is failing. I noticed that I may have not taken the Alias into account but testing both of these options made no difference: $result = virtual( '/error/HTTP_NOT_FOUND.html.var' ); $result = virtual( '/var/www/error/HTTP_NOT_FOUND.html.var' ); As far as I can tell after the line with the "virtual" call on PHP doesn't excute anything after it. The basis of my test code is below: public static function status404() { header("status: 404"); header("Content-type: text/html"); // This is used to generate the 404 response directly in PHP // // echo self::content404(); // // This doesn't work, but looks like it should... // $result = virtual( '/error/HTTP_NOT_FOUND.html.var' ); // $result = virtual( '/var/www/error/HTTP_NOT_FOUND.html.var' ); // I don't see ANY output back at the browser after the virtual call. if (!$result) { echo "<html><head><title>Error</title></head><body><h1>Apache virtual command failed.</h1></body></html>"; } else { echo "<html><head><title>Error</title></head><body><h1>Apache virtual command ok</h1></body></html>"; } // } /** Get the content for a 404 Not Found response. @return string */ public static function content404() { $url = self::requestURI(); $h = <<<HTTPDOC <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL <code>{$url}</code> was not found on this server.</p> <h5>HTTP Status: 404</h5> <hr> </body></html> HTTPDOC; return $h; } Quote Link to comment Share on other sites More sharing options...
minc Posted September 5, 2007 Author Share Posted September 5, 2007 just send the header error to the server instead. the server will interprest it ans send whatever ErrorDocument says to send: cexec('HTTP/1.1 404 FILE NOT FOUND"); or header("HTTP/1.1 410 GONE"); but dont take my answer on the http/1.1 part, i dont know if that is correct syntax. I don't understand what the cexec command does adn can't find any similar examples. Would I call it as; virtual( cexec('HTTP/1.1 404 FILE NOT FOUND") ); From PHP, calling the header() function will only set the header and not fetch the contents of the Apache error document. Is there another way to use this? Still trying to think this one through. Max Quote Link to comment Share on other sites More sharing options...
d22552000 Posted September 5, 2007 Share Posted September 5, 2007 cexec is like exec and pretty much is like teh console execution command.. you could do virtual... you could also do; header("Redirect 404 http://bla.com/html/FILE_NOT_FOUND_404.html"); This would tell the browser that it was a 404, and then redirect to the: "http://bla.com/html/FILE_NOT_FOUND_404.html" page: to tell the user that it was a 404. (replace html with html.var) Quote Link to comment Share on other sites More sharing options...
minc Posted September 6, 2007 Author Share Posted September 6, 2007 Using a redirect would "work", but isn't a very satisfactory method and would negate the security measure I'm trying to implement in the first place. On reading the virtual() function docs again it seems to imply that the function param must be a filename. I can't see how I can run cexec using virtual. (Tried, it didn't work.) The apache_get_version function works, so the Apache functions are there. On further testing of virtual() with simple test cases trying to include text files I can't even get it to work. E.g. 'test' is a simple text file // PHP log - these two fail virtual('/full/unix/path/www/web/root/relative/test'); virtual('http://test.com/web/root/relative/test'); // PHP log - no error message virtual('/web/root/relative/test'); virtual('./test'); None of the above work. When the virtual() function is executed the php script seems to just finish. No error messages even. include('./test'); works fine. At the moment, I can't even get a simple test case of virtual() to work. Unless I can work out why I guess I'll have to stick to using ErrorDocument and have local files in the the web space. Works, but not as neat. Max Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.