Apache ErrorDocument / PHP header() interaction does not work as expected

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • liyanage@gmail.com

    #1

    Apache ErrorDocument / PHP header() interaction does not work as expected


    I recently worked on error handling and three related issues/questions
    came up.


    1.) I am trying to trigger Apache ErrorDocument handlers by setting
    appropriate HTTP status codes in my PHP code, but I don't get the
    expected results.

    My PHP file:

    ----------------
    <?php
    header("HTTP/1.0 500 Internal Server Error");
    ----------------


    In my Apache configuration I have this:

    ----------------
    ErrorDocument 500 "test error 500 handler
    ----------------

    The status code is sent to the browser, but the ErrorDocument handler
    is never triggered, it looks like Apache passes the value on to the
    client, but does not interpret it.

    The last posting on this page suggests something to this effect:




    This surprises me, is that really how it works? In my Perl
    applications running under mod_perl, returning status 500 does *both*,
    send that status to the browser and make Apache interpret and act upon
    the value. What is mod_perl doing differently?

    I can actually have two separate status values, one that gets sent to
    the browser (Apache2::Reque stRec::status() ), and one that is returned
    to the Apache server (the handler() method's return value). Does
    something similar exist in PHP? Or do I really have to replicate the
    ErrorDocument functionality in my PHP code?


    2.) In my tests with mod_perl just now I also realized that mod_perl
    will properly signal an error 500 condition to Apache if a Perl error
    such as a syntax error or an unhandled exception occurs. A configured
    ErrorDocument 500 handler will be triggered, as I would expect it to
    be.

    It seems that PHP does not signal an error 500 to Apache when PHP code
    fails. Wouldn't this be a useful addition for exactly this reason
    (ability to use Apache ErrorDocument).


    3.) While playing around with set_error_handl er(), I also saw that
    syntax errors are not trappable with a custom error handler. I use an
    autoloader that loads classes on demand, and if one of the class files
    loaded at run-time has a syntax error, my error handler is bypassed.
    Combined with the inability to trigger ErrorDocuments described above,
    doesn't this mean that it is absolutely impossible to hide such errors
    from users by replacing them with a "friendly" error page when using
    PHP?

    That would mean that I am not even able to emulate the ErrorDocument
    feature in PHP code.

  • shimmyshack

    #2
    Re: Apache ErrorDocument / PHP header() interaction does not work as expected

    On May 10, 10:19 am, "liyan...@gmail .com" <liyan...@gmail .comwrote:
    I recently worked on error handling and three related issues/questions
    came up.
    >
    1.) I am trying to trigger Apache ErrorDocument handlers by setting
    appropriate HTTP status codes in my PHP code, but I don't get the
    expected results.
    >
    My PHP file:
    >
    ----------------
    <?php
    header("HTTP/1.0 500 Internal Server Error");
    ----------------
    >
    In my Apache configuration I have this:
    >
    ----------------
    ErrorDocument 500 "test error 500 handler
    ----------------
    >
    The status code is sent to the browser, but the ErrorDocument handler
    is never triggered, it looks like Apache passes the value on to the
    client, but does not interpret it.
    >
    The last posting on this page suggests something to this effect:
    >

    >
    This surprises me, is that really how it works? In my Perl
    applications running under mod_perl, returning status 500 does *both*,
    send that status to the browser and make Apache interpret and act upon
    the value. What is mod_perl doing differently?
    >
    I can actually have two separate status values, one that gets sent to
    the browser (Apache2::Reque stRec::status() ), and one that is returned
    to the Apache server (the handler() method's return value). Does
    something similar exist in PHP? Or do I really have to replicate the
    ErrorDocument functionality in my PHP code?
    >
    2.) In my tests with mod_perl just now I also realized that mod_perl
    will properly signal an error 500 condition to Apache if a Perl error
    such as a syntax error or an unhandled exception occurs. A configured
    ErrorDocument 500 handler will be triggered, as I would expect it to
    be.
    >
    It seems that PHP does not signal an error 500 to Apache when PHP code
    fails. Wouldn't this be a useful addition for exactly this reason
    (ability to use Apache ErrorDocument).
    >
    3.) While playing around with set_error_handl er(), I also saw that
    syntax errors are not trappable with a custom error handler. I use an
    autoloader that loads classes on demand, and if one of the class files
    loaded at run-time has a syntax error, my error handler is bypassed.
    Combined with the inability to trigger ErrorDocuments described above,
    doesn't this mean that it is absolutely impossible to hide such errors
    from users by replacing them with a "friendly" error page when using
    PHP?
    >
    That would mean that I am not even able to emulate the ErrorDocument
    feature in PHP code.
    well you /can/ do
    sendErrorDocume ntAndQuit($code )
    {
    $arrStatusCodes = array(
    404=>'Page Not Found',
    500=>'Custom Internal Server Error'
    );
    if( !in_array($code ,array_keys($ar rStatusCodes)) )
    {
    $code = 403;
    }
    header( 'HTTP/1.1 ' . $code . ' "' . $arrStatusCodes[$code] . '"' );
    include( '/path/to/aliased/errordocs/'.$code.'.html' );
    exit();
    }


    sendErrorDocume ntAndQuit(404);

    there's no 302, little overhead but of course emulating some of these
    errors should only be done with care, 500 for instance. You are
    "lying" about Apache's _real_ state, which is 200/304 if Apache is
    really OK.

    You're right though, there isn't the tight integration with Apache API
    that Perl has.

    Using mod_security - which of course is an apache module, you can trap
    any response body string - such as errors, or <?php etc... that you
    consider should never be sent to the user, so it should be possible to
    spark off an action which might result in a standard error page.

    Comment

    • liyanage@gmail.com

      #3
      Re: Apache ErrorDocument / PHP header() interaction does not work as expected

      On May 10, 12:00 pm, shimmyshack <matt.fa...@gma il.comwrote:
      well you /can/ do
      sendErrorDocume ntAndQuit($code )
      That is basically what I meant with emulating the Apache behavior in
      PHP. I would like to avoid that, mostly because, as I mentioned, some
      errors cannot be intercepted at the PHP code level.

      Using mod_security - which of course is an apache module...
      Thanks for this hint, this looks pretty interesting.

      Comment

      • gosha bine

        #4
        Re: Apache ErrorDocument / PHP header() interaction does not workas expected

        On 10.05.2007 11:19 liyanage@gmail. com wrote:
        >
        I can actually have two separate status values, one that gets sent to
        the browser (Apache2::Reque stRec::status() ), and one that is returned
        to the Apache server (the handler() method's return value). Does
        something similar exist in PHP? Or do I really have to replicate the
        ErrorDocument functionality in my PHP code?
        php module handler always returns OK (=200) to apache, no matter what
        the script did. See for yourself:



        I'm afraid, there's no way to change this behaviour in php code.
        >
        3.) While playing around with set_error_handl er(), I also saw that
        syntax errors are not trappable with a custom error handler. I use an
        autoloader that loads classes on demand, and if one of the class files
        loaded at run-time has a syntax error, my error handler is bypassed.
        Combined with the inability to trigger ErrorDocuments described above,
        doesn't this mean that it is absolutely impossible to hide such errors
        from users by replacing them with a "friendly" error page when using
        PHP?
        Cleanup callbacks (output buffering, destructors, shutdown functions)
        are still executed in case of fatals, you can use them to produce nicer
        post mortem error message, e.g.

        function check_fatals($b uf) {
        if(strpos($buf, 'Fatal'))
        return 'pardon!';
        return $buf;
        }

        ob_start('check _fatals');
        include 'whatever.php';


        --
        gosha bine

        extended php parser ~ http://code.google.com/p/pihipi
        blok ~ http://www.tagarga.com/blok

        Comment

        • liyanage@gmail.com

          #5
          Re: Apache ErrorDocument / PHP header() interaction does not work as expected

          On May 10, 5:35 pm, gosha bine <stereof...@gma il.comwrote:
          php module handler always returns OK (=200) to apache, no matter what
          the script did. See for yourself:
          Thanks a lot, that is the sort of confirmation I wanted to hear.
          That's really unfortunate, it would be useful if PHP would send 500 to
          Apache in case of a PHP script error.
          Cleanup callbacks (output buffering, destructors, shutdown functions)
          are still executed in case of fatals
          Interesting idea, I'll take a look at that.

          Thanks again...



          Comment

          Working...