mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-11 16:38:39 +01:00
full implementation of draft-murchison-webdav-prefer-05, incl. return=representation for 412 conflicts
This commit is contained in:
parent
71332a3deb
commit
2d88f9db75
@ -775,6 +775,8 @@ class calendar_groupdav extends groupdav_handler
|
||||
if ($schedule_tag_match !== $schedule_tag)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."(,,$user) schedule_tag missmatch: given '$schedule_tag_match' != '$schedule_tag'");
|
||||
// honor Prefer: return=representation for 412 too (no need for client to explicitly reload)
|
||||
$this->check_return_representation($options, $id, $user);
|
||||
return '412 Precondition Failed';
|
||||
}
|
||||
}
|
||||
@ -892,6 +894,8 @@ class calendar_groupdav extends groupdav_handler
|
||||
}
|
||||
elseif ($cal_id === 0) // etag failure
|
||||
{
|
||||
// honor Prefer: return=representation for 412 too (no need for client to explicitly reload)
|
||||
$this->check_return_representation($options, $id, $user);
|
||||
return '412 Precondition Failed';
|
||||
}
|
||||
else
|
||||
|
@ -742,6 +742,13 @@ class HTTP_WebDAV_Server
|
||||
header("DAV: " .join(", ", $dav));
|
||||
header('Content-Type: text/xml; charset="utf-8"');
|
||||
|
||||
// add Vary and Preference-Applied header for Prefer: return=minimal
|
||||
if (isset($this->_SERVER['HTTP_PREFER']) && in_array('return=minimal', preg_split('/, ?/', $this->_SERVER['HTTP_PREFER'])))
|
||||
{
|
||||
header("Preference-Applied: return=minimal");
|
||||
header("Vary: Prefer");
|
||||
}
|
||||
|
||||
// ... and payload
|
||||
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
echo $this->crrnd ? "<multistatus xmlns=\"DAV:\">\n" : "<D:multistatus xmlns:D=\"DAV:\">\n";
|
||||
@ -777,9 +784,20 @@ class HTTP_WebDAV_Server
|
||||
{
|
||||
$files = new ArrayIterator($files);
|
||||
}
|
||||
// support for "Prefer: depth-noroot" header on PROPFIND
|
||||
$skip_root = $this->_SERVER['REQUEST_METHOD'] == 'PROPFIND' &&
|
||||
!isset($initial_ns_hash) && // multistatus_response calls itself, do NOT apply skip in that case
|
||||
isset($this->_SERVER['HTTP_PREFER']) && in_array('depth-noroot', preg_split('/, ?/', $this->_SERVER['HTTP_PREFER']));
|
||||
|
||||
// now we loop over all returned file entries
|
||||
foreach ($files as $file) {
|
||||
|
||||
// skip first element (root), if requested by Prefer: depth-noroot
|
||||
if ($skip_root) {
|
||||
$skip_root = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// collect namespaces here
|
||||
$ns_hash = $initial_ns_hash;
|
||||
|
||||
@ -864,9 +882,9 @@ class HTTP_WebDAV_Server
|
||||
= $this->mkprop("DAV:",
|
||||
"lockdiscovery",
|
||||
$this->lockdiscovery($file['path']));
|
||||
// only collect $file['noprops'] if we have NO Brief: t and NO Prefer: return-minimal HTTP Header
|
||||
// only collect $file['noprops'] if we have NO Brief: t and NO Prefer: return=minimal HTTP Header
|
||||
} elseif ((!isset($this->_SERVER['HTTP_BRIEF']) || $this->_SERVER['HTTP_BRIEF'] != 't') &&
|
||||
(!isset($this->_SERVER['HTTP_PREFER']) || $this->_SERVER['HTTP_PREFER'] != 'return-minimal')) {
|
||||
(!isset($this->_SERVER['HTTP_PREFER']) || !in_array('return=minimal', preg_split('/, ?/', $this->_SERVER['HTTP_PREFER'])))) {
|
||||
// add empty value for this property
|
||||
$file["noprops"][] =
|
||||
$this->mkprop($reqprop["xmlns"], $reqprop["name"], "");
|
||||
|
@ -292,6 +292,8 @@ abstract class groupdav_handler
|
||||
if ($this->http_if_match !== $etag)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."($method,path=$options[path],$id) HTTP_IF_MATCH='$_SERVER[HTTP_IF_MATCH]', etag='$etag': 412 Precondition failed".array2string($entry));
|
||||
// honor Prefer: return=representation for 412 too (no need for client to explicitly reload)
|
||||
$this->check_return_representation($options, $id);
|
||||
return '412 Precondition Failed';
|
||||
}
|
||||
}
|
||||
@ -310,6 +312,8 @@ abstract class groupdav_handler
|
||||
if ($method == 'PUT' && ($if_none_match == '*' || $if_none_match == $etag))
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."($method,,$id) HTTP_IF_NONE_MATCH='$_SERVER[HTTP_IF_NONE_MATCH]', etag='$etag': 412 Precondition failed");
|
||||
// honor Prefer: return=representation for 412 too (no need for client to explicitly reload)
|
||||
$this->check_return_representation($options, $id);
|
||||
return '412 Precondition Failed';
|
||||
}
|
||||
}
|
||||
@ -317,6 +321,44 @@ abstract class groupdav_handler
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return representation, if requested by HTTP Prefer header
|
||||
*
|
||||
* @param array $options
|
||||
* @param int $id
|
||||
* @param int $user=null account_id
|
||||
* @return string|boolean http status of get or null if no representation was requested
|
||||
*/
|
||||
public function check_return_representation($options, $id, $user=null)
|
||||
{
|
||||
//error_log(__METHOD__."(, $id, $user) start ".function_backtrace());
|
||||
if (isset($_SERVER['HTTP_PREFER']) && in_array('return=representation', preg_split('/, ?/', $_SERVER['HTTP_PREFER'])))
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST')
|
||||
{
|
||||
$location = $this->groupdav->base_uri.$options['path'];
|
||||
if ($location[0] == '/')
|
||||
{
|
||||
$location = (@$_SERVER['HTTPS'] === 'on' ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$location;
|
||||
}
|
||||
header('Content-Location: '.$location);
|
||||
}
|
||||
|
||||
// remove If-Match or If-None-Match headers, otherwise HTTP status 412 goes into endless loop!
|
||||
unset($_SERVER['HTTP_IF_MATCH']);
|
||||
unset($_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
|
||||
if (($ret = $this->get($options, $id ? $id : $this->new_id, $user)) && !empty($options['data']))
|
||||
{
|
||||
header('Content-Length: '.$this->groupdav->bytes($options['data']));
|
||||
header('Content-Type: '.$options['mimetype']);
|
||||
echo $options['data'];
|
||||
}
|
||||
}
|
||||
//error_log(__METHOD__."(, $id, $user) returning ".array2string($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handler for the given app
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user