mirror of
https://github.com/nextcloud/server.git
synced 2026-02-23 18:05:02 -05:00
Merge pull request #39740 from nextcloud/backport/38613/stable27
[stable27] feat(HTTPClient): Provide wrapped access to Guzzle's asyncRequest()
This commit is contained in:
commit
c5da296d3c
10 changed files with 700 additions and 69 deletions
|
|
@ -45,35 +45,34 @@ class ClassLoader
|
|||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
|
|
@ -81,8 +80,7 @@ class ClassLoader
|
|||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
|
|
@ -90,21 +88,20 @@ class ClassLoader
|
|||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
|
|
@ -113,7 +110,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
|
|
@ -125,8 +122,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
|
|
@ -134,8 +130,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
|
|
@ -143,8 +138,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
|
|
@ -152,8 +146,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
|
|
@ -161,8 +154,7 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -179,24 +171,25 @@ class ClassLoader
|
|||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -205,19 +198,19 @@ class ClassLoader
|
|||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -226,9 +219,9 @@ class ClassLoader
|
|||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
|
|
@ -236,17 +229,18 @@ class ClassLoader
|
|||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
|
|
@ -256,18 +250,18 @@ class ClassLoader
|
|||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -276,8 +270,8 @@ class ClassLoader
|
|||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -294,8 +288,8 @@ class ClassLoader
|
|||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
|
|
@ -481,9 +475,9 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ return array(
|
|||
'OCP\\HintException' => $baseDir . '/lib/public/HintException.php',
|
||||
'OCP\\Http\\Client\\IClient' => $baseDir . '/lib/public/Http/Client/IClient.php',
|
||||
'OCP\\Http\\Client\\IClientService' => $baseDir . '/lib/public/Http/Client/IClientService.php',
|
||||
'OCP\\Http\\Client\\IPromise' => $baseDir . '/lib/public/Http/Client/IPromise.php',
|
||||
'OCP\\Http\\Client\\IResponse' => $baseDir . '/lib/public/Http/Client/IResponse.php',
|
||||
'OCP\\Http\\Client\\LocalServerException' => $baseDir . '/lib/public/Http/Client/LocalServerException.php',
|
||||
'OCP\\Http\\WellKnown\\GenericResponse' => $baseDir . '/lib/public/Http/WellKnown/GenericResponse.php',
|
||||
|
|
@ -1335,6 +1336,7 @@ return array(
|
|||
'OC\\Http\\Client\\Client' => $baseDir . '/lib/private/Http/Client/Client.php',
|
||||
'OC\\Http\\Client\\ClientService' => $baseDir . '/lib/private/Http/Client/ClientService.php',
|
||||
'OC\\Http\\Client\\DnsPinMiddleware' => $baseDir . '/lib/private/Http/Client/DnsPinMiddleware.php',
|
||||
'OC\\Http\\Client\\GuzzlePromiseAdapter' => $baseDir . '/lib/private/Http/Client/GuzzlePromiseAdapter.php',
|
||||
'OC\\Http\\Client\\NegativeDnsCache' => $baseDir . '/lib/private/Http/Client/NegativeDnsCache.php',
|
||||
'OC\\Http\\Client\\Response' => $baseDir . '/lib/private/Http/Client/Response.php',
|
||||
'OC\\Http\\CookieHelper' => $baseDir . '/lib/private/Http/CookieHelper.php',
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\HintException' => __DIR__ . '/../../..' . '/lib/public/HintException.php',
|
||||
'OCP\\Http\\Client\\IClient' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IClient.php',
|
||||
'OCP\\Http\\Client\\IClientService' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IClientService.php',
|
||||
'OCP\\Http\\Client\\IPromise' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IPromise.php',
|
||||
'OCP\\Http\\Client\\IResponse' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IResponse.php',
|
||||
'OCP\\Http\\Client\\LocalServerException' => __DIR__ . '/../../..' . '/lib/public/Http/Client/LocalServerException.php',
|
||||
'OCP\\Http\\WellKnown\\GenericResponse' => __DIR__ . '/../../..' . '/lib/public/Http/WellKnown/GenericResponse.php',
|
||||
|
|
@ -1368,6 +1369,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Http\\Client\\Client' => __DIR__ . '/../../..' . '/lib/private/Http/Client/Client.php',
|
||||
'OC\\Http\\Client\\ClientService' => __DIR__ . '/../../..' . '/lib/private/Http/Client/ClientService.php',
|
||||
'OC\\Http\\Client\\DnsPinMiddleware' => __DIR__ . '/../../..' . '/lib/private/Http/Client/DnsPinMiddleware.php',
|
||||
'OC\\Http\\Client\\GuzzlePromiseAdapter' => __DIR__ . '/../../..' . '/lib/private/Http/Client/GuzzlePromiseAdapter.php',
|
||||
'OC\\Http\\Client\\NegativeDnsCache' => __DIR__ . '/../../..' . '/lib/private/Http/Client/NegativeDnsCache.php',
|
||||
'OC\\Http\\Client\\Response' => __DIR__ . '/../../..' . '/lib/private/Http/Client/Response.php',
|
||||
'OC\\Http\\CookieHelper' => __DIR__ . '/../../..' . '/lib/private/Http/CookieHelper.php',
|
||||
|
|
|
|||
|
|
@ -34,13 +34,16 @@ declare(strict_types=1);
|
|||
namespace OC\Http\Client;
|
||||
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use OCP\Http\Client\IClient;
|
||||
use OCP\Http\Client\IPromise;
|
||||
use OCP\Http\Client\IResponse;
|
||||
use OCP\Http\Client\LocalServerException;
|
||||
use OCP\ICertificateManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\Security\IRemoteHostValidator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function parse_url;
|
||||
|
||||
/**
|
||||
|
|
@ -61,7 +64,8 @@ class Client implements IClient {
|
|||
IConfig $config,
|
||||
ICertificateManager $certificateManager,
|
||||
GuzzleClient $client,
|
||||
IRemoteHostValidator $remoteHostValidator
|
||||
IRemoteHostValidator $remoteHostValidator,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->client = $client;
|
||||
|
|
@ -205,7 +209,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -236,7 +240,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -271,7 +275,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -312,7 +316,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -347,7 +351,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -370,7 +374,7 @@ class Client implements IClient {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sends a options request
|
||||
* Sends an OPTIONS request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
|
|
@ -382,7 +386,7 @@ class Client implements IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -403,4 +407,215 @@ class Client implements IClient {
|
|||
$response = $this->client->request('options', $uri, $this->buildRequestOptions($options));
|
||||
return new Response($response);
|
||||
}
|
||||
|
||||
protected function wrapGuzzlePromise(PromiseInterface $promise): IPromise {
|
||||
return new GuzzlePromiseAdapter(
|
||||
$promise,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous GET request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'query' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function getAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
$response = $this->client->requestAsync('get', $uri, $this->buildRequestOptions($options));
|
||||
return $this->wrapGuzzlePromise($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous HEAD request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function headAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
$response = $this->client->requestAsync('head', $uri, $this->buildRequestOptions($options));
|
||||
return $this->wrapGuzzlePromise($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous POST request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function postAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
|
||||
if (isset($options['body']) && is_array($options['body'])) {
|
||||
$options['form_params'] = $options['body'];
|
||||
unset($options['body']);
|
||||
}
|
||||
|
||||
return $this->wrapGuzzlePromise($this->client->requestAsync('post', $uri, $this->buildRequestOptions($options)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous PUT request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function putAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
$response = $this->client->requestAsync('put', $uri, $this->buildRequestOptions($options));
|
||||
return $this->wrapGuzzlePromise($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous DELETE request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function deleteAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
$response = $this->client->requestAsync('delete', $uri, $this->buildRequestOptions($options));
|
||||
return $this->wrapGuzzlePromise($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asynchronous OPTIONS request
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* 'timeout' => 5,
|
||||
* @return IPromise
|
||||
*/
|
||||
public function optionsAsync(string $uri, array $options = []): IPromise {
|
||||
$this->preventLocalAddress($uri, $options);
|
||||
$response = $this->client->requestAsync('options', $uri, $this->buildRequestOptions($options));
|
||||
return $this->wrapGuzzlePromise($response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ use OCP\ICertificateManager;
|
|||
use OCP\IConfig;
|
||||
use OCP\Security\IRemoteHostValidator;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class ClientService
|
||||
|
|
@ -59,6 +60,7 @@ class ClientService implements IClientService {
|
|||
DnsPinMiddleware $dnsPinMiddleware,
|
||||
IRemoteHostValidator $remoteHostValidator,
|
||||
IEventLogger $eventLogger,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->certificateManager = $certificateManager;
|
||||
|
|
@ -87,6 +89,7 @@ class ClientService implements IClientService {
|
|||
$this->certificateManager,
|
||||
$client,
|
||||
$this->remoteHostValidator,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
139
lib/private/Http/Client/GuzzlePromiseAdapter.php
Normal file
139
lib/private/Http/Client/GuzzlePromiseAdapter.php
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Http\Client;
|
||||
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use LogicException;
|
||||
use OCP\Http\Client\IPromise;
|
||||
use OCP\Http\Client\IResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* A wrapper around Guzzle's PromiseInterface
|
||||
*
|
||||
* @see \GuzzleHttp\Promise\PromiseInterface
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class GuzzlePromiseAdapter implements IPromise {
|
||||
public function __construct(
|
||||
protected PromiseInterface $promise,
|
||||
protected LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends fulfillment and rejection handlers to the promise, and returns
|
||||
* a new promise resolving to the return value of the called handler.
|
||||
*
|
||||
* @param ?callable(IResponse): void $onFulfilled Invoked when the promise fulfills. Gets an \OCP\Http\Client\IResponse passed in as argument
|
||||
* @param ?callable(Exception): void $onRejected Invoked when the promise is rejected. Gets an \Exception passed in as argument
|
||||
*
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function then(
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null,
|
||||
): IPromise {
|
||||
if ($onFulfilled !== null) {
|
||||
$wrappedOnFulfilled = static function (ResponseInterface $response) use ($onFulfilled) {
|
||||
$onFulfilled(new Response($response));
|
||||
};
|
||||
} else {
|
||||
$wrappedOnFulfilled = null;
|
||||
}
|
||||
|
||||
if ($onRejected !== null) {
|
||||
$wrappedOnRejected = static function (RequestException $e) use ($onRejected) {
|
||||
$onRejected($e);
|
||||
};
|
||||
} else {
|
||||
$wrappedOnRejected = null;
|
||||
}
|
||||
|
||||
$this->promise->then($wrappedOnFulfilled, $wrappedOnRejected);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of the promise ("pending", "rejected", or "fulfilled").
|
||||
*
|
||||
* The three states can be checked against the constants defined:
|
||||
* STATE_PENDING, STATE_FULFILLED, and STATE_REJECTED.
|
||||
*
|
||||
* @return IPromise::STATE_*
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getState(): string {
|
||||
$state = $this->promise->getState();
|
||||
if ($state === PromiseInterface::FULFILLED) {
|
||||
return self::STATE_FULFILLED;
|
||||
}
|
||||
if ($state === PromiseInterface::REJECTED) {
|
||||
return self::STATE_REJECTED;
|
||||
}
|
||||
if ($state === PromiseInterface::PENDING) {
|
||||
return self::STATE_PENDING;
|
||||
}
|
||||
|
||||
$this->logger->error('Unexpected promise state "{state}" returned by Guzzle', [
|
||||
'state' => $state,
|
||||
]);
|
||||
return self::STATE_PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the promise if possible.
|
||||
*
|
||||
* @link https://github.com/promises-aplus/cancellation-spec/issues/7
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function cancel(): void {
|
||||
$this->promise->cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the promise completes if possible.
|
||||
*
|
||||
* Pass $unwrap as true to unwrap the result of the promise, either
|
||||
* returning the resolved value or throwing the rejected exception.
|
||||
*
|
||||
* If the promise cannot be waited on, then the promise will be rejected.
|
||||
*
|
||||
* @param bool $unwrap
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws LogicException if the promise has no wait function or if the
|
||||
* promise does not settle after waiting.
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function wait(bool $unwrap = true): mixed {
|
||||
return $this->promise->wait($unwrap);
|
||||
}
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -69,7 +69,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -99,7 +99,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -129,7 +129,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -159,7 +159,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -178,7 +178,7 @@ interface IClient {
|
|||
public function delete(string $uri, array $options = []): IResponse;
|
||||
|
||||
/**
|
||||
* Sends a options request
|
||||
* Sends an OPTIONS request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
|
|
@ -189,7 +189,7 @@ interface IClient {
|
|||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => ['
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
|
|
@ -206,4 +206,173 @@ interface IClient {
|
|||
* @since 8.1.0
|
||||
*/
|
||||
public function options(string $uri, array $options = []): IResponse;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous GET request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'query' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getAsync(string $uri, array $options = []): IPromise;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous HEAD request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function headAsync(string $uri, array $options = []): IPromise;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous POST request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function postAsync(string $uri, array $options = []): IPromise;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous PUT request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function putAsync(string $uri, array $options = []): IPromise;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous DELETE request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function deleteAsync(string $uri, array $options = []): IPromise;
|
||||
|
||||
/**
|
||||
* Sends an asynchronous OPTIONS request
|
||||
* @param string $uri
|
||||
* @param array $options Array such as
|
||||
* 'body' => [
|
||||
* 'field' => 'abc',
|
||||
* 'other_field' => '123',
|
||||
* 'file_name' => fopen('/path/to/file', 'r'),
|
||||
* ],
|
||||
* 'headers' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'cookies' => [
|
||||
* 'foo' => 'bar',
|
||||
* ],
|
||||
* 'allow_redirects' => [
|
||||
* 'max' => 10, // allow at most 10 redirects.
|
||||
* 'strict' => true, // use "strict" RFC compliant redirects.
|
||||
* 'referer' => true, // add a Referer header
|
||||
* 'protocols' => ['https'] // only allow https URLs
|
||||
* ],
|
||||
* 'sink' => '/path/to/file', // save to a file or a stream
|
||||
* 'verify' => true, // bool or string to CA file
|
||||
* 'debug' => true,
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function optionsAsync(string $uri, array $options = []): IPromise;
|
||||
}
|
||||
|
|
|
|||
100
lib/public/Http/Client/IPromise.php
Normal file
100
lib/public/Http/Client/IPromise.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\Http\Client;
|
||||
|
||||
use Exception;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* A wrapper around Guzzle's PromiseInterface
|
||||
* @see \GuzzleHttp\Promise\PromiseInterface
|
||||
* @since 28.0.0
|
||||
*/
|
||||
interface IPromise {
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public const STATE_PENDING = 'pending';
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public const STATE_FULFILLED = 'fulfilled';
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public const STATE_REJECTED = 'rejected';
|
||||
|
||||
/**
|
||||
* Appends fulfillment and rejection handlers to the promise, and returns
|
||||
* a new promise resolving to the return value of the called handler.
|
||||
*
|
||||
* @param ?callable(IResponse): void $onFulfilled Invoked when the promise fulfills. Gets an \OCP\Http\Client\IResponse passed in as argument
|
||||
* @param ?callable(Exception): void $onRejected Invoked when the promise is rejected. Gets an \Exception passed in as argument
|
||||
*
|
||||
* @return IPromise
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function then(
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null,
|
||||
): IPromise;
|
||||
|
||||
/**
|
||||
* Get the state of the promise ("pending", "rejected", or "fulfilled").
|
||||
*
|
||||
* The three states can be checked against the constants defined:
|
||||
* STATE_PENDING, STATE_FULFILLED, and STATE_REJECTED.
|
||||
*
|
||||
* @return self::STATE_*
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getState(): string;
|
||||
|
||||
/**
|
||||
* Cancels the promise if possible.
|
||||
*
|
||||
* @link https://github.com/promises-aplus/cancellation-spec/issues/7
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function cancel(): void;
|
||||
|
||||
/**
|
||||
* Waits until the promise completes if possible.
|
||||
*
|
||||
* Pass $unwrap as true to unwrap the result of the promise, either
|
||||
* returning the resolved value or throwing the rejected exception.
|
||||
*
|
||||
* If the promise cannot be waited on, then the promise will be rejected.
|
||||
*
|
||||
* @param bool $unwrap
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws LogicException if the promise has no wait function or if the
|
||||
* promise does not settle after waiting.
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function wait(bool $unwrap = true): mixed;
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ use OCP\ICertificateManager;
|
|||
use OCP\IConfig;
|
||||
use OCP\Security\IRemoteHostValidator;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class ClientServiceTest
|
||||
|
|
@ -41,13 +42,15 @@ class ClientServiceTest extends \Test\TestCase {
|
|||
});
|
||||
$remoteHostValidator = $this->createMock(IRemoteHostValidator::class);
|
||||
$eventLogger = $this->createMock(IEventLogger::class);
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
|
||||
$clientService = new ClientService(
|
||||
$config,
|
||||
$certificateManager,
|
||||
$dnsPinMiddleware,
|
||||
$remoteHostValidator,
|
||||
$eventLogger
|
||||
$eventLogger,
|
||||
$logger,
|
||||
);
|
||||
|
||||
$handler = new CurlHandler();
|
||||
|
|
@ -65,7 +68,8 @@ class ClientServiceTest extends \Test\TestCase {
|
|||
$config,
|
||||
$certificateManager,
|
||||
$guzzleClient,
|
||||
$remoteHostValidator
|
||||
$remoteHostValidator,
|
||||
$logger,
|
||||
),
|
||||
$clientService->newClient()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use OCP\ICertificateManager;
|
|||
use OCP\IConfig;
|
||||
use OCP\Security\IRemoteHostValidator;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function parse_url;
|
||||
|
||||
/**
|
||||
|
|
@ -44,11 +45,13 @@ class ClientTest extends \Test\TestCase {
|
|||
$this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class);
|
||||
$this->certificateManager = $this->createMock(ICertificateManager::class);
|
||||
$this->remoteHostValidator = $this->createMock(IRemoteHostValidator::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->client = new Client(
|
||||
$this->config,
|
||||
$this->certificateManager,
|
||||
$this->guzzleClient,
|
||||
$this->remoteHostValidator
|
||||
$this->remoteHostValidator,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue