mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-02-17 19:01:04 +01:00
Fix CalDAV issues
This commit is contained in:
parent
045e2b5180
commit
9c5284bc61
@ -482,7 +482,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
|
|||||||
$oldEvent = $this->_common_get_put_delete('PUT',$options,$id,$return_no_access);
|
$oldEvent = $this->_common_get_put_delete('PUT',$options,$id,$return_no_access);
|
||||||
if (!is_null($oldEvent) && !is_array($oldEvent))
|
if (!is_null($oldEvent) && !is_array($oldEvent))
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__.print_r($oldEvent,true).function_backtrace());
|
if ($this->debug) error_log(__METHOD__.': '.print_r($oldEvent,true).function_backtrace());
|
||||||
return $oldEvent;
|
return $oldEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,10 +591,44 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
|
|||||||
*/
|
*/
|
||||||
function post(&$options,$id,$user=null)
|
function post(&$options,$id,$user=null)
|
||||||
{
|
{
|
||||||
if (preg_match('/^METHOD:PUBLISH(\r\n|\r|\n)/im', $options['content']))
|
if ($this->debug) error_log(__METHOD__."($id, $user)".print_r($options,true));
|
||||||
|
|
||||||
|
if (preg_match('/^METHOD:(PUBLISH|REQUEST)(\r\n|\r|\n)(.*)^BEGIN:VEVENT/ism', $options['content']))
|
||||||
{
|
{
|
||||||
$status = $this->put($options,$id,$user);
|
$handler = $this->_get_handler();
|
||||||
// error_log("CalDAV POST: $status" . print_r($options, true));
|
$vCalendar = htmlspecialchars_decode($options['content']);
|
||||||
|
$charset = null;
|
||||||
|
if (!empty($options['content_type']))
|
||||||
|
{
|
||||||
|
$content_type = explode(';', $options['content_type']);
|
||||||
|
if (count($content_type) > 1)
|
||||||
|
{
|
||||||
|
array_shift($content_type);
|
||||||
|
foreach ($content_type as $attribute)
|
||||||
|
{
|
||||||
|
trim($attribute);
|
||||||
|
list($key, $value) = explode('=', $attribute);
|
||||||
|
switch (strtolower($key))
|
||||||
|
{
|
||||||
|
case 'charset':
|
||||||
|
$charset = strtoupper(substr($value,1,-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($foundEvents = $handler->search($vCalendar, null, false, $charset)))
|
||||||
|
{
|
||||||
|
$eventId = array_shift($foundEvents);
|
||||||
|
list($eventId) = explode(':', $eventId);
|
||||||
|
|
||||||
|
if (!($cal_id = $handler->importVCal($vCalendar, $eventId, null,
|
||||||
|
false, 0, $this->principalURL, $user, $charset)))
|
||||||
|
{
|
||||||
|
if ($this->debug) error_log(__METHOD__."() importVCal($eventId) returned false");
|
||||||
|
}
|
||||||
|
header('ETag: '.$this->get_etag($eventId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1337,20 +1337,102 @@ class HTTP_WebDAV_Server
|
|||||||
$options = Array();
|
$options = Array();
|
||||||
$options['path'] = $this->path;
|
$options['path'] = $this->path;
|
||||||
|
|
||||||
if (!isset($options['mimetype'])) {
|
error_log('WebDAV POST: ' . $this->path);
|
||||||
$options['mimetype'] = "application/octet-stream";
|
|
||||||
}
|
|
||||||
header("Content-type: $options[mimetype]");
|
|
||||||
|
|
||||||
if (isset($options['mtime'])) {
|
if (isset($this->_SERVER['CONTENT_LENGTH']))
|
||||||
header("Last-modified:".gmdate("D, d M Y H:i:s ", $options['mtime'])."GMT");
|
{
|
||||||
|
$options['content_length'] = $this->_SERVER['CONTENT_LENGTH'];
|
||||||
|
}
|
||||||
|
elseif (isset($this->_SERVER['X-Expected-Entity-Length']))
|
||||||
|
{
|
||||||
|
// MacOS gives us that hint
|
||||||
|
$options['content_length'] = $this->_SERVER['X-Expected-Entity-Length'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($options['size'])) {
|
// get the Content-type
|
||||||
header("Content-length: ".$options['size']);
|
if (isset($this->_SERVER["CONTENT_TYPE"])) {
|
||||||
|
// for now we do not support any sort of multipart requests
|
||||||
|
if (!strncmp($this->_SERVER["CONTENT_TYPE"], 'multipart/', 10)) {
|
||||||
|
$this->http_status('501 not implemented');
|
||||||
|
echo 'The service does not support mulipart POST requests';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$options['content_type'] = $this->_SERVER['CONTENT_TYPE'];
|
||||||
|
} else {
|
||||||
|
// default content type if none given
|
||||||
|
$options['content_type'] = 'application/octet-stream';
|
||||||
}
|
}
|
||||||
|
|
||||||
$options["stream"] = fopen("php://input", "r");
|
/* RFC 2616 2.6 says: "The recipient of the entity MUST NOT
|
||||||
|
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 ($this->_SERVER as $key => $val) {
|
||||||
|
if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
|
||||||
|
switch ($key) {
|
||||||
|
case 'HTTP_CONTENT_ENCODING': // RFC 2616 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";
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_LANGUAGE': // RFC 2616 14.12
|
||||||
|
// we assume it is not critical if this one is ignored
|
||||||
|
// in the actual POST implementation ...
|
||||||
|
$options['content_language'] = $val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_LENGTH':
|
||||||
|
// defined on IIS and has the same value as CONTENT_LENGTH
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_LOCATION': // RFC 2616 14.14
|
||||||
|
/* The meaning of the Content-Location header in PUT
|
||||||
|
or POST requests is undefined; servers are free
|
||||||
|
to ignore it in those cases. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_RANGE': // RFC 2616 14.16
|
||||||
|
// single byte range requests are supported
|
||||||
|
// the header format is also specified in RFC 2616 14.16
|
||||||
|
// TODO we have to ensure that implementations support this or send 501 instead
|
||||||
|
if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $val, $matches)) {
|
||||||
|
$this->http_status('400 bad request');
|
||||||
|
echo 'The service does only support single byte ranges';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$range = array('start'=>$matches[1], 'end'=>$matches[2]);
|
||||||
|
if (is_numeric($matches[3])) {
|
||||||
|
$range['total_length'] = $matches[3];
|
||||||
|
}
|
||||||
|
$option['ranges'][] = $range;
|
||||||
|
|
||||||
|
// TODO make sure the implementation supports partial POST
|
||||||
|
// this has to be done in advance to avoid data being overwritten
|
||||||
|
// on implementations that do not support this ...
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_TYPE':
|
||||||
|
// defined on IIS and has the same value as CONTENT_TYPE
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'HTTP_CONTENT_MD5': // RFC 2616 14.15
|
||||||
|
// TODO: maybe we can just pretend here?
|
||||||
|
$this->http_status('501 not implemented');
|
||||||
|
echo 'The service does not support content MD5 checksum verification';
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// any other unknown Content-* headers
|
||||||
|
$this->http_status('501 not implemented');
|
||||||
|
echo "The service does not support '$key'";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$options['stream'] = fopen('php://input', 'r');
|
||||||
|
|
||||||
if (method_exists($this, 'POST')) {
|
if (method_exists($this, 'POST')) {
|
||||||
$status = $this->POST($options);
|
$status = $this->POST($options);
|
||||||
@ -1359,24 +1441,24 @@ class HTTP_WebDAV_Server
|
|||||||
$status = '400 Something went wrong';
|
$status = '400 Something went wrong';
|
||||||
} else if ($status === true) {
|
} else if ($status === true) {
|
||||||
$status = '200 OK';
|
$status = '200 OK';
|
||||||
} else if (is_resource($status) && get_resource_type($status) == "stream") {
|
} else if (is_resource($status) && get_resource_type($status) == 'stream') {
|
||||||
$stream = $status;
|
$stream = $status;
|
||||||
|
|
||||||
$status = empty($options["new"]) ? '200 OK' : '201 Created';
|
$status = empty($options['new']) ? '200 OK' : '201 Created';
|
||||||
|
|
||||||
if (!empty($options["ranges"])) {
|
if (!empty($options['ranges'])) {
|
||||||
// TODO multipart support is missing (see also above)
|
// TODO multipart support is missing (see also above)
|
||||||
if (0 == fseek($stream, $range[0]["start"], SEEK_SET)) {
|
if (0 == fseek($stream, $range[0]['start'], SEEK_SET)) {
|
||||||
$length = $range[0]["end"]-$range[0]["start"]+1;
|
$length = $range[0]['end']-$range[0]['start']+1;
|
||||||
if (!fwrite($stream, fread($options["stream"], $length))) {
|
if (!fwrite($stream, fread($options['stream'], $length))) {
|
||||||
$status = '403 Forbidden';
|
$status = '403 Forbidden';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$status = '403 Forbidden';
|
$status = '403 Forbidden';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (!feof($options["stream"])) {
|
while (!feof($options['stream'])) {
|
||||||
if (false === fwrite($stream, fread($options["stream"], 4096))) {
|
if (false === fwrite($stream, fread($options['stream'], 4096))) {
|
||||||
$status = '403 Forbidden';
|
$status = '403 Forbidden';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -264,6 +264,10 @@ class groupdav_principals extends groupdav_handler
|
|||||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$this->base_uri.'/calendar/'))),
|
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$this->base_uri.'/calendar/'))),
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address',$account['account_email']))),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address',$account['account_email']))),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'last-name',$account['account_lastname']),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'first-name',$account['account_firstname']),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'record-type','user'),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-type','INDIVIDUAL'),
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
||||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
||||||
HTTP_WebDAV_Server::mkprop('group-member-ship', $memberships),
|
HTTP_WebDAV_Server::mkprop('group-member-ship', $memberships),
|
||||||
@ -308,6 +312,8 @@ class groupdav_principals extends groupdav_handler
|
|||||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
||||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'record-type','group'),
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-type','GROUP'),
|
||||||
HTTP_WebDAV_Server::mkprop('group-member-set', $members),
|
HTTP_WebDAV_Server::mkprop('group-member-set', $members),
|
||||||
//HTTP_WebDAV_Server::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
//HTTP_WebDAV_Server::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user