147 lines
5.4 KiB
PHP
147 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace Yeepay\Yop\Sdk\Http;
|
|
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use GuzzleHttp\Exception\ServerException;
|
|
use GuzzleHttp\RequestOptions;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
use Yeepay\Yop\Sdk\Exception\YopClientException;
|
|
use Yeepay\Yop\Sdk\Internal\MultiPartFile;
|
|
use Yeepay\Yop\Sdk\Internal\Request;
|
|
use Yeepay\Yop\Sdk\Log\LogFactory;
|
|
use Yeepay\Yop\Sdk\Utils\Http\HttpUtils;
|
|
|
|
class YopHttpClient
|
|
{
|
|
|
|
/**
|
|
* @var ClientConfiguration
|
|
*/
|
|
private $clientConfiguration;
|
|
|
|
/**
|
|
* @var Client
|
|
*/
|
|
private $guzzleClient;
|
|
|
|
/**
|
|
* @var LoggerInterface
|
|
*/
|
|
private $logger;
|
|
|
|
/**
|
|
* YopHttpClient constructor.
|
|
*
|
|
* @param ClientConfiguration $clientConfiguration
|
|
*/
|
|
public function __construct(ClientConfiguration $clientConfiguration)
|
|
{
|
|
$this->logger = LogFactory::getLogger(get_class($this));
|
|
$this->clientConfiguration = $clientConfiguration;
|
|
$guzzleClientConfig = [
|
|
RequestOptions::CONNECT_TIMEOUT => $clientConfiguration->getConnectionTimeoutInMillis() / 1000,
|
|
RequestOptions::TIMEOUT, $clientConfiguration->getSocketTimeoutInMillis() / 1000,
|
|
];
|
|
if (! empty($clientConfiguration->getProxyUrl())) {
|
|
$guzzleClientConfig[RequestOptions::PROXY] = $clientConfiguration->getProxyUrl();
|
|
}
|
|
$this->guzzleClient = new Client($guzzleClientConfig);
|
|
}
|
|
|
|
/**
|
|
* @param Request $request
|
|
* @param ExecutionContext $executionContext
|
|
* @return YopHttpResponse
|
|
* @throws YopClientException
|
|
*/
|
|
public function execute(Request $request, ExecutionContext $executionContext)
|
|
{
|
|
$credentials = $executionContext->getCredentials();
|
|
$request->addHeader(Headers::YOP_APPKEY, $credentials->getAppKey());
|
|
$request->addHeader(Headers::USER_AGENT, $this->clientConfiguration->getUserAgent());
|
|
if ($executionContext->isNeedEncrypt()) {
|
|
$executionContext->getEncryptor()->encrypt($request);
|
|
}
|
|
$executionContext->getSigner()
|
|
->sign($request, $executionContext->getCredentials(), $executionContext->getSignOptions());
|
|
try {
|
|
\Log::channel('yeepay')->error('头部信息', $request->getHeaders());
|
|
|
|
$guzzleResponse = $this->sendRequest($request);
|
|
} catch (ServerException $e) {
|
|
$guzzleResponse = $e->getResponse();
|
|
} catch (\Throwable $e) {
|
|
throw new YopClientException("execute request failed:".$e->getMessage());
|
|
}
|
|
|
|
return new YopHttpResponse($guzzleResponse);
|
|
}
|
|
|
|
/**
|
|
* @param Request $request
|
|
* @return mixed|ResponseInterface
|
|
* @throws GuzzleException
|
|
* @throws YopClientException
|
|
*/
|
|
private function sendRequest(Request $request)
|
|
{
|
|
$uri = $request->getEndpoint().HttpUtils::urlEncodeExceptSlash($request->getResourcePath());
|
|
if (! empty($request->getMultipartFiles())) {
|
|
if ($request->getHttpMethod() == HttpMethod::POST) {
|
|
$body = [];
|
|
if (! empty($request->getParameters())) {
|
|
foreach ($request->getParameters() as $k => $v) {
|
|
if (! empty($v)) {
|
|
foreach ($v as $value) {
|
|
$body[] = ['name' => $k, 'contents' => $value];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($request->getMultipartFiles() as $k => $v) {
|
|
$part = ['name' => $k];
|
|
if (! empty($v)) {
|
|
foreach ($v as $value) {
|
|
/** @var MultiPartFile $value */
|
|
$part['contents'] = $value->getContent();
|
|
$part['filename'] = $value->getFileName();
|
|
$body[] = $part;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->guzzleClient->request($request->getHttpMethod(), $uri,
|
|
[
|
|
RequestOptions::MULTIPART => $body,
|
|
RequestOptions::HEADERS => $request->getHeaders(),
|
|
]);
|
|
} else {
|
|
throw new YopClientException("contentType:multipart/form-data only support post request.");
|
|
}
|
|
}
|
|
$requestIsPostOrPut = $request->getHttpMethod() == HttpMethod::POST || $request->getHttpMethod() == HttpMethod::PUT;
|
|
$requestHasPayload = ! empty($request->getContent());
|
|
$putParamsInUri = ! $requestIsPostOrPut || $requestHasPayload;
|
|
if ($putParamsInUri) {
|
|
$encodedParameters = \GuzzleHttp\Psr7\Query::build(HttpUtils::encodedParameters($request->getParameters()));
|
|
if (! empty($encodedParameters)) {
|
|
$uri = $uri.'?'.$encodedParameters;
|
|
}
|
|
}
|
|
$requestOptions = [RequestOptions::HEADERS => $request->getHeaders()];
|
|
if ($requestHasPayload) {
|
|
$requestOptions[RequestOptions::BODY] = $request->getContent();
|
|
} else {
|
|
if ($requestIsPostOrPut) {
|
|
$requestOptions[RequestOptions::BODY] = \GuzzleHttp\Psr7\Query::build(HttpUtils::encodedParameters($request->getParameters()));
|
|
}
|
|
}
|
|
|
|
return $this->guzzleClient->request($request->getHttpMethod(), $uri, $requestOptions);
|
|
}
|
|
|
|
}
|