Jump to content

Calling Apache error documents from PHP


minc

Recommended Posts

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

 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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;	
}

 

 

Link to comment
Share on other sites

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

 

 

 

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.