Пример #1
0
    /**
     * Takes the deserialized AMF request and performs any operations.
     *
     * @todo   should implement and SPL observer pattern for custom AMF headers
     * @todo   DescribeService support
     * @param  Request\StreamRequest $request
     * @return Response\StreamResponse
     */
    protected function _handle(Request\StreamRequest $request)
    {
        // Get the object encoding of the request.
        $objectEncoding = $request->getObjectEncoding();

        // create a response object to place the output from the services.
        $response = $this->getResponse();

        // set response encoding
        $response->setObjectEncoding($objectEncoding);

        $responseBody = $request->getAmfBodies();

        $handleAuth = false;
        if ($this->_auth) {
            $headers = $request->getAmfHeaders();
            if (isset($headers[Constants::CREDENTIALS_HEADER]) &&
                isset($headers[Constants::CREDENTIALS_HEADER]->userid)) {
                $handleAuth = true;
            }
        }

        // Iterate through each of the service calls in the AMF request
        foreach($responseBody as $body)
        {
            try {
                if ($handleAuth) {
                    if ($this->_handleAuth(
                        $headers[Constants::CREDENTIALS_HEADER]->userid,
                        $headers[Constants::CREDENTIALS_HEADER]->password)) {
                        // use RequestPersistentHeader to clear credentials
                        $response->addAmfHeader(
                            new Value\MessageHeader(
                                Constants::PERSISTENT_HEADER,
                                false,
                                new Value\MessageHeader(
                                    Constants::CREDENTIALS_HEADER,
                                    false, null)));
                        $handleAuth = false;
                    }
                }

                if ($objectEncoding == Constants::AMF0_OBJECT_ENCODING) {
                    // AMF0 Object Encoding
                    $targetURI = $body->getTargetURI();
                    $message = '';

                    // Split the target string into its values.
                    $source = substr($targetURI, 0, strrpos($targetURI, '.'));

                    if ($source) {
                        // Break off method name from namespace into source
                        $method = substr(strrchr($targetURI, '.'), 1);
                        $return = $this->_dispatch($method, $body->getData(), $source);
                    } else {
                        // Just have a method name.
                        $return = $this->_dispatch($targetURI, $body->getData());
                    }
                } else {
                    // AMF3 read message type
                    $message = $body->getData();
                    if ($message instanceof Value\Messaging\CommandMessage) {
                        // async call with command message
                        $return = $this->_loadCommandMessage($message);
                    } elseif ($message instanceof Value\Messaging\RemotingMessage) {
                        $return = new Value\Messaging\AcknowledgeMessage($message);
                        $return->body = $this->_dispatch($message->operation, $message->body, $message->source);
                    } else {
                        // Amf3 message sent with netConnection
                        $targetURI = $body->getTargetURI();

                        // Split the target string into its values.
                        $source = substr($targetURI, 0, strrpos($targetURI, '.'));

                        if ($source) {
                            // Break off method name from namespace into source
                            $method = substr(strrchr($targetURI, '.'), 1);
                            $return = $this->_dispatch($method, $body->getData(), $source);
                        } else {
                            // Just have a method name.
                            $return = $this->_dispatch($targetURI, $body->getData());
                        }
                    }
                }
                $responseType = Constants::RESULT_METHOD;
            } catch (\Exception $e) {
                $return = $this->_errorMessage($objectEncoding, $message,
                    $e->getMessage(), $e->getTraceAsString(),$e->getCode(),  $e->getLine());
                $responseType = Constants::STATUS_METHOD;
            }

            $responseURI = $body->getResponseURI() . $responseType;
            $newBody     = new Value\MessageBody($responseURI, null, $return);
            $response->addAmfBody($newBody);
        }
        // Add a session header to the body if session is requested.
        if($this->isSession()) {
           $currentID = session_id();
           $joint = "?";
           if(isset($_SERVER['QUERY_STRING'])) {
               if(!strpos($_SERVER['QUERY_STRING'], $currentID) !== FALSE) {
                   if(strrpos($_SERVER['QUERY_STRING'], "?") !== FALSE) {
                       $joint = "&";
                   }
               }
           }

            // create a new AMF message header with the session id as a variable.
            $sessionValue = $joint . $this->_sessionName . "=" . $currentID;
            $sessionHeader = new Value\MessageHeader(Constants::URL_APPEND_HEADER, false, $sessionValue);
            $response->addAmfHeader($sessionHeader);
        }

        // serialize the response and return serialized body.
        $response->finalize();
    }