示例#1
0
    /**
     * Performs a HTTP request using the specified method
     *
     * @param string $method The HTTP method for the request - 'GET', 'POST',
     *                       'PUT', 'DELETE'
     * @param string $uri The URL to which this request is being performed
     * @param array $headers An associative array of HTTP headers
     *                       for this request
     * @param string $body The body of the HTTP request
     * @param string $contentType The value for the content type
     *                                of the request body
     * @param int $remainingRedirects Number of redirects to follow if request
     *                              s results in one
     * @return \Zend\Http\Response The response object
     */
    public function performHttpRequest($method, $uri, $headers = null,
        $body = null, $contentType = null, $remainingRedirects = null)
    {
        if ($remainingRedirects === null) {
            $remainingRedirects = self::getMaxRedirects();
        }
        if ($headers === null) {
            $headers = array();
        }

        // Append a Gdata version header if protocol v2 or higher is in use.
        // (Protocol v1 does not use this header.)
        $major = $this->getMajorProtocolVersion();
        $minor = $this->getMinorProtocolVersion();
        if ($major >= 2) {
            $headers['GData-Version'] = $major +
                    (($minor === null) ? '.' + $minor : '');
        }

        // check the overridden method
        if (($method == 'POST' || $method == 'PUT') && $body === null &&
            $headers['x-http-method-override'] != 'DELETE') {
                throw new App\InvalidArgumentException(
                        'You must specify the data to post as either a ' .
                        'string or a child of Zend\GData\App\Entry');
        }
        if ($uri === null) {
            throw new App\InvalidArgumentException(
                'You must specify an URI to which to post.');
        }
        //$headers['Content-Type'] = $contentType;
        if (self::getGzipEnabled()) {
            // some services require the word 'gzip' to be in the user-agent
            // header in addition to the accept-encoding header
            if (strpos($this->_httpClient->headers()->get('User-Agent'),
                'gzip') === false) {
                $headers['User-Agent'] =
                    $this->_httpClient->headers()->get('User-Agent') . ' (gzip)';
            }
            $headers['Accept-encoding'] = 'gzip, deflate';
        } else {
            $headers['Accept-encoding'] = 'identity';
        }

        // Make sure the HTTP client object is 'clean' before making a request
        // In addition to standard headers to reset via resetParameters(),
        // also reset the Slug and If-Match headers
        $this->_httpClient->resetParameters();
        $this->_httpClient->setHeaders(array('Slug' => 'If-Match'));

        // Set the params for the new request to be performed
        $this->_httpClient->setHeaders($headers);
        $uriObj = Uri\UriFactory::factory($uri);
        preg_match("/^(.*?)(\?.*)?$/", $uri, $matches);
        $this->_httpClient->setUri($matches[1]);
        $queryArray = $uriObj->getQueryAsArray();
        $this->_httpClient->setParameterGet($queryArray);


        $this->_httpClient->setOptions(array('maxredirects' => 0));

        // Set the proper adapter if we are handling a streaming upload
        $usingMimeStream = false;
        $oldHttpAdapter = null;

        if ($body instanceof \Zend\GData\MediaMimeStream) {
            $usingMimeStream = true;
            $this->_httpClient->setRawDataStream($body, $contentType);
            $oldHttpAdapter = $this->_httpClient->getAdapter();

            if ($oldHttpAdapter instanceof \Zend\Http\Client\Adapter\Proxy) {
                $newAdapter = new HttpAdapterStreamingProxy();
            } else {
                $newAdapter = new HttpAdapterStreamingSocket();
            }
            $this->_httpClient->setAdapter($newAdapter);
        } else {
            $this->_httpClient->setRawBody($body);
        }

        try {
            $this->_httpClient->setMethod($method);
            $response = $this->_httpClient->send();
            // reset adapter
            if ($usingMimeStream) {
                $this->_httpClient->setAdapter($oldHttpAdapter);
            }
        } catch (\Zend\Http\Client\Exception\ExceptionInterface $e) {
            // reset adapter
            if ($usingMimeStream) {
                $this->_httpClient->setAdapter($oldHttpAdapter);
            }
            throw new App\HttpException($e->getMessage(), $e);
        }
        if ($response->isRedirect() && $response->getStatusCode() != '304') {
            if ($remainingRedirects > 0) {
                $newUrl = $response->headers()->get('Location');
                $response = $this->performHttpRequest(
                    $method, $newUrl, $headers, $body,
                    $contentType, $remainingRedirects);
            } else {
                throw new App\HttpException(
                        'Number of redirects exceeds maximum', null, $response);
            }
        }
        if (!$response->isSuccess()) {
            $exceptionMessage = 'Expected response code 200, got ' .
                $response->getStatusCode();
            if (self::getVerboseExceptionMessages()) {
                $exceptionMessage .= "\n" . $response->getBody();
            }
            $exception = new App\HttpException($exceptionMessage);
            $exception->setResponse($response);
            throw $exception;
        }

        //Apply defaults in case of later requests.
        $this->applyDefaults();

        return $response;
    }