From b85f8e79fe7855642072cdb40c764a4a1ef1fc7e Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Wed, 22 Jun 2016 23:26:24 +0100 Subject: [PATCH] Fail better! There's a long-standing annoyance about catching errors in the early stages of startup - sometimes they seem to disappear nowhere and yet nothing works. This fixes at least part of that. --- htdocs/always.php | 21 ++++++++++ htdocs/caldav.php | 99 +++++++++++++++++++++++++++-------------------- inc/always.php.in | 21 ++++++++++ 3 files changed, 100 insertions(+), 41 deletions(-) diff --git a/htdocs/always.php b/htdocs/always.php index 9d9b9b9a..432a069d 100644 --- a/htdocs/always.php +++ b/htdocs/always.php @@ -42,6 +42,27 @@ function early_exception_handler($e) { } set_exception_handler('early_exception_handler'); +function early_catch_fatal_error() { + global $request; + + if ( !empty($request) ) return; + + // Getting Last Error + $e = error_get_last(); + + // Check if Last error is of type FATAL + if (isset($e['type']) && $e['type'] == E_ERROR) { + if ( !headers_sent() ) { + header("Content-type: text/plain"); + header( sprintf("HTTP/1.1 %d %s", 500, getStatusMessage(500)) ); + } + echo "PHP Fatal error: ".$e['message']."\n"; + echo "At line ", $e['line'], " of ", $e['file'], "\n"; + error_log("PHP Fatal Error: '".$e['message']. "' at line ". $e['line']. " of ". $e['file']); + } +} +register_shutdown_function('early_catch_fatal_error'); + $c->default_timezone = ini_get ( 'date.timezone' ); if (empty ( $c->default_timezone )) { if (isset ( $_SERVER ['HTTP_X_DAVICAL_TESTCASE'] )) { diff --git a/htdocs/caldav.php b/htdocs/caldav.php index 78f07310..ba7fc896 100644 --- a/htdocs/caldav.php +++ b/htdocs/caldav.php @@ -75,6 +75,17 @@ function send_dav_header() { require_once('CalDAVRequest.php'); $request = new CalDAVRequest(); +function late_catch_fatal_error() { + global $request; + + // Getting Last Error + $e = error_get_last(); + if (isset($e['type']) && $e['type'] == E_ERROR) { + $request->DoResponse(500, "Fatal PHP Error"); + } +} +register_shutdown_function('late_catch_fatal_error'); + //if ( $request->method == 'OPTIONS' || $c->always_send_dav_header ) send_dav_header(); // Avoid polluting global namespace @@ -94,50 +105,56 @@ if ( ! ($request->IsPrincipal() || isset($request->collection) || $request->meth param_to_global('add_member', '.*', 'add-member'); $add_member = isset($add_member); -switch ( $request->method ) { - case 'OPTIONS': include_once('caldav-OPTIONS.php'); break; - case 'REPORT': include_once('caldav-REPORT.php'); break; - case 'PROPFIND': include('caldav-PROPFIND.php'); break; - case 'GET': include('caldav-GET.php'); break; - case 'HEAD': include('caldav-GET.php'); break; - case 'PROPPATCH': include('caldav-PROPPATCH.php'); break; - case 'POST': - if ( $request->content_type != 'text/vcard' && !$add_member ) { - include('caldav-POST.php'); +try { + + switch ( $request->method ) { + case 'OPTIONS': include_once('caldav-OPTIONS.php'); break; + case 'REPORT': include_once('caldav-REPORT.php'); break; + case 'PROPFIND': include('caldav-PROPFIND.php'); break; + case 'GET': include('caldav-GET.php'); break; + case 'HEAD': include('caldav-GET.php'); break; + case 'PROPPATCH': include('caldav-PROPPATCH.php'); break; + case 'POST': + if ( $request->content_type != 'text/vcard' && !$add_member ) { + include('caldav-POST.php'); + break; + } + case 'PUT': + switch( $request->content_type ) { + case 'text/calendar': + include('caldav-PUT-vcalendar.php'); + break; + case 'text/vcard': + case 'text/x-vcard': + include('caldav-PUT-vcard.php'); + break; + default: + include('caldav-PUT-default.php'); + break; + } break; - } - case 'PUT': - switch( $request->content_type ) { - case 'text/calendar': - include('caldav-PUT-vcalendar.php'); - break; - case 'text/vcard': - case 'text/x-vcard': - include('caldav-PUT-vcard.php'); - break; - default: - include('caldav-PUT-default.php'); - break; - } - break; - case 'MKCALENDAR': include('caldav-MKCOL.php'); break; - case 'MKCOL': include('caldav-MKCOL.php'); break; - case 'DELETE': include('caldav-DELETE.php'); break; - case 'MOVE': include('caldav-MOVE.php'); break; - case 'ACL': include('caldav-ACL.php'); break; - case 'LOCK': include('caldav-LOCK.php'); break; - case 'UNLOCK': include('caldav-LOCK.php'); break; - case 'MKTICKET': include('caldav-MKTICKET.php'); break; - case 'DELTICKET': include('caldav-DELTICKET.php'); break; - case 'BIND': include('caldav-BIND.php'); break; + case 'MKCALENDAR': include('caldav-MKCOL.php'); break; + case 'MKCOL': include('caldav-MKCOL.php'); break; + case 'DELETE': include('caldav-DELETE.php'); break; + case 'MOVE': include('caldav-MOVE.php'); break; + case 'ACL': include('caldav-ACL.php'); break; + case 'LOCK': include('caldav-LOCK.php'); break; + case 'UNLOCK': include('caldav-LOCK.php'); break; + case 'MKTICKET': include('caldav-MKTICKET.php'); break; + case 'DELTICKET': include('caldav-DELTICKET.php'); break; + case 'BIND': include('caldav-BIND.php'); break; - case 'TESTRRULE': include('test-RRULE-v2.php'); break; + case 'TESTRRULE': include('test-RRULE-v2.php'); break; - default: - dbg_error_log( 'caldav', 'Unhandled request method >>%s<<', $request->method ); - dbg_log_array( 'caldav', '_SERVER', $_SERVER, true ); - dbg_error_log( 'caldav', 'RAW: %s', str_replace("\n", '',str_replace("\r", '', $request->raw_post)) ); + default: + dbg_error_log( 'caldav', 'Unhandled request method >>%s<<', $request->method ); + dbg_log_array( 'caldav', '_SERVER', $_SERVER, true ); + dbg_error_log( 'caldav', 'RAW: %s', str_replace("\n", '',str_replace("\r", '', $request->raw_post)) ); + } + +} catch (Exception $e) { + trace_bug('DAViCal Fatal Error'); + $request->DoResponse( 500, translate('DAViCal Fatal Error') ); } $request->DoResponse( 400, translate('The application program does not understand that request.') ); - diff --git a/inc/always.php.in b/inc/always.php.in index 57068532..5ad55980 100644 --- a/inc/always.php.in +++ b/inc/always.php.in @@ -42,6 +42,27 @@ function early_exception_handler($e) { } set_exception_handler('early_exception_handler'); +function early_catch_fatal_error() { + global $request; + + if ( !empty($request) ) return; + + // Getting Last Error + $e = error_get_last(); + + // Check if Last error is of type FATAL + if (isset($e['type']) && $e['type'] == E_ERROR) { + if ( !headers_sent() ) { + header("Content-type: text/plain"); + header( sprintf("HTTP/1.1 %d %s", 500, getStatusMessage(500)) ); + } + echo "PHP Fatal error: ".$e['message']."\n"; + echo "At line ", $e['line'], " of ", $e['file'], "\n"; + error_log("PHP Fatal Error: '".$e['message']. "' at line ". $e['line']. " of ". $e['file']); + } +} +register_shutdown_function('early_catch_fatal_error'); + $c->default_timezone = ini_get ( 'date.timezone' ); if (empty ( $c->default_timezone )) { if (isset ( $_SERVER ['HTTP_X_DAVICAL_TESTCASE'] )) {