Commit 1a357f14 authored by mku's avatar mku

ZP-150 #comment Inline images can not be downloaded with Windows Phone 7.5 or...

ZP-150 #comment Inline images can not be downloaded with Windows Phone 7.5 or Samsung Galaxy S2, added multipart request handling, new multipart prop for streamer vars, stat function for streams  #time 12h

git-svn-id: https://z-push.org/svn/z-push/trunk@1384 b7dd7b3b-3a3c-0410-9da9-bee62a6cc5b5
parent a6381c1e
......@@ -123,6 +123,19 @@ class MAPIStreamWrapper {
return ($this->position >= $this->streamlength);
}
/**
* Retrieves information about a stream
*
* @access public
* @return array
*/
public function stream_stat() {
return array(
7 => $this->streamlength,
'size' => $this->streamlength,
);
}
/**
* Instantiates a MAPIStreamWrapper
*
......
......@@ -112,6 +112,19 @@ class StringStreamWrapper {
return ($this->position >= $this->stringlength);
}
/**
* Retrieves information about a stream
*
* @access public
* @return array
*/
public function stream_stat() {
return array(
7 => $this->stringlength,
'size' => $this->stringlength,
);
}
/**
* Instantiates a StringStreamWrapper
*
......
......@@ -61,6 +61,7 @@ class Streamer implements Serializable {
const STREAMER_TYPE_NO_CONTAINER = 7;
const STREAMER_TYPE_COMMA_SEPARATED = 8;
const STREAMER_TYPE_SEMICOLON_SEPARATED = 9;
const STREAMER_TYPE_MULTIPART = 10;
protected $mapping;
public $flags;
......@@ -280,6 +281,14 @@ class Streamer implements Serializable {
continue;
}
if ($encoder->getMultipart() && isset($map[self::STREAMER_PROP]) && $map[self::STREAMER_PROP] == self::STREAMER_TYPE_MULTIPART) {
$encoder->addBodypartStream($this->$map[self::STREAMER_VAR]);
$encoder->startTag(SYNC_ITEMOPERATIONS_PART);
$encoder->content(count($encoder->getBodypartsCount()));
$encoder->endTag();
continue;
}
// Simple type
if(!isset($map[self::STREAMER_TYPE]) && strlen($this->$map[self::STREAMER_VAR]) == 0) {
// send empty tags
......
......@@ -94,6 +94,7 @@ class Request {
static private $longId; //TODO
static private $occurence; //TODO
static private $saveInSent;
static private $acceptMultipart;
/**
......@@ -163,8 +164,11 @@ class Request {
if (isset($query[self::COMMANDPARAM_ITEMID]))
self::$itemId = self::filterEvilInput($query[self::COMMANDPARAM_ITEMID], self::HEX_ONLY);
if (isset($query[self::COMMANDPARAM_OPTIONS]) && ($query[self::COMMANDPARAM_OPTIONS] & 1))
if (isset($query[self::COMMANDPARAM_OPTIONS]) && (ord($query[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_SAVEINSENT))
self::$saveInSent = true;
if (isset($query[self::COMMANDPARAM_OPTIONS]) && (ord($query[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_ACCEPTMULTIPART))
self::$acceptMultipart = true;
}
// in base64 encoded query string user is not necessarily set
......@@ -201,6 +205,11 @@ class Request {
if (isset(self::$asProtocolVersion))
self::$headers["ms-asprotocolversion"] = self::$asProtocolVersion;
}
if (!isset(self::$acceptMultipart) && isset(self::$headers["ms-asacceptmultipart"]) && strtoupper(self::$headers["ms-asacceptmultipart"]) == "T") {
self::$acceptMultipart = true;
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion));
}
......@@ -316,6 +325,19 @@ class Request {
return true;
}
/**
* Returns if the AcceptMultipart parameter of the querystring is set
*
* @access public
* @return boolean
*/
static public function GetGETAcceptMultipart() {
if (isset(self::$acceptMultipart))
return self::$acceptMultipart;
else
return false;
}
/**
* Returns the value of the AttachmentName parameter of the querystring
*
......
......@@ -110,7 +110,7 @@ abstract class RequestProcessor {
if (!ZPush::CommandNeedsPlainInput(Request::GetCommandCode()))
self::$decoder = new WBXMLDecoder(Request::GetInputStream());
self::$encoder = new WBXMLEncoder(Request::GetOutputStream());
self::$encoder = new WBXMLEncoder(Request::GetOutputStream(), Request::GetGETAcceptMultipart());
}
/**
......
......@@ -56,7 +56,8 @@ class SyncBaseBody extends SyncObject {
SYNC_AIRSYNCBASE_TYPE => array (self::STREAMER_VAR => "type"),
SYNC_AIRSYNCBASE_ESTIMATEDDATASIZE => array (self::STREAMER_VAR => "estimatedDataSize"),
SYNC_AIRSYNCBASE_TRUNCATED => array (self::STREAMER_VAR => "truncated"),
SYNC_AIRSYNCBASE_DATA => array (self::STREAMER_VAR => "data"), //TODO data should be of a type stream
SYNC_AIRSYNCBASE_DATA => array (self::STREAMER_VAR => "data",
self::STREAMER_PROP => self::STREAMER_TYPE_MULTIPART), //TODO data should be of a type stream
);
if(Request::GetProtocolVersion() >= 14.0) {
$mapping[SYNC_AIRSYNCBASE_PREVIEW] = array (self::STREAMER_VAR => "preview");
......
......@@ -52,7 +52,8 @@ class SyncItemOperationsAttachment extends SyncObject {
$mapping = array(
SYNC_AIRSYNCBASE_CONTENTTYPE => array ( self::STREAMER_VAR => "contenttype"),
SYNC_ITEMOPERATIONS_DATA => array ( self::STREAMER_VAR => "data",
self::STREAMER_TYPE => self::STREAMER_TYPE_STREAM),
self::STREAMER_TYPE => self::STREAMER_TYPE_STREAM,
self::STREAMER_PROP => self::STREAMER_TYPE_MULTIPART),
);
parent::SyncObject($mapping);
......
......@@ -59,7 +59,10 @@ class WBXMLEncoder extends WBXMLDefs {
private $_stack;
public function WBXMLEncoder($output) {
private $multipart; // the content is multipart
private $bodyparts;
public function WBXMLEncoder($output, $multipart = false) {
// make sure WBXML_DEBUG is defined. It should be at this point
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
......@@ -80,6 +83,8 @@ class WBXMLEncoder extends WBXMLDefs {
}
}
$this->_stack = array();
$this->multipart = $multipart;
$this->bodyparts = array();
}
/**
......@@ -89,7 +94,12 @@ class WBXMLEncoder extends WBXMLDefs {
* @return
*/
public function startWBXML() {
header("Content-Type: application/vnd.ms-sync.wbxml");
if ($this->multipart) {
header("Content-Type: application/vnd.ms-sync.multipart");
}
else {
header("Content-Type: application/vnd.ms-sync.wbxml");
}
$this->outByte(0x03); // WBXML 1.3
$this->outMBUInt(0x01); // Public ID 1
......@@ -138,6 +148,10 @@ class WBXMLEncoder extends WBXMLDefs {
// Only output end tags for items that have had a start tag sent
if($stackelem['sent']) {
$this->_endTag();
if(count($this->_stack) == 0 && $this->multipart == true) {
$this->processMultipart();
}
}
}
......@@ -160,6 +174,39 @@ class WBXMLEncoder extends WBXMLDefs {
$this->_content($content);
}
/**
* Gets the value of multipart
*
* @access public
* @return boolean
*/
public function getMultipart() {
return $this->multipart;
}
/**
* Adds a bodypart
*
* @param Stream $bp
*
* @access public
* @return void
*/
public function addBodypartStream($bp) {
if ($this->multipart)
$this->bodyparts[] = $bp;
}
/**
* Gets the number of bodyparts
*
* @access public
* @return int
*/
public function getBodypartsCount() {
return count($this->bodyparts);
}
/**----------------------------------------------------------------------------------------------------------
* Private WBXMLEncoder stuff
*/
......@@ -417,6 +464,38 @@ class WBXMLEncoder extends WBXMLDefs {
$spaces = str_repeat(" ", count($this->logStack));
ZLog::Write(LOGLEVEL_WBXML,"O " . $spaces . $content);
}
/**
* Processes the multipart response
*
* @access private
* @return void
*/
private function processMultipart() {
$len = ob_get_length();
$buffer = ob_get_clean();
$nrBodyparts = $this->getBodypartsCount();
$blockstart = (($nrBodyparts + 1) * 2) * 4 + 4;
$data = pack("iii", ($nrBodyparts + 1), $blockstart, $len);
ob_start(null, 1048576);
foreach ($this->bodyparts as $bp) {
$blockstart = $blockstart + $len;
$len = fstat($bp);
$len = (isset($len['size'])) ? $len['size'] : 0;
$data .= pack("ii", $blockstart, $len);
}
fwrite($this->_out, $data);
fwrite($this->_out, $buffer);
foreach($this->bodyparts as $bp) {
while (!feof($bp)) {
fwrite($this->_out, fread($bp, 4096));
}
}
}
}
?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment