From 2bc821f4282e65f546e26c00c65d29a84be1787d Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Tue, 21 Feb 2012 20:04:45 +0000 Subject: [PATCH] use groupdav->log() for all permanent error-messages, to log the into request-log too, if both If-Match and If-Schdule-Tag-Match given use If-Match for organiser/owner and If-Schedule-Tag-Match for attendees/participants --- .../inc/class.addressbook_groupdav.inc.php | 9 ++-- calendar/inc/class.calendar_groupdav.inc.php | 23 +++++++-- infolog/inc/class.infolog_groupdav.inc.php | 5 +- phpgwapi/inc/class.groupdav.inc.php | 50 +++++++++++-------- phpgwapi/inc/class.groupdav_handler.inc.php | 3 ++ .../inc/class.groupdav_principals.inc.php | 11 ++-- 6 files changed, 70 insertions(+), 31 deletions(-) diff --git a/addressbook/inc/class.addressbook_groupdav.inc.php b/addressbook/inc/class.addressbook_groupdav.inc.php index 7a14256278..8e7f1e4b2d 100644 --- a/addressbook/inc/class.addressbook_groupdav.inc.php +++ b/addressbook/inc/class.addressbook_groupdav.inc.php @@ -17,6 +17,9 @@ * Propfind now uses a groupdav_propfind_iterator with a callback to query huge addressbooks in chunk, * without getting into problems with memory_limit. * + * Permanent error_log() calls should use $this->groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). + * * @todo check/fix contacts in LDAP (no carddav_name column!) */ class addressbook_groupdav extends groupdav_handler @@ -281,7 +284,7 @@ class addressbook_groupdav extends groupdav_handler switch((string)$filter['name']) { case 'param-filter': - error_log(__METHOD__."(...) param-filter='{$filter['attrs']['name']}' not (yet) implemented!"); + $this->groupdav->log(__METHOD__."(...) param-filter='{$filter['attrs']['name']}' not (yet) implemented!"); break; case 'prop-filter': // can be multiple prop-filter, see example if ($matches) $prop_filters[] = implode($prop_test=='allof'?' AND ':' OR ',$matches); @@ -346,7 +349,7 @@ class addressbook_groupdav extends groupdav_handler } // fall through default: - error_log(__METHOD__."(".array2string($options).",,$id) unknown filter=".array2string($filter).' --> ignored'); + $this->groupdav->log(__METHOD__."(".array2string($options).",,$id) unknown filter=".array2string($filter).' --> ignored'); break; } } @@ -376,7 +379,7 @@ class addressbook_groupdav extends groupdav_handler case 'href': break; // from addressbook-multiget, handled below default: - error_log(__METHOD__."(...) unknown xml: options[other]=".array2string($options['other'])); + $this->groupdav->log(__METHOD__."(...) unknown xml: options[other]=".array2string($options['other'])); break; } } diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index 2089ab4a23..8c1887f973 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -14,7 +14,10 @@ require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; /** - * eGroupWare: GroupDAV access: calendar handler + * EGroupware: CalDAV / GroupDAV access: calendar handler + * + * Permanent error_log() calls should use $this->groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). */ class calendar_groupdav extends groupdav_handler { @@ -597,6 +600,20 @@ class calendar_groupdav extends groupdav_handler { $eventId = $oldEvent['id']; + //client specified a CalDAV Scheduling schedule-tag AND an etag If-Match precondition + if ($this->use_schedule_tag && isset($_SERVER['HTTP_IF_SCHEDULE_TAG_MATCH']) && + isset($_SERVER['HTTP_IF_MATCH'])) + { + if ($oldEvent['owner'] == $GLOBALS['egw_info']['user']['account_id']) + { + $this->groupdav->log("Both If-Match and If-Schedule-Tag-Match header given: If-Schedule-Tag-Match ignored for event owner!"); + unset($_SERVER['HTTP_IF_SCHEDULE_TAG_MATCH']); + } + else + { + $this->groupdav->log("Both If-Match and If-Schedule-Tag-Match header given: If-Schedule-Tag-Match takes precedence for participants!"); + } + } //client specified a CalDAV Scheduling schedule-tag precondition if ($this->use_schedule_tag && isset($_SERVER['HTTP_IF_SCHEDULE_TAG_MATCH'])) { @@ -638,7 +655,7 @@ class calendar_groupdav extends groupdav_handler } elseif (!isset($event['participants']) || $event['participants'][$user] === $oldEvent['participants'][$user]) { - error_log(__METHOD__."(,,$user) schedule-tag given, but NO change for current user event=".array2string($event).', old-event='.array2string($oldEvent)); + $this->groupdav->log(__METHOD__."(,,$user) schedule-tag given, but NO change for current user event=".array2string($event).', old-event='.array2string($oldEvent)); return '412 Precondition Failed'; } } @@ -858,7 +875,7 @@ class calendar_groupdav extends groupdav_handler } if ($event['owner'] != $user) { - error_log(__METHOD__."('$ical',,$user) ORGANIZER is NOT principal!"); + $this->groupdav->log(__METHOD__."('$ical',,$user) ORGANIZER is NOT principal!"); return '403 Forbidden'; } //print_r($event); diff --git a/infolog/inc/class.infolog_groupdav.inc.php b/infolog/inc/class.infolog_groupdav.inc.php index cfdfba2801..c8a1b0d6a6 100644 --- a/infolog/inc/class.infolog_groupdav.inc.php +++ b/infolog/inc/class.infolog_groupdav.inc.php @@ -15,6 +15,9 @@ require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; /** * EGroupware: GroupDAV access: infolog handler + * + * Permanent error_log() calls should use $this->groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). */ class infolog_groupdav extends groupdav_handler { @@ -367,7 +370,7 @@ class infolog_groupdav extends groupdav_handler } elseif (empty($attrs['start'])) { - error_log(__METHOD__.'('.array2string($attrs).') minimum one of start or end is required!'); + $this->groupdav->log(__METHOD__.'('.array2string($attrs).') minimum one of start or end is required!'); return '1'; // to not give sql error, but simply not filter out anything } // we dont need to care for DURATION line in rfc4791#section-9.9, as we always put that in DUE/info_enddate diff --git a/phpgwapi/inc/class.groupdav.inc.php b/phpgwapi/inc/class.groupdav.inc.php index 2811af37eb..c249e102ea 100644 --- a/phpgwapi/inc/class.groupdav.inc.php +++ b/phpgwapi/inc/class.groupdav.inc.php @@ -39,6 +39,9 @@ require_once('HTTP/WebDAV/Server.php'); * Calling one of the above collections with a GET request / regular browser generates an automatic index * from the data of a allprop PROPFIND, allow to browse CalDAV/CardDAV/GroupDAV tree with a regular browser. * + * Permanent error_log() calls should use groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). + * * @link http://www.groupdav.org/ GroupDAV spec * @link http://caldav.calconnect.org/ CalDAV resources * @link http://carddav.calconnect.org/ CardDAV resources @@ -393,7 +396,7 @@ class groupdav extends HTTP_WebDAV_Server // Hack for iOS 5.0.1 addressbook to stop asking directory gateway permissions with depth=1 if ($method == 'PROPFIND' && $options['path'] == '/addressbook/' && $handler->get_agent() == 'dataaccess') { - error_log(__CLASS__."::$method(".array2string($options).') Enabling hack for iOS 5.0.1 addressbook: force Depth: 0 on PROPFIND for directory gateway!'); + $this->log(__CLASS__."::$method(".array2string($options).') Enabling hack for iOS 5.0.1 addressbook: force Depth: 0 on PROPFIND for directory gateway!'); return true; } if (!$options['depth']) return true; // depth 0 --> show only the self url @@ -901,9 +904,6 @@ class groupdav extends HTTP_WebDAV_Server if (!$this->_parse_path($options['path'],$id,$app,$user) || $app == 'principals') { return $this->autoindex($options); - - error_log(__METHOD__."(".array2string($options).") 404 Not Found"); - return '404 Not Found'; } if (($handler = self::app_handler($app))) { @@ -1553,30 +1553,40 @@ class groupdav extends HTTP_WebDAV_Server if ($debug_level !== 'f' && strlen($c) > 1536) $c = substr($c,0,1536)."\n*** LOG TRUNKATED\n"; $content .= $c; if ($extra) $content .= $extra; + if ($this->to_log) $content .= "\n### ".implode("\n### ", $this->to_log)."\n"; $content .= sprintf('*** %s --> "%s" took %5.3f s',$_SERVER['REQUEST_METHOD'].($_SERVER['REQUEST_METHOD']=='REPORT'?' '.$this->propfind_options['root']['name']:'').' '.$_SERVER['PATH_INFO'],$this->_http_status,microtime(true)-self::$request_starttime)."\n\n"; - self::log($content,$msg_file); + + if ($msg_file && ($f = fopen($msg_file,'a'))) + { + flock($f,LOCK_EX); + fwrite($f,$content); + flock($f,LOCK_UN); + fclose($f); + } + else + { + foreach($explode("\n",$content) as $line) error_log($line); + } } } /** - * Log to a given file or error_log + * Content of log() calls, to be appended to request_log * - * @param string $content - * @param string $msg_file=null + * @var array */ - private static function log($content,$msg_file=null) + private $to_log = array(); + + /** + * Log unconditional to own request- and PHP error-log + * + * @param string $str + */ + public function log($str) { - if ($msg_file && ($f = fopen($msg_file,'a'))) - { - flock($f,LOCK_EX); - fwrite($f,$content); - flock($f,LOCK_UN); - fclose($f); - } - else - { - foreach($explode("\n",$content) as $line) error_log($line); - } + $to_log[] = $str; + + error_log($str); } /** diff --git a/phpgwapi/inc/class.groupdav_handler.inc.php b/phpgwapi/inc/class.groupdav_handler.inc.php index cecc4a9d10..75030cea65 100644 --- a/phpgwapi/inc/class.groupdav_handler.inc.php +++ b/phpgwapi/inc/class.groupdav_handler.inc.php @@ -13,6 +13,9 @@ /** * EGroupware: GroupDAV access: abstract baseclass for groupdav/caldav/carddav handlers + * + * Permanent error_log() calls should use $this->groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). */ abstract class groupdav_handler { diff --git a/phpgwapi/inc/class.groupdav_principals.inc.php b/phpgwapi/inc/class.groupdav_principals.inc.php index 580d8223ce..fb2868e04a 100644 --- a/phpgwapi/inc/class.groupdav_principals.inc.php +++ b/phpgwapi/inc/class.groupdav_principals.inc.php @@ -18,6 +18,9 @@ * to allow to check if required properties are set! * groupdav_principals::add_principal() converts simple associative props (name => value pairs) * to name => HTTP_WebDAV_Server(name, value) pairs. + * + * Permanent error_log() calls should use $this->groupdav->log($str) instead, to be send to PHP error_log() + * and our request-log (prefixed with "### " after request and response, like exceptions). */ class groupdav_principals extends groupdav_handler { @@ -111,7 +114,7 @@ class groupdav_principals extends groupdav_handler { return $this->$method($path, $options, $files, $user); } - error_log(__METHOD__."('$path', ".array2string($options).",, $user) not implemented report, returning 501 Not Implemented"); + $this->groupdav->log(__METHOD__."('$path', ".array2string($options).",, $user) not implemented report, returning 501 Not Implemented"); return '501 Not Implemented'; } list(,$principals,$type,$name,$rest) = explode('/',$path,5); @@ -290,7 +293,7 @@ class groupdav_principals extends groupdav_handler } if (!isset($property_search) || !$search_props || !isset($search_props[$property_search]['match'])) { - error_log(__METHOD__."('$path',...) Could not parse options[other]=".array2string($options['other'])); + $this->groupdav->log(__METHOD__."('$path',...) Could not parse options[other]=".array2string($options['other'])); return '400 Bad Request'; } // make sure search property is included in toplevel props (can be missing and defaults to property-search/prop's) @@ -310,7 +313,7 @@ class groupdav_principals extends groupdav_handler substr($search_props[0]['match'],-13) == '/groupdav.php') { $path = '/principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/'; - error_log('Enabling hack for Lightning prior 1.1.1 for searching calendar-home-set matching "/groupdav.php": limiting search to '.$path); + $this->groupdav->log('Enabling hack for Lightning prior 1.1.1 for searching calendar-home-set matching "/groupdav.php": limiting search to '.$path); } } // check type attribute to limit search on a certain tree @@ -894,7 +897,7 @@ class groupdav_principals extends groupdav_handler break; default: - error_log(__METHOD__."('$url') unsupported principal URL '$url'!"); + $this->groupdav->log(__METHOD__."('$url') unsupported principal URL '$url'!"); return false; } return $uid && in_array($type, $only_type) ? $uid : false;