2023-07-15 10:18:38 +08:00

452 lines
10 KiB
PHP
Executable File

<?php
namespace AlibabaCloud\Client\Request;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
use AlibabaCloud\Client\Encode;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Request\Traits\AcsTrait;
use AlibabaCloud\Client\Request\Traits\ClientTrait;
use AlibabaCloud\Client\Request\Traits\DeprecatedTrait;
use AlibabaCloud\Client\Request\Traits\RetryTrait;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Traits\ArrayAccessTrait;
use AlibabaCloud\Client\Traits\HttpTrait;
use AlibabaCloud\Client\Traits\ObjectAccessTrait;
use AlibabaCloud\Client\Traits\RegionTrait;
use ArrayAccess;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\MessageFormatter;
use GuzzleHttp\Middleware;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\Uri;
use Psr\Http\Message\ResponseInterface;
/**
* Class Request
*
* @package AlibabaCloud\Client\Request
*
* @method string stringToSign()
* @method string resolveParameter()
*/
abstract class Request implements ArrayAccess
{
use DeprecatedTrait;
use HttpTrait;
use RegionTrait;
use ClientTrait;
use AcsTrait;
use ArrayAccessTrait;
use ObjectAccessTrait;
use RetryTrait;
/**
* Request Connect Timeout
*/
const CONNECT_TIMEOUT = 5;
/**
* Request Timeout
*/
const TIMEOUT = 10;
/**
* @var string HTTP Method
*/
public $method = 'GET';
/**
* @var string
*/
public $format = 'JSON';
/**
* @var string HTTP Scheme
*/
protected $scheme = 'http';
/**
* @var string
*/
public $client;
/**
* @var Uri
*/
public $uri;
/**
* @var array The original parameters of the request.
*/
public $data = [];
/**
* @var array
*/
private $userAgent = [];
/**
* Request constructor.
*
* @param array $options
*
* @throws ClientException
*/
public function __construct(array $options = [])
{
$this->client = CredentialsProvider::getDefaultName();
$this->uri = new Uri();
$this->uri = $this->uri->withScheme($this->scheme);
$this->options['http_errors'] = false;
$this->options['connect_timeout'] = self::CONNECT_TIMEOUT;
$this->options['timeout'] = self::TIMEOUT;
// Turn on debug mode based on environment variable.
if (null !== \AlibabaCloud\Client\env('DEBUG') && strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
$this->options['debug'] = true;
}
// Rewrite configuration if the user has a configuration.
if ($options !== []) {
$this->options($options);
}
}
/**
* @param string $name
* @param string $value
*
* @return $this
* @throws ClientException
*/
public function appendUserAgent($name, $value)
{
$filter_name = Filter::name($name);
if (!UserAgent::isGuarded($filter_name)) {
$this->userAgent[$filter_name] = Filter::value($value);
}
return $this;
}
/**
* @param array $userAgent
*
* @return $this
*/
public function withUserAgent(array $userAgent)
{
$this->userAgent = UserAgent::clean($userAgent);
return $this;
}
/**
* Set Accept format.
*
* @param string $format
*
* @return $this
* @throws ClientException
*/
public function format($format)
{
$this->format = ApiFilter::format($format);
return $this;
}
/**
* @param $contentType
*
* @return $this
* @throws ClientException
*/
public function contentType($contentType)
{
$this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType);
return $this;
}
/**
* @param string $accept
*
* @return $this
* @throws ClientException
*/
public function accept($accept)
{
$this->options['headers']['Accept'] = HttpFilter::accept($accept);
return $this;
}
/**
* Set the request body.
*
* @param string $body
*
* @return $this
* @throws ClientException
*/
public function body($body)
{
$this->options['body'] = HttpFilter::body($body);
return $this;
}
/**
* Set the json as body.
*
* @param array|object $content
*
* @return $this
* @throws ClientException
*/
public function jsonBody($content)
{
if (!\is_array($content) && !\is_object($content)) {
throw new ClientException(
'jsonBody only accepts an array or object',
SDK::INVALID_ARGUMENT
);
}
return $this->body(\json_encode($content));
}
/**
* Set the request scheme.
*
* @param string $scheme
*
* @return $this
* @throws ClientException
*/
public function scheme($scheme)
{
$this->scheme = HttpFilter::scheme($scheme);
$this->uri = $this->uri->withScheme($scheme);
return $this;
}
/**
* Set the request host.
*
* @param string $host
*
* @return $this
* @throws ClientException
*/
public function host($host)
{
$this->uri = $this->uri->withHost(HttpFilter::host($host));
return $this;
}
/**
* @param string $method
*
* @return $this
* @throws ClientException
*/
public function method($method)
{
$this->method = HttpFilter::method($method);
return $this;
}
/**
* @param string $clientName
*
* @return $this
* @throws ClientException
*/
public function client($clientName)
{
$this->client = ClientFilter::clientName($clientName);
return $this;
}
/**
* @return bool
* @throws ClientException
*/
public function isDebug()
{
if (isset($this->options['debug'])) {
return $this->options['debug'] === true;
}
if (isset($this->httpClient()->options['debug'])) {
return $this->httpClient()->options['debug'] === true;
}
return false;
}
/**
* @throws ClientException
* @throws ServerException
*/
public function resolveOption()
{
$this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent);
$this->cleanQuery();
$this->cleanFormParams();
$this->resolveHost();
$this->resolveParameter();
if (isset($this->options['form_params'])) {
if (function_exists('\GuzzleHttp\Psr7\parse_query')) {
$this->options['form_params'] = \GuzzleHttp\Psr7\parse_query(
Encode::create($this->options['form_params'])->toString()
);
} else {
$this->options['form_params'] = \GuzzleHttp\Psr7\Query::parse(
Encode::create($this->options['form_params'])->toString()
);
}
}
$this->mergeOptionsIntoClient();
}
/**
* @return Result
* @throws ClientException
* @throws ServerException
*/
public function request()
{
$this->resolveOption();
$result = $this->response();
if ($this->shouldServerRetry($result)) {
return $this->request();
}
if (!$result->isSuccess()) {
throw new ServerException($result);
}
return $result;
}
/***
* @return PromiseInterface
* @throws Exception
*/
public function requestAsync()
{
$this->resolveOption();
return self::createClient($this)->requestAsync(
$this->method,
(string)$this->uri,
$this->options
);
}
/**
* @param Request $request
*
* @return Client
* @throws Exception
*/
public static function createClient(Request $request = null)
{
if (AlibabaCloud::hasMock()) {
$stack = HandlerStack::create(AlibabaCloud::getMock());
} else {
$stack = HandlerStack::create();
}
if (AlibabaCloud::isRememberHistory()) {
$stack->push(Middleware::history(AlibabaCloud::referenceHistory()));
}
if (AlibabaCloud::getLogger()) {
$stack->push(Middleware::log(
AlibabaCloud::getLogger(),
new MessageFormatter(AlibabaCloud::getLogFormat())
));
}
$stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) {
return new Result($response, $request);
}));
self::$config['handler'] = $stack;
return new Client(self::$config);
}
/**
* @throws ClientException
* @throws Exception
*/
private function response()
{
try {
return self::createClient($this)->request(
$this->method,
(string)$this->uri,
$this->options
);
} catch (GuzzleException $exception) {
if ($this->shouldClientRetry($exception)) {
return $this->response();
}
throw new ClientException(
$exception->getMessage(),
SDK::SERVER_UNREACHABLE,
$exception
);
}
}
/**
* Remove redundant Query
*
* @codeCoverageIgnore
*/
private function cleanQuery()
{
if (isset($this->options['query']) && $this->options['query'] === []) {
unset($this->options['query']);
}
}
/**
* Remove redundant Headers
*
* @codeCoverageIgnore
*/
private function cleanFormParams()
{
if (isset($this->options['form_params']) && $this->options['form_params'] === []) {
unset($this->options['form_params']);
}
}
}