mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-27 05:11:44 +02:00
* CalDAV/CardDAV/GroupDAV new user preference to log requests and responses to Apache error-log
This commit is contained in:
parent
6ac00a2375
commit
ac78cbbdae
@ -599,6 +599,19 @@ class HTTP_WebDAV_Server
|
|||||||
|
|
||||||
// {{{ http_PROPFIND()
|
// {{{ http_PROPFIND()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the whole PROPFIND request (xml) be stored
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
var $store_request = false;
|
||||||
|
/**
|
||||||
|
* Content of (last) PROPFIND request
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PROPFIND method handler
|
* PROPFIND method handler
|
||||||
*
|
*
|
||||||
@ -620,7 +633,8 @@ class HTTP_WebDAV_Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
// analyze request payload
|
// analyze request payload
|
||||||
$propinfo = new _parse_propfind("php://input");
|
$propinfo = new _parse_propfind("php://input", $this->store_request);
|
||||||
|
if ($this->store_request) $this->request = $propinfo->request;
|
||||||
if (!$propinfo->success) {
|
if (!$propinfo->success) {
|
||||||
$this->http_status("400 Error");
|
$this->http_status("400 Error");
|
||||||
return;
|
return;
|
||||||
@ -1052,7 +1066,7 @@ class HTTP_WebDAV_Server
|
|||||||
|
|
||||||
$options["path"] = $this->path;
|
$options["path"] = $this->path;
|
||||||
|
|
||||||
$propinfo = new _parse_proppatch("php://input");
|
$propinfo = new _parse_proppatch("php://input", $this->store_request);
|
||||||
|
|
||||||
if (!$propinfo->success) {
|
if (!$propinfo->success) {
|
||||||
$this->http_status("400 Error");
|
$this->http_status("400 Error");
|
||||||
@ -1409,6 +1423,26 @@ class HTTP_WebDAV_Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
$options['stream'] = fopen('php://input', 'r');
|
$options['stream'] = fopen('php://input', 'r');
|
||||||
|
switch($this->_SERVER['HTTP_CONTENT_ENCODING'])
|
||||||
|
{
|
||||||
|
case 'gzip':
|
||||||
|
case 'deflate': //zlib
|
||||||
|
if (extension_loaded('zlib'))
|
||||||
|
{
|
||||||
|
stream_filter_append($options['stream'], 'zlib.inflate', STREAM_FILTER_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// store request in $this->request, if requested via $this->store_request
|
||||||
|
if ($this->store_request)
|
||||||
|
{
|
||||||
|
$options['content'] = '';
|
||||||
|
while(!feof($options['stream']))
|
||||||
|
{
|
||||||
|
$options['content'] .= fread($options['stream'],8192);
|
||||||
|
}
|
||||||
|
$this->request =& $options['content'];
|
||||||
|
unset($options['stream']);
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 2616 2.6 says: "The recipient of the entity MUST NOT
|
/* RFC 2616 2.6 says: "The recipient of the entity MUST NOT
|
||||||
ignore any Content-* (e.g. Content-Range) headers that it
|
ignore any Content-* (e.g. Content-Range) headers that it
|
||||||
@ -1423,11 +1457,7 @@ class HTTP_WebDAV_Server
|
|||||||
{
|
{
|
||||||
case 'gzip':
|
case 'gzip':
|
||||||
case 'deflate': //zlib
|
case 'deflate': //zlib
|
||||||
if (extension_loaded('zlib'))
|
if (extension_loaded('zlib')) break;
|
||||||
{
|
|
||||||
stream_filter_append($options['stream'], 'zlib.inflate', STREAM_FILTER_READ);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fall through for no zlib support
|
// fall through for no zlib support
|
||||||
default:
|
default:
|
||||||
$this->http_status('415 Unsupported Media Type');
|
$this->http_status('415 Unsupported Media Type');
|
||||||
@ -1568,6 +1598,26 @@ class HTTP_WebDAV_Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
$options["stream"] = fopen("php://input", "r");
|
$options["stream"] = fopen("php://input", "r");
|
||||||
|
switch($this->_SERVER['HTTP_CONTENT_ENCODING'])
|
||||||
|
{
|
||||||
|
case 'gzip':
|
||||||
|
case 'deflate': //zlib
|
||||||
|
if (extension_loaded('zlib'))
|
||||||
|
{
|
||||||
|
stream_filter_append($options['stream'], 'zlib.inflate', STREAM_FILTER_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// store request in $this->request, if requested via $this->store_request
|
||||||
|
if ($this->store_request)
|
||||||
|
{
|
||||||
|
$options['content'] = '';
|
||||||
|
while(!feof($options['stream']))
|
||||||
|
{
|
||||||
|
$options['content'] .= fread($options['stream'],8192);
|
||||||
|
}
|
||||||
|
$this->request =& $options['content'];
|
||||||
|
unset($options['stream']);
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 2616 2.6 says: "The recipient of the entity MUST NOT
|
/* RFC 2616 2.6 says: "The recipient of the entity MUST NOT
|
||||||
ignore any Content-* (e.g. Content-Range) headers that it
|
ignore any Content-* (e.g. Content-Range) headers that it
|
||||||
@ -1582,11 +1632,7 @@ class HTTP_WebDAV_Server
|
|||||||
{
|
{
|
||||||
case 'gzip':
|
case 'gzip':
|
||||||
case 'deflate': //zlib
|
case 'deflate': //zlib
|
||||||
if (extension_loaded('zlib'))
|
if (extension_loaded('zlib')) break;
|
||||||
{
|
|
||||||
stream_filter_append($options['stream'], 'zlib.inflate', STREAM_FILTER_READ);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fall through for no zlib support
|
// fall through for no zlib support
|
||||||
default:
|
default:
|
||||||
$this->http_status('415 Unsupported Media Type');
|
$this->http_status('415 Unsupported Media Type');
|
||||||
|
@ -97,13 +97,21 @@ class _parse_propfind
|
|||||||
*/
|
*/
|
||||||
var $depth = 0;
|
var $depth = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On return whole request, if $store_request == true was specified in constructor
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param string $path
|
||||||
|
* @param boolean $store_request=false if true whole request data will be made available in $this->request
|
||||||
*/
|
*/
|
||||||
function _parse_propfind($path)
|
function _parse_propfind($path, $store_request=false)
|
||||||
{
|
{
|
||||||
// success state flag
|
// success state flag
|
||||||
$this->success = true;
|
$this->success = true;
|
||||||
@ -140,10 +148,10 @@ class _parse_propfind
|
|||||||
xml_parser_set_option($xml_parser,
|
xml_parser_set_option($xml_parser,
|
||||||
XML_OPTION_CASE_FOLDING, false);
|
XML_OPTION_CASE_FOLDING, false);
|
||||||
|
|
||||||
|
|
||||||
// parse input
|
// parse input
|
||||||
while ($this->success && !feof($f_in)) {
|
while ($this->success && !feof($f_in)) {
|
||||||
$line = fgets($f_in);
|
$line = fgets($f_in);
|
||||||
|
if ($store_request) $this->request .= $line;
|
||||||
if (is_string($line)) {
|
if (is_string($line)) {
|
||||||
$had_input = true;
|
$had_input = true;
|
||||||
$this->success &= xml_parse($xml_parser, $line, false);
|
$this->success &= xml_parse($xml_parser, $line, false);
|
||||||
|
@ -83,13 +83,21 @@ class _parse_proppatch
|
|||||||
*/
|
*/
|
||||||
var $current;
|
var $current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On return whole request, if $store_request == true was specified in constructor
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
*
|
*
|
||||||
* @param string path of input stream
|
* @param string path of input stream
|
||||||
|
* @param boolean $store_request=false if true whole request data will be made available in $this->request
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function _parse_proppatch($path)
|
function _parse_proppatch($path, $store_request=false)
|
||||||
{
|
{
|
||||||
$this->success = true;
|
$this->success = true;
|
||||||
|
|
||||||
@ -117,6 +125,7 @@ class _parse_proppatch
|
|||||||
|
|
||||||
while($this->success && !feof($f_in)) {
|
while($this->success && !feof($f_in)) {
|
||||||
$line = fgets($f_in);
|
$line = fgets($f_in);
|
||||||
|
if ($store_request) $this->request .= $line;
|
||||||
if (is_string($line)) {
|
if (is_string($line)) {
|
||||||
$had_input = true;
|
$had_input = true;
|
||||||
$this->success &= xml_parse($xml_parser, $line, false);
|
$this->success &= xml_parse($xml_parser, $line, false);
|
||||||
|
@ -351,7 +351,7 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
{
|
{
|
||||||
// principals collection
|
// principals collection
|
||||||
$files['files'][] = $this->add_collection('/principals/', array(
|
$files['files'][] = $this->add_collection('/principals/', array(
|
||||||
'displayname' => lang('Accounts'),
|
'displayname' => lang('Accounts'),
|
||||||
));
|
));
|
||||||
// todo: account_selection owngroups and none!!!
|
// todo: account_selection owngroups and none!!!
|
||||||
foreach($this->accounts->search(array('type' => 'both')) as $account)
|
foreach($this->accounts->search(array('type' => 'both')) as $account)
|
||||||
@ -1235,7 +1235,7 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
}
|
}
|
||||||
if ($path[0] == '/')
|
if ($path[0] == '/')
|
||||||
{
|
{
|
||||||
$path = substr($path, 1);
|
$path = substr($path, 1);
|
||||||
}
|
}
|
||||||
$parts = explode('/', $this->_unslashify($path));
|
$parts = explode('/', $this->_unslashify($path));
|
||||||
|
|
||||||
@ -1293,4 +1293,43 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
self::mkprop('write-content',''),
|
self::mkprop('write-content',''),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve WebDAV HTTP request
|
||||||
|
*
|
||||||
|
* Reimplemented to add logging, currently only to Apache error-log
|
||||||
|
*/
|
||||||
|
function ServeRequest()
|
||||||
|
{
|
||||||
|
if (($debug_level=$GLOBALS['egw_info']['user']['preferences']['groupdav']['debug_level']) === 'r' ||
|
||||||
|
$debug_level === 'f' || $this->debug)
|
||||||
|
{
|
||||||
|
$starttime = microtime(true);
|
||||||
|
$this->store_request = true;
|
||||||
|
ob_start();
|
||||||
|
}
|
||||||
|
parent::ServeRequest();
|
||||||
|
|
||||||
|
if ($starttime)
|
||||||
|
{
|
||||||
|
error_log($_SERVER['REQUEST_METHOD'].' '.$_SERVER['PATH_INFO'].' HTTP/1.1');
|
||||||
|
// reconstruct headers
|
||||||
|
foreach($_SERVER as $name => $value)
|
||||||
|
{
|
||||||
|
list($type,$name) = explode('_',$name,2);
|
||||||
|
if ($type == 'HTTP' || $type == 'CONTENT') error_log(str_replace(' ','-',ucwords(strtolower(($type=='HTTP'?'':$type.' ').str_replace('_',' ',$name)))).': '.$value);
|
||||||
|
}
|
||||||
|
if ($this->request)
|
||||||
|
{
|
||||||
|
error_log('');
|
||||||
|
foreach(explode("\n",$this->request) as $line) error_log($line);
|
||||||
|
}
|
||||||
|
error_log('HTTP/1.1 '.$this->_http_status);
|
||||||
|
foreach(headers_list() as $line) error_log($line);
|
||||||
|
if (($content = ob_get_flush())) error_log('');
|
||||||
|
if (strlen($content) > 1024 && $debug_level !== 'f') $content = substr($content,0,1024)."\n*** LOG TRUNKATED ";
|
||||||
|
$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)-$starttime)."\n";
|
||||||
|
foreach(explode("\n",$content) as $line) error_log($line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,12 @@ class groupdav_hooks
|
|||||||
'name' => 'debug_level',
|
'name' => 'debug_level',
|
||||||
'help' => 'Enables debug-messages to Apache/PHP error-log, allowing to diagnose problems on a per user basis.',
|
'help' => 'Enables debug-messages to Apache/PHP error-log, allowing to diagnose problems on a per user basis.',
|
||||||
'values' => array(
|
'values' => array(
|
||||||
'0' => '0 - off',
|
'0' => 'Off',
|
||||||
'1' => '1 - function calls',
|
'r' => 'Requests and truncated responses',
|
||||||
'2' => '2 - more info',
|
'f' => 'Requests and full responses',
|
||||||
'3' => '3 - complete $_SERVER array',
|
'1' => 'Debug 1 - function calls',
|
||||||
|
'2' => 'Debug 2 - more info',
|
||||||
|
'3' => 'Debug 3 - complete $_SERVER array',
|
||||||
),
|
),
|
||||||
'xmlrpc' => true,
|
'xmlrpc' => true,
|
||||||
'admin' => false,
|
'admin' => false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user