File indexing completed on 2024-05-12 06:02:16

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Amf
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /** @see Zend_Amf_Parse_InputStream */
0023 // require_once 'Zend/Amf/Parse/InputStream.php';
0024 
0025 /** @see Zend_Amf_Parse_Amf0_Deserializer */
0026 // require_once 'Zend/Amf/Parse/Amf0/Deserializer.php';
0027 
0028 /** @see Zend_Amf_Constants */
0029 // require_once 'Zend/Amf/Constants.php';
0030 
0031 /** @see Zend_Amf_Value_MessageHeader */
0032 // require_once 'Zend/Amf/Value/MessageHeader.php';
0033 
0034 /** @see Zend_Amf_Value_MessageBody */
0035 // require_once 'Zend/Amf/Value/MessageBody.php';
0036 
0037 /**
0038  * Handle the incoming AMF request by deserializing the data to php object
0039  * types and storing the data for Zend_Amf_Server to handle for processing.
0040  *
0041  * @todo       Currently not checking if the object needs to be Type Mapped to a server object.
0042  * @package    Zend_Amf
0043  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0044  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0045  */
0046 class Zend_Amf_Request
0047 {
0048     /**
0049      * @var int AMF client type (AMF0, AMF3)
0050      */
0051     protected $_clientType = 0; // default AMF0
0052 
0053     /**
0054      * @var array Message bodies
0055      */
0056     protected $_bodies = array();
0057 
0058     /**
0059      * @var array Message headers
0060      */
0061     protected $_headers = array();
0062 
0063     /**
0064      * @var int Message encoding to use for objects in response
0065      */
0066     protected $_objectEncoding = 0;
0067 
0068     /**
0069      * @var Zend_Amf_Parse_InputStream
0070      */
0071     protected $_inputStream;
0072 
0073     /**
0074      * @var Zend_Amf_Parse_AMF0_Deserializer
0075      */
0076     protected $_deserializer;
0077 
0078     /**
0079      * Time of the request
0080      * @var  mixed
0081      */
0082     protected $_time;
0083 
0084     /**
0085      * Prepare the AMF InputStream for parsing.
0086      *
0087      * @param  string $request
0088      * @return Zend_Amf_Request
0089      */
0090     public function initialize($request)
0091     {
0092         $this->_inputStream  = new Zend_Amf_Parse_InputStream($request);
0093         $this->_deserializer = new Zend_Amf_Parse_Amf0_Deserializer($this->_inputStream);
0094         $this->readMessage($this->_inputStream);
0095         return $this;
0096     }
0097 
0098     /**
0099      * Takes the raw AMF input stream and converts it into valid PHP objects
0100      *
0101      * @param  Zend_Amf_Parse_InputStream
0102      * @return Zend_Amf_Request
0103      */
0104     public function readMessage(Zend_Amf_Parse_InputStream $stream)
0105     {
0106         $clientVersion = $stream->readUnsignedShort();
0107         if (($clientVersion != Zend_Amf_Constants::AMF0_OBJECT_ENCODING)
0108             && ($clientVersion != Zend_Amf_Constants::AMF3_OBJECT_ENCODING)
0109             && ($clientVersion != Zend_Amf_Constants::FMS_OBJECT_ENCODING)
0110         ) {
0111             // require_once 'Zend/Amf/Exception.php';
0112             throw new Zend_Amf_Exception('Unknown Player Version ' . $clientVersion);
0113         }
0114 
0115         $this->_bodies  = array();
0116         $this->_headers = array();
0117         $headerCount    = $stream->readInt();
0118 
0119         // Iterate through the AMF envelope header
0120         while ($headerCount--) {
0121             $this->_headers[] = $this->readHeader();
0122         }
0123 
0124         // Iterate through the AMF envelope body
0125         $bodyCount = $stream->readInt();
0126         while ($bodyCount--) {
0127             $this->_bodies[] = $this->readBody();
0128         }
0129 
0130         return $this;
0131     }
0132 
0133     /**
0134      * Deserialize a message header from the input stream.
0135      *
0136      * A message header is structured as:
0137      * - NAME String
0138      * - MUST UNDERSTAND Boolean
0139      * - LENGTH Int
0140      * - DATA Object
0141      *
0142      * @return Zend_Amf_Value_MessageHeader
0143      */
0144     public function readHeader()
0145     {
0146         $name     = $this->_inputStream->readUTF();
0147         $mustRead = (bool)$this->_inputStream->readByte();
0148         $length   = $this->_inputStream->readLong();
0149 
0150         try {
0151             $data = $this->_deserializer->readTypeMarker();
0152         } catch (Exception $e) {
0153             // require_once 'Zend/Amf/Exception.php';
0154             throw new Zend_Amf_Exception('Unable to parse ' . $name . ' header data: ' . $e->getMessage() . ' '. $e->getLine(), 0, $e);
0155         }
0156 
0157         $header = new Zend_Amf_Value_MessageHeader($name, $mustRead, $data, $length);
0158         return $header;
0159     }
0160 
0161     /**
0162      * Deserialize a message body from the input stream
0163      *
0164      * @return Zend_Amf_Value_MessageBody
0165      */
0166     public function readBody()
0167     {
0168         $targetURI   = $this->_inputStream->readUTF();
0169         $responseURI = $this->_inputStream->readUTF();
0170         $length      = $this->_inputStream->readLong();
0171 
0172         try {
0173             $data = $this->_deserializer->readTypeMarker();
0174         } catch (Exception $e) {
0175             // require_once 'Zend/Amf/Exception.php';
0176             throw new Zend_Amf_Exception('Unable to parse ' . $targetURI . ' body data ' . $e->getMessage(), 0, $e);
0177         }
0178 
0179         // Check for AMF3 objectEncoding
0180         if ($this->_deserializer->getObjectEncoding() == Zend_Amf_Constants::AMF3_OBJECT_ENCODING) {
0181             /*
0182              * When and AMF3 message is sent to the server it is nested inside
0183              * an AMF0 array called Content. The following code gets the object
0184              * out of the content array and sets it as the message data.
0185              */
0186             if(is_array($data) && $data[0] instanceof Zend_Amf_Value_Messaging_AbstractMessage){
0187                 $data = $data[0];
0188             }
0189 
0190             // set the encoding so we return our message in AMF3
0191             $this->_objectEncoding = Zend_Amf_Constants::AMF3_OBJECT_ENCODING;
0192         }
0193 
0194         $body = new Zend_Amf_Value_MessageBody($targetURI, $responseURI, $data);
0195         return $body;
0196     }
0197 
0198     /**
0199      * Return an array of the body objects that were found in the amf request.
0200      *
0201      * @return array {target, response, length, content}
0202      */
0203     public function getAmfBodies()
0204     {
0205         return $this->_bodies;
0206     }
0207 
0208     /**
0209      * Accessor to private array of message bodies.
0210      *
0211      * @param  Zend_Amf_Value_MessageBody $message
0212      * @return Zend_Amf_Request
0213      */
0214     public function addAmfBody(Zend_Amf_Value_MessageBody $message)
0215     {
0216         $this->_bodies[] = $message;
0217         return $this;
0218     }
0219 
0220     /**
0221      * Return an array of headers that were found in the amf request.
0222      *
0223      * @return array {operation, mustUnderstand, length, param}
0224      */
0225     public function getAmfHeaders()
0226     {
0227         return $this->_headers;
0228     }
0229 
0230     /**
0231      * Return the either 0 or 3 for respect AMF version
0232      *
0233      * @return int
0234      */
0235     public function getObjectEncoding()
0236     {
0237         return $this->_objectEncoding;
0238     }
0239 
0240     /**
0241      * Set the object response encoding
0242      *
0243      * @param  mixed $int
0244      * @return Zend_Amf_Request
0245      */
0246     public function setObjectEncoding($int)
0247     {
0248         $this->_objectEncoding = $int;
0249         return $this;
0250     }
0251 }