aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJack Bates <jablko@users.sourceforge.net>2006-04-14 02:50:09 +0000
committerJack Bates <jablko@users.sourceforge.net>2006-04-14 02:50:09 +0000
commit40e077eb346693da15662632a90e5df0ff305046 (patch)
treec00c8197ae733e7e56e61e2aacecbde2c6818082 /lib
parentdfc4ff9ca8e46383d68320738b0336cf27458bab (diff)
downloadphpicalendar-40e077eb346693da15662632a90e5df0ff305046.tar.gz
phpicalendar-40e077eb346693da15662632a90e5df0ff305046.tar.bz2
phpicalendar-40e077eb346693da15662632a90e5df0ff305046.zip
* Depth: header support
* Committing current WebDAV library
Diffstat (limited to 'lib')
-rw-r--r--lib/HTTP/WebDAV/Server.php453
-rw-r--r--lib/HTTP/WebDAV/Tools/_parse_lockinfo.php2
-rw-r--r--lib/HTTP/WebDAV/Tools/_parse_propfind.php280
-rw-r--r--lib/HTTP/WebDAV/Tools/_parse_proppatch.php2
4 files changed, 407 insertions, 330 deletions
diff --git a/lib/HTTP/WebDAV/Server.php b/lib/HTTP/WebDAV/Server.php
index 9acddff..2d5785d 100644
--- a/lib/HTTP/WebDAV/Server.php
+++ b/lib/HTTP/WebDAV/Server.php
@@ -16,7 +16,7 @@
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
-// $Id: Server.php,v 1.1 2006/04/09 19:27:12 jablko Exp $
+// $Id: Server.php,v 1.2 2006/04/14 02:50:09 jablko Exp $
require_once 'Tools/_parse_propfind.php';
require_once 'Tools/_parse_proppatch.php';
@@ -150,8 +150,9 @@ class HTTP_WebDAV_Server
$method = strtolower($_SERVER['REQUEST_METHOD']);
$wrapper = $method . '_wrapper';
- // activate HEAD emulation by GET if no HEAD method found
- if ($method == 'head' && !method_exists($this, 'head')) {
+ // emulate HEAD using GET if no HEAD method found
+ if ($wrapper == 'head_wrapper' &&
+ !method_exists($this, 'head')) {
$method = 'get';
}
@@ -462,22 +463,20 @@ class HTTP_WebDAV_Server
$options = array();
$options['path'] = $this->path;
- // search depth from header (default is 'infinity')
+ // get depth from header (default is 'infinity')
+ $options['depth'] = 'infinity';
if (isset($_SERVER['HTTP_DEPTH'])) {
$options['depth'] = $_SERVER['HTTP_DEPTH'];
- } else {
- $options['depth'] = 'infinity';
}
// analyze request payload
- $propinfo = new _parse_propfind('php://input');
-
- if (!$propinfo->success) {
+ $parser = new _parse_propfind('php://input');
+ if (!$parser->success) {
$this->http_status('400 Bad Request');
return;
}
- $options['props'] = $propinfo->props;
+ $options['props'] = $parser->props;
return true;
}
@@ -499,6 +498,12 @@ class HTTP_WebDAV_Server
// now loop over all returned files
foreach ($files as $file) {
+
+ // collect namespaces here
+ // Microsoft need this special namespace for date and time values
+ $ns_hash = array(
+ 'urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882' => 'ns0');
+
$response = array();
$response['href'] = $this->getHref($file['path']);
@@ -508,63 +513,23 @@ class HTTP_WebDAV_Server
$response['propstat'] = array();
- // collect namespaces here
- $ns_hash = array();
-
- // Microsoft need this special namespace for date and time values
- $ns_hash['urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882'] = 'ns0';
+ if (is_array($options['props'])) {
- // nothing to do if no properties were returend
- if (isset($file['props']) && is_array($file['props'])) {
-
- // now loop over all returned properties
- foreach ($file['props'] as $prop) {
+ // loop over all requested properties
+ foreach ($options['props'] as $reqprop) {
$status = '200 OK';
+ $prop = $this->getProp($reqprop, $file, $options);
- // as a convenience feature we do not require user handlers
- // restrict returned properties to the requested ones
- // here we ignore unrequested entries
- switch ($options['props']) {
- case 'names':
-
- // only names of all existing properties were requested
- // so remove values
- unset($prop['val']);
-
- case 'all':
- if (isset($prop['status'])) {
- $status = $prop['status'];
- }
-
- if (!isset($response['propstat'][$status])) {
- $response['propstat'][$status] = array();
- }
-
- $response['propstat'][$status][] = $prop;
- break;
-
- default:
-
- // search property name in requested properties
- foreach($options['props'] as $reqprop) {
- if ($reqprop['name'] == $prop['name'] &&
- $reqprop['xmlns'] == $prop['ns']) {
- if (isset($prop['status'])) {
- $status = $prop['status'];
- }
-
- if (!isset($response['propstat'][$status])) {
- $response['propstat'][$status] = array();
- }
-
- $response['propstat'][$status][] = $prop;
- break(2);
- }
- }
+ if (isset($prop['status'])) {
+ $status = $prop['status'];
+ }
- continue(2);
+ if (!isset($response['propstat'][$status])) {
+ $response['propstat'][$status] = array();
}
+ $response['propstat'][$status][] = $prop;
+
// namespace handling
if (empty($prop['ns']) || // empty namespace
$prop['ns'] == 'DAV:' || // default namespace
@@ -575,57 +540,39 @@ class HTTP_WebDAV_Server
// register namespace
$ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
}
- }
-
- // also need empty entries for properties requested
- // but for which no values where returned
- if (isset($options['props']) && is_array($options['props'])) {
-
- // now loop over all requested properties
- foreach ($options['props'] as $reqprop) {
- $status = '404 Not Found';
-
- // check if property exists in result
- foreach ($file['props'] as $prop) {
- if ($reqprop['name'] == $prop['name'] &&
- $reqprop['xmlns'] == $prop['ns']) {
- continue(2);
- }
- }
-
- if ($reqprop['name'] == 'lockdiscovery' &&
- $reqprop['xmlns'] == 'DAV:' &&
- method_exists($this, 'getLocks')) {
+ } else if (is_array($file['props'])) {
- $status = '200 OK';
- if (!isset($response['propstat'][$status])) {
- $response['propstat'][$status] = array();
- }
+ // loop over all returned properties
+ foreach ($file['props'] as $prop) {
+ $status = '200 OK';
- $response['propstat'][$status][] =
- $this->mkprop('DAV:', 'lockdiscovery',
- $this->getLocks($file['path']));
- continue;
+ if (isset($prop['status'])) {
+ $status = $prop['status'];
}
if (!isset($response['propstat'][$status])) {
$response['propstat'][$status] = array();
}
- // add empty value for this property
- $response['propstat'][$status][] =
- $this->mkprop($reqprop['xmlns'], $reqprop['name'],
- null);
+ if ($options['props'] == 'propname') {
+
+ // only names of all existing properties were requested
+ // so remove values
+ unset($prop['value']);
+ }
+
+ $response['propstat'][$status][] = $prop;
+ unset($prop['value']);
// namespace handling
- if (empty($reqprop['xmlns']) || // empty namespace
- $reqprop['xmlns'] == 'DAV:' || // default namespace
- isset($ns_hash[$reqprop['xmlns']])) { // already known
+ if (empty($prop['ns']) || // empty namespace
+ $prop['ns'] == 'DAV:' || // default namespace
+ isset($ns_hash[$prop['ns']])) { // already known
continue;
}
// register namespace
- $ns_hash[$reqprop['xmlns']] = 'ns' . count($ns_hash);
+ $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
}
}
@@ -676,8 +623,8 @@ class HTTP_WebDAV_Server
// empty properties (cannot use empty for check as '0'
// is a legal value here)
- if (!isset($prop['val']) || empty($prop['val']) &&
- $prop['val'] !== 0) {
+ if (!isset($prop['value']) || empty($prop['value']) &&
+ $prop['value'] !== 0) {
if ($prop['ns'] == 'DAV:') {
echo " <D:$prop[name]/>\n";
continue;
@@ -700,45 +647,45 @@ class HTTP_WebDAV_Server
switch ($prop['name']) {
case 'creationdate':
echo " <D:creationdate ns0:dt=\"dateTime.tz\">\n";
- echo ' ' . gmdate('Y-m-d\TH:i:s\Z', $prop['val']) . "\n";
+ echo ' ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
echo " </D:creationdate>\n";
break;
case 'getlastmodified':
echo " <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
- echo ' ' . gmdate('D, d M Y H:i:s', $prop['val']) . " GMT\n";
+ echo ' ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
echo " </D:getlastmodified>\n";
break;
case 'resourcetype':
echo " <D:resourcetype>\n";
- echo " <D:$prop[val]/>\n";
+ echo " <D:$prop[value]/>\n";
echo " </D:resourcetype>\n";
break;
case 'supportedlock':
- if (is_array($prop[val])) {
- $prop[val] = $this->_lockentries($prop[val]);
+ if (is_array($prop[value])) {
+ $prop[value] = $this->_lockentries($prop[value]);
}
echo " <D:supportedlock>\n";
- echo " $prop[val]\n";
+ echo " $prop[value]\n";
echo " </D:supportedlock>\n";
break;
case 'lockdiscovery':
- if (is_array($prop[val])) {
- $prop[val] = $this->_activelocks($prop[val]);
+ if (is_array($prop[value])) {
+ $prop[value] = $this->_activelocks($prop[value]);
}
echo " <D:lockdiscovery>\n";
- echo " $prop[val]\n";
+ echo " $prop[value]\n";
echo " </D:lockdiscovery>\n";
break;
default:
echo " <D:$prop[name]>\n";
- echo ' ' . $this->_prop_encode(htmlspecialchars($prop['val'])) . "\n";
+ echo ' ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
echo " </D:$prop[name]>\n";
}
@@ -747,14 +694,14 @@ class HTTP_WebDAV_Server
if (!empty($prop['ns'])) {
echo ' <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
- echo ' ' . $this->_prop_encode(htmlspecialchars($prop['val'])) . "\n";
+ echo ' ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
echo ' </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
continue;
}
echo " <$prop[name] xmlns=\"\">\n";
- echo ' ' . $this->_prop_encode(htmlspecialchars($prop['val'])) . "\n";
+ echo ' ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
echo " </$prop[name]>\n";
}
@@ -961,6 +908,33 @@ class HTTP_WebDAV_Server
return true;
}
+ /**
+ * parse HTTP Range: header
+ *
+ * @param array options array to store result in
+ * @return void
+ */
+ function _get_ranges(&$options)
+ {
+ // process Range: header if present
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ // we only support standard 'bytes' range specifications for now
+ if (ereg('bytes[[:space:]]*=[[:space:]]*(.+)', $_SERVER['HTTP_RANGE'], $matches)) {
+ $options['ranges'] = array();
+
+ // ranges are comma separated
+ foreach (explode(',', $matches[1]) as $range) {
+ // ranges are either from-to pairs or just end positions
+ list($start, $end) = explode('-', $range);
+ $options['ranges'][] = ($start === '')
+ ? array('last' => $end)
+ : array('start' => $start, 'end' => $end);
+ }
+ }
+ }
+ }
+
// }}}
// {{{ get_response_helper
@@ -975,7 +949,7 @@ class HTTP_WebDAV_Server
function get_response_helper($options, $status)
{
if (empty($status)) {
- $status('404 Not Found');
+ $status = '404 Not Found';
}
// set headers before we start printing
@@ -995,7 +969,7 @@ class HTTP_WebDAV_Server
gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
}
- if (isset($options['stream'])) {
+ if ($options['stream']) {
// GET handler returned a stream
if (!empty($options['ranges']) &&
@@ -1082,57 +1056,6 @@ class HTTP_WebDAV_Server
}
}
- // }}}
-
- // {{{ get_wrapper
-
- /**
- * GET method wrapper
- *
- * @param void
- * @return void
- */
- function get_wrapper()
- {
- // perpare data-structure from GET request
- if (!$this->get_request_helper($options)) {
- return;
- }
-
- // call user handler
- $status = $this->get($options);
-
- // format GET response
- $this->get_response_helper($options, $status);
- }
-
- /**
- * parse HTTP Range: header
- *
- * @param array options array to store result in
- * @return void
- */
- function _get_ranges(&$options)
- {
- // process Range: header if present
- if (isset($_SERVER['HTTP_RANGE'])) {
-
- // we only support standard 'bytes' range specifications for now
- if (ereg('bytes[[:space:]]*=[[:space:]]*(.+)', $_SERVER['HTTP_RANGE'], $matches)) {
- $options['ranges'] = array();
-
- // ranges are comma separated
- foreach (explode(',', $matches[1]) as $range) {
- // ranges are either from-to pairs or just end positions
- list($start, $end) = explode('-', $range);
- $options['ranges'][] = ($start === '')
- ? array('last' => $end)
- : array('start' => $start, 'end' => $end);
- }
- }
- }
- }
-
/**
* generate separator headers for multipart response
*
@@ -1179,6 +1102,138 @@ class HTTP_WebDAV_Server
// }}}
+ // {{{ get_wrapper
+
+ /**
+ * GET method wrapper
+ *
+ * @param void
+ * @return void
+ */
+ function get_wrapper()
+ {
+ // perpare data-structure from GET request
+ if (!$this->get_request_helper($options)) {
+ return;
+ }
+
+ // call user handler
+ $status = $this->get($options);
+
+ // format GET response
+ $this->get_response_helper($options, $status);
+ }
+
+ // }}}
+
+ // {{{ head_response_helper
+
+ /**
+ * HEAD response helper - format HEAD response
+ *
+ * @param options
+ * @param status
+ * @return void
+ */
+ function head_response_helper($options, $status)
+ {
+ if (empty($status)) {
+ $status('404 Not Found');
+ }
+
+ // set headers before we start printing
+ $this->http_status($status);
+
+ if ($status !== true) {
+ return;
+ }
+
+ if (!isset($options['mimetype'])) {
+ $options['mimetype'] = 'application/octet-stream';
+ }
+ header("Content-Type: $options[mimetype]");
+
+ if (isset($options['mtime'])) {
+ header('Last-Modified:' .
+ gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
+ }
+
+ if (isset($options['stream'])) {
+ // GET handler returned a stream
+
+ if (!empty($options['ranges']) &&
+ (fseek($options['stream'], 0, SEEK_SET) === 0)) {
+ // partial request and stream is seekable
+
+ if (count($options['ranges']) === 1) {
+ $range = $options['ranges'][0];
+
+ if (isset($range['start'])) {
+ fseek($options['stream'], $range['start'], SEEK_SET);
+ if (feof($options['stream'])) {
+ $this->http_status('416 Requested Range Not Satisfiable');
+ return;
+ }
+
+ if (isset($range['end'])) {
+ $size = $range['end'] - $range['start'] + 1;
+ $this->http_status('206 Partial');
+ header("Content-Length: $size");
+ header("Content-Range: $range[start]-$range[end]/" .
+ (isset($options['size']) ? $options['size'] : '*'));
+ } else {
+ $this->http_status('206 Partial');
+ if (isset($options['size'])) {
+ header("Content-Length: " .
+ ($options['size'] - $range['start']));
+ header("Content-Range: $start-$end/" .
+ (isset($options['size']) ? $options['size'] : '*'));
+ }
+ }
+ } else {
+ header("Content-Length: $range[last]");
+ fseek($options['stream'], -$range['last'], SEEK_END);
+ }
+ } else {
+ $this->_multipart_byterange_header(); // init multipart
+ foreach ($options['ranges'] as $range) {
+
+ // TODO what if size unknown? 500?
+ if (isset($range['start'])) {
+ $from = $range['start'];
+ $to = !empty($range['end']) ? $range['end'] :
+ $options['size'] - 1;
+ } else {
+ $from = $options['size'] - $range['last'] - 1;
+ $to = $options['size'] - 1;
+ }
+ $total = isset($options['size']) ? $options['size'] :
+ '*';
+ $size = $to - $from + 1;
+ $this->_multipart_byterange_header($options['mimetype'],
+ $from, $to, $total);
+
+ fseek($options['stream'], $start, SEEK_SET);
+ }
+ $this->_multipart_byterange_header(); // end multipart
+ }
+ } else {
+ // normal request or stream isn't seekable, return full content
+ if (isset($options['size'])) {
+ header("Content-Length: $options[size]");
+ }
+ }
+ } else if (isset($options['data'])) {
+ if (is_array($options['data'])) {
+ // reply to partial request
+ } else {
+ header("Content-Length: " . strlen($options['data']));
+ }
+ }
+ }
+
+ // }}}
+
// {{{ head_wrapper
/**
@@ -1192,18 +1247,19 @@ class HTTP_WebDAV_Server
$options = array();
$options['path'] = $this->path;
- if (method_exists($this, 'HEAD')) {
+ // call user handler
+ if (method_exists($this, 'head')) {
$status = $this->head($options);
- } else if (method_exists($this, 'GET')) {
+ } else {
+
+ // can emulate HEAD using GET
ob_start();
$status = $this->get($options);
ob_end_clean();
}
- if (empty($status)) {
- $status = '404 Not Found';
- }
- $this->http_status($status);
+ // format HEAD response
+ $this->head_response_helper($options, $status);
}
// }}}
@@ -1243,14 +1299,14 @@ class HTTP_WebDAV_Server
// ignore any Content-* (e.g. Content-Range) headers that it
// does not understand or implement and MUST return a 501
// (Not Implemented) response in such cases.
- foreach ($_SERVER as $key => $val) {
+ foreach ($_SERVER as $key => $value) {
if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
switch ($key) {
case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
// TODO support this if ext/zlib filters are available
$this->http_status('501 Not Implemented');
- echo "The service does not support '$val' content encoding";
+ echo "The service does not support '$value' content encoding";
return;
case 'HTTP_CONTENT_LANGUAGE': // RFC2616 14.12
@@ -1763,6 +1819,30 @@ class HTTP_WebDAV_Server
return $this->base_uri . '/' . $path;
}
+ function getProp($reqprop, $file, $options)
+ {
+ // check if property exists in response
+ foreach ($file['props'] as $prop) {
+ if ($reqprop['name'] == $prop['name'] &&
+ $reqprop['ns'] == $prop['ns']) {
+ return $prop;
+ }
+ }
+
+ if ($reqprop['name'] == 'lockdiscovery' &&
+ $reqprop['ns'] == 'DAV:' &&
+ method_exists($this, 'getLocks')) {
+
+ return $this->mkprop('DAV:', 'lockdiscovery',
+ $this->getLocks($file['path']));
+ }
+
+ // incase the requested property had a value, like calendar-data
+ unset($reqprop['value']);
+ $reqprop['status'] = '404 Not Found';
+ return $reqprop;
+ }
+
function getDescendentsLocks($path)
{
$options = array();
@@ -1801,9 +1881,9 @@ class HTTP_WebDAV_Server
// http://bugs.php.net/bug.php?id=36944
//if (!strncmp('_wrapper', $method, -8)) {
if (!strcmp(substr($method, -8), '_wrapper')) {
- $method = strtoupper(substr($method, 0, -8));
+ $method = strtolower(substr($method, 0, -8));
if (method_exists($this, $method) &&
- ($method != 'LOCK' && $method != 'UNLOCK' ||
+ ($method != 'lock' && $method != 'unlock' ||
method_exists($this, 'getLocks'))) {
$allow[] = $method;
}
@@ -1833,15 +1913,18 @@ class HTTP_WebDAV_Server
function mkprop()
{
$args = func_get_args();
- if (count($args) == 3) {
- return array('ns' => $args[0],
- 'name' => $args[1],
- 'val' => $args[2]);
+
+ $prop = array();
+ $prop['ns'] = 'DAV:';
+ if (count($args) > 2) {
+ $prop['ns'] = array_shift($args);
}
- return array('ns' => 'DAV:',
- 'name' => $args[0],
- 'val' => $args[1]);
+ $prop['name'] = array_shift($args);
+ $prop['value'] = array_shift($args);
+ $prop['status'] = array_shift($args);
+
+ return $prop;
}
// }}}
@@ -2058,8 +2141,8 @@ class HTTP_WebDAV_Server
if (is_array($uris[$uri])) {
$uris[$uri] = array_merge($uris[$uri], $list);
- continue;
- }
+ continue;
+ }
$uris[$uri] = $list;
}
@@ -2103,7 +2186,7 @@ class HTTP_WebDAV_Server
}
if (!$this->_check_uri_condition($uri, $condition)) {
- continue(2);
+ continue (2);
}
}
diff --git a/lib/HTTP/WebDAV/Tools/_parse_lockinfo.php b/lib/HTTP/WebDAV/Tools/_parse_lockinfo.php
index 9b1ba39..d32d12a 100644
--- a/lib/HTTP/WebDAV/Tools/_parse_lockinfo.php
+++ b/lib/HTTP/WebDAV/Tools/_parse_lockinfo.php
@@ -17,7 +17,7 @@
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
-// $Id: _parse_lockinfo.php,v 1.1 2006/04/09 19:27:12 jablko Exp $
+// $Id: _parse_lockinfo.php,v 1.2 2006/04/14 02:50:10 jablko Exp $
//
/**
diff --git a/lib/HTTP/WebDAV/Tools/_parse_propfind.php b/lib/HTTP/WebDAV/Tools/_parse_propfind.php
index be560a8..a44c3a9 100644
--- a/lib/HTTP/WebDAV/Tools/_parse_propfind.php
+++ b/lib/HTTP/WebDAV/Tools/_parse_propfind.php
@@ -1,5 +1,4 @@
<?php
-//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
@@ -17,8 +16,7 @@
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
-// $Id: _parse_propfind.php,v 1.1 2006/04/09 19:27:12 jablko Exp $
-//
+// $Id: _parse_propfind.php,v 1.2 2006/04/14 02:50:10 jablko Exp $
/**
* helper class for parsing PROPFIND request bodies
@@ -29,145 +27,141 @@
*/
class _parse_propfind
{
- /**
- * success state flag
- *
- * @var bool
- * @access public
- */
- var $success = false;
-
- /**
- * found properties are collected here
- *
- * @var array
- * @access public
- */
- var $props = false;
-
- /**
- * internal tag nesting depth counter
- *
- * @var int
- * @access private
- */
- var $depth = 0;
-
- /**
- * constructor
- *
- * @access public
- */
- function _parse_propfind($path)
- {
- // success state flag
- $this->success = true;
-
- // property storage array
- $this->props = array();
-
- // internal tag depth counter
- $this->depth = 0;
-
- // remember if any input was parsed
- $had_input = false;
-
- // open input stream
- $f_in = fopen($path, 'r');
- if (!$f_in) {
- $this->success = false;
- return;
- }
-
- // create XML parser
- $xml_parser = xml_parser_create_ns('UTF-8', ' ');
-
- // set tag and data handlers
- xml_set_element_handler($xml_parser,
- array(&$this, '_startElement'),
- array(&$this, '_endElement'));
-
- // we want a case sensitive parser
- xml_parser_set_option($xml_parser,
- XML_OPTION_CASE_FOLDING, false);
-
- // parse input
- while($this->success && !feof($f_in)) {
- $line = fgets($f_in);
- if (is_string($line)) {
- $had_input = true;
- $this->success &= xml_parse($xml_parser, $line, false);
- }
- }
-
- // finish parsing
- if($had_input) {
- $this->success &= xml_parse($xml_parser, '', true);
- }
-
- // free parser
- xml_parser_free($xml_parser);
-
- // close input stream
- fclose($f_in);
-
- // if no input was parsed it was a request
- if(!count($this->props)) $this->props = 'all'; // default
- }
-
- /**
- * start tag handler
- *
- * @access private
- * @param resource parser
- * @param string tag name
- * @param array tag attributes
- */
- function _startElement($parser, $name, $attrs)
- {
- // name space handling
- if (strstr($name, ' ')) {
- list($ns, $tag) = explode(' ', $name);
- if ($ns == '')
- $this->success = false;
- } else {
- $ns = '';
- $tag = $name;
- }
-
- // special tags at level 1: <allprop> and <propname>
- if ($this->depth == 1) {
- if ($tag == 'allprop')
- $this->props = 'all';
-
- if ($tag == 'propname')
- $this->props = 'names';
- }
-
- // requested properties are found at level 2
- if ($this->depth == 2) {
- $prop = array('name' => $tag);
- if ($ns)
- $prop['xmlns'] = $ns;
- $this->props[] = $prop;
- }
-
- // increment depth count
- $this->depth++;
- }
-
- /**
- * end tag handler
- *
- * @access private
- * @param resource parser
- * @param string tag name
- */
- function _endElement($parser, $name)
- {
- // here we only need to decrement the depth count
- $this->depth--;
- }
+ /**
+ * success state flag
+ *
+ * @var bool
+ * @access public
+ */
+ var $success = false;
+
+ /**
+ * found properties are collected here
+ *
+ * @var array
+ * @access public
+ */
+ var $props = false;
+
+ /**
+ * internal tag nesting depth counter
+ *
+ * @var int
+ * @access private
+ */
+ var $depth = 0;
+
+ /**
+ * constructor
+ *
+ * @access public
+ */
+ function _parse_propfind($input)
+ {
+ // success state flag
+ $this->success = true;
+
+ // property storage array
+ $this->props = array();
+
+ // internal tag depth counter
+ $this->depth = 0;
+
+ // remember if any input was parsed
+ $had_input = false;
+
+ // open input stream
+ $handle = fopen($input, 'r');
+ if (!$handle) {
+ $this->success = false;
+ return;
+ }
+
+ // create XML parser
+ $parser = xml_parser_create_ns('UTF-8', ' ');
+
+ // set tag and data handlers
+ xml_set_element_handler($parser, array(&$this, '_startElement'),
+ array(&$this, '_endElement'));
+
+ // we want a case sensitive parser
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
+
+ // parse input
+ while ($this->success && !feof($handle)) {
+ $line = fgets($handle);
+ if (is_string($line)) {
+ $had_input = true;
+ $this->success &= xml_parse($parser, $line, false);
+ }
+ }
+
+ // finish parsing
+ if ($had_input) {
+ $this->success &= xml_parse($parser, '', true);
+ }
+
+ // free parser
+ xml_parser_free($parser);
+
+ // close input stream
+ fclose($handle);
+
+ // if no input was parsed it was a request
+ if (empty($this->props)) {
+ $this->props = 'allprop';
+ }
+ }
+
+ /**
+ * start tag handler
+ *
+ * @access private
+ * @param resource parser
+ * @param string tag name
+ * @param array tag attributes
+ */
+ function _startElement($parser, $name, $attrs)
+ {
+ // name space handling
+ if (strstr($name, ' ')) {
+ list ($ns, $name) = explode(' ', $name);
+ if (!$ns) {
+ $this->success = false;
+ }
+ }
+
+ // special tags at level 1: <allprop> and <propname>
+ if ($this->depth == 1) {
+ if ($name == 'allprop' || $name == 'propname') {
+ $this->props = $name;
+ }
+ }
+
+ // requested properties are found at level 2
+ if ($this->depth == 2) {
+ $prop = array('name' => $name);
+ if ($ns) {
+ $prop['ns'] = $ns;
+ }
+ $this->props[] = $prop;
+ }
+
+ // increment depth count
+ $this->depth++;
+ }
+
+ /**
+ * end tag handler
+ *
+ * @access private
+ * @param resource parser
+ * @param string tag name
+ */
+ function _endElement($parser, $name)
+ {
+ // here we only need to decrement the depth count
+ $this->depth--;
+ }
}
-
?>
diff --git a/lib/HTTP/WebDAV/Tools/_parse_proppatch.php b/lib/HTTP/WebDAV/Tools/_parse_proppatch.php
index eb6b0a4..ca10890 100644
--- a/lib/HTTP/WebDAV/Tools/_parse_proppatch.php
+++ b/lib/HTTP/WebDAV/Tools/_parse_proppatch.php
@@ -17,7 +17,7 @@
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
-// $Id: _parse_proppatch.php,v 1.1 2006/04/09 19:27:12 jablko Exp $
+// $Id: _parse_proppatch.php,v 1.2 2006/04/14 02:50:10 jablko Exp $
//
/**

© 2014-2024 Faster IT GmbH | imprint | privacy policy