* CalDAV/CardDAV: do NOT use Content-Length header, if zlib.output_compression is enabled, fixes problems with iOS7 eg. eTask app

Content-Length is size AFTER applying transfer encoding which compression is, as compression is done in PHP outside our control, we only set wrong (to big) size
This commit is contained in:
Ralf Becker 2013-11-20 14:14:19 +00:00
parent 0bec203626
commit 8cf762ea2d
2 changed files with 37 additions and 13 deletions

View File

@ -1181,6 +1181,30 @@ class HTTP_WebDAV_Server
// }}}
/**
* Check or set if we want ot use compression as transfer encoding
*
* If we use compression via zlib.output_compression as transfer encoding,
* we can NOT send Content-Length headers, as the have to reflect size
* AFTER applying compression/transfer encoding.
*
* @param boolean $set=null
* @return boolean true if we use compression, false otherwise
*/
public static function use_compression($set=null)
{
static $compression = null;
if (isset($set))
{
ini_set('zlib.output_compression', $compression=(boolean)$set);
}
elseif (!isset($compression))
{
$compression = (boolean)ini_get('zlib.output_compression');
}
//error_log(__METHOD__."(".array2string($set).") returning ".array2string($compression));
return $compression;
}
// {{{ http_GET()
@ -1210,7 +1234,7 @@ class HTTP_WebDAV_Server
// and anyway little sense with with other content like pictures
if (substr($options['mimetype'],0,5) != 'text/')
{
ini_set('zlib.output_compression',0);
self::use_compression(false);
}
header("Content-type: $options[mimetype]");
@ -1240,9 +1264,9 @@ class HTTP_WebDAV_Server
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]/"
$this->http_status("206 Partial content");
if (!self::use_compression()) header("Content-Length: $size");
header("Content-Range: bytes $range[start]-$range[end]/"
. (isset($options['size']) ? $options['size'] : "*"));
while ($size && !feof($options['stream'])) {
$buffer = fread($options['stream'], 4096);
@ -1252,14 +1276,14 @@ class HTTP_WebDAV_Server
} else {
$this->http_status("206 partial");
if (isset($options['size'])) {
header("Content-length: ".($options['size'] - $range['start']));
header("Content-range: ".$range['start']."-".$range['end']."/"
if (!self::use_compression()) header("Content-Length: ".($options['size'] - $range['start']));
header("Content-Range: bytes ".$range['start']."-".$range['end']."/"
. (isset($options['size']) ? $options['size'] : "*"));
}
fpassthru($options['stream']);
}
} else {
header("Content-length: ".$range['last']);
if (!self::use_compression()) header("Content-length: ".$range['last']);
fseek($options['stream'], -$range['last'], SEEK_END);
fpassthru($options['stream']);
}
@ -1290,8 +1314,8 @@ class HTTP_WebDAV_Server
}
} else {
// normal request or stream isn't seekable, return full content
if (isset($options['size'])) {
header("Content-length: ".$options['size']);
if (isset($options['size']) && !self::use_compression()) {
header("Content-Length: ".$options['size']);
}
fpassthru($options['stream']);
return; // no more headers
@ -1300,7 +1324,7 @@ class HTTP_WebDAV_Server
if (is_array($options['data'])) {
// reply to partial request
} else {
header("Content-length: ".$this->bytes($options['data']));
if (!self::use_compression()) header("Content-Length: ".$this->bytes($options['data']));
echo $options['data'];
}
}
@ -1424,7 +1448,7 @@ class HTTP_WebDAV_Server
}
if (isset($options['size'])) {
header("Content-length: ".$options['size']);
header("Content-Length: ".$options['size']);
}
if ($status === true) $status = "200 OK";
@ -2076,7 +2100,7 @@ class HTTP_WebDAV_Server
}
$content .= '</'.($this->crrnd?'':'D:')."error>\n";
}
header("Content-length: ".$this->bytes($content));
if (!self::use_compression()) header("Content-Length: ".$this->bytes($content));
if ($content) echo $options['content'];
}

View File

@ -348,7 +348,7 @@ abstract class groupdav_handler
if (($ret = $this->get($options, $id ? $id : $this->new_id, $user)) && !empty($options['data']))
{
header('Content-Length: '.$this->groupdav->bytes($options['data']));
if (!$this->groupdav->use_compression()) header('Content-Length: '.$this->groupdav->bytes($options['data']));
header('Content-Type: '.$options['mimetype']);
echo $options['data'];
}