/**
  * Send request to BCE.
  *
  * @param array $config
  * @param string $httpMethod The Http request method, uppercase.
  * @param string $path The resource path.
  * @param string|resource $body The Http request body.
  * @param array $headers The extra Http request headers.
  * @param array $params The extra Http url query strings.
  * @param SignerInterface $signer This function will generate authorization header.
  * @param resource|string $outputStream Write the Http response to this stream.
  *
  * @return \Guzzle\Http\Message\Response body and http_headers
  *
  * @throws BceClientException
  * @throws BceServiceException
  */
 public function sendRequest(array $config, $httpMethod, $path, $body, array $headers, array $params, SignerInterface $signer, $outputStream = null, $options = array())
 {
     $headers[HttpHeaders::USER_AGENT] = sprintf('bce-sdk-php/%s/%s/%s', Bce::SDK_VERSION, php_uname(), phpversion());
     if (!isset($headers[HttpHeaders::BCE_DATE])) {
         $now = new \DateTime();
         $now->setTimezone(DateUtils::$UTC_TIMEZONE);
         $headers[HttpHeaders::BCE_DATE] = DateUtils::formatAlternateIso8601Date($now);
     }
     list($hostUrl, $hostHeader) = HttpUtils::parseEndpointFromConfig($config);
     $headers[HttpHeaders::HOST] = $hostHeader;
     $url = $hostUrl . HttpUtils::urlEncodeExceptSlash($path);
     $queryString = HttpUtils::getCanonicalQueryString($params, false);
     if ($queryString !== '') {
         $url .= "?{$queryString}";
     }
     if (!isset($headers[HttpHeaders::CONTENT_LENGTH])) {
         $headers[HttpHeaders::CONTENT_LENGTH] = $this->guessContentLength($body);
     }
     $entityBody = null;
     if ($headers[HttpHeaders::CONTENT_LENGTH] == 0) {
         //if passing a stream and content length is 0, guzzle will remove
         //"Content-Length:0" from header, to work around this, we have to
         //set body to a empty string
         $entityBody = "";
     } else {
         if (is_resource($body)) {
             $offset = ftell($body);
             $original = EntityBody::factory($body);
             $entityBody = new ReadLimitEntityBody($original, $headers[HttpHeaders::CONTENT_LENGTH], $offset);
         } else {
             $entityBody = $body;
         }
     }
     $headers[HttpHeaders::AUTHORIZATION] = $signer->sign($config[BceClientConfigOptions::CREDENTIALS], $httpMethod, $path, $headers, $params, $options);
     if (LogFactory::isDebugEnabled()) {
         $this->logger->debug('HTTP method: ' . $httpMethod);
         $this->logger->debug('HTTP url: ' . $url);
         $this->logger->debug('HTTP headers: ' . print_r($headers, true));
     }
     $guzzleRequestOptions = array('exceptions' => false);
     if (isset($config[BceClientConfigOptions::CONNECTION_TIMEOUT_IN_MILLIS])) {
         $guzzleRequestOptions['connect_timeout'] = $config[BceClientConfigOptions::CONNECTION_TIMEOUT_IN_MILLIS] / 1000.0;
     }
     if (isset($config[BceClientConfigOptions::SOCKET_TIMEOUT_IN_MILLIS])) {
         $guzzleRequestOptions['timeout'] = $config[BceClientConfigOptions::SOCKET_TIMEOUT_IN_MILLIS] / 1000.0;
     }
     $guzzleRequest = $this->guzzleClient->createRequest($httpMethod, $url, $headers, $entityBody, $guzzleRequestOptions);
     if ($outputStream !== null) {
         $guzzleRequest->setResponseBody($outputStream);
     }
     // Send request
     try {
         $guzzleResponse = $this->guzzleClient->send($guzzleRequest);
     } catch (\Exception $e) {
         throw new BceClientException($e->getMessage());
     }
     if ($guzzleResponse->isInformational()) {
         throw new BceClientException('Can not handle 1xx Http status code');
     } elseif (!$guzzleResponse->isSuccessful()) {
         $requestId = $guzzleResponse->getHeader(HttpHeaders::BCE_REQUEST_ID);
         $message = $guzzleResponse->getReasonPhrase();
         $code = null;
         if ($guzzleResponse->isContentType('json')) {
             try {
                 $responseBody = $guzzleResponse->json();
                 if (isset($responseBody['message'])) {
                     $message = $responseBody['message'];
                 }
                 if (isset($responseBody['code'])) {
                     $code = $responseBody['code'];
                 }
             } catch (\Exception $e) {
                 // ignore this error
                 $this->logger->warning('Fail to parse error response body: ' . $e->getMessage());
             }
         }
         throw new BceServiceException($requestId, $code, $message, $guzzleResponse->getStatusCode());
     }
     if ($outputStream === null) {
         $body = $guzzleResponse->getBody(true);
     } else {
         $body = null;
         // detach the stream so that it will not be closed when the response
         // is garbage collected.
         $guzzleResponse->getBody()->detachStream();
     }
     return array('headers' => $this->parseHeaders($guzzleResponse), 'body' => $body);
 }
Exemple #2
0
 /**
  * Copy one object to another.
  *
  * @param string $sourceBucketName The source bucket name.
  * @param string $sourceKey The source object path.
  * @param string $targetBucketName The target bucket name.
  * @param string $targetKey The target object path.
  * @param mixed $options The optional bce configuration, which will overwrite the
  *   default configuration that was passed while creating BosClient instance.
  *
  * @return mixed
  */
 public function copyObject($sourceBucketName, $sourceKey, $targetBucketName, $targetKey, $options = array())
 {
     if (empty($sourceBucketName)) {
         throw new \InvalidArgumentException('$sourceBucketName should not be empty or null.');
     }
     if (empty($sourceKey)) {
         throw new \InvalidArgumentException('$sourceKey should not be empty or null.');
     }
     if (empty($targetBucketName)) {
         throw new \InvalidArgumentException('$targetBucketName should not be empty or null.');
     }
     if (empty($targetKey)) {
         throw new \InvalidArgumentException('$targetKey should not be empty or null.');
     }
     list($config, $userMetadata, $etag) = $this->parseOptions($options, BosOptions::CONFIG, BosOptions::USER_METADATA, BosOptions::ETAG);
     $headers = array();
     $headers[HttpHeaders::BCE_COPY_SOURCE] = HttpUtils::urlEncodeExceptSlash(sprintf("/%s/%s", $sourceBucketName, $sourceKey));
     if ($etag !== null) {
         $etag = trim($etag, '"');
         $headers[HttpHeaders::BCE_COPY_SOURCE_IF_MATCH] = '"' . $etag . '"';
     }
     if ($userMetadata === null) {
         $headers[HttpHeaders::BCE_COPY_METADATA_DIRECTIVE] = 'copy';
     } else {
         $headers[HttpHeaders::BCE_COPY_METADATA_DIRECTIVE] = 'replace';
         $this->populateRequestHeadersWithUserMetadata($headers, $userMetadata);
     }
     return $this->sendRequest(HttpMethod::PUT, array(BosOptions::CONFIG => $config, 'bucket_name' => $targetBucketName, 'key' => $targetKey, 'headers' => $headers));
 }
Exemple #3
0
 /**
  * @param $path string
  * @return string
  */
 private static function getCanonicalURIPath($path)
 {
     if (empty($path)) {
         return '/';
     } else {
         if ($path[0] == '/') {
             return HttpUtils::urlEncodeExceptSlash($path);
         } else {
             return '/' . HttpUtils::urlEncodeExceptSlash($path);
         }
     }
 }