Skip to content

Update Guzzle #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: MOODLE_311_STABLE
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 107 additions & 20 deletions guzzle/GuzzleHttp/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
namespace GuzzleHttp;

use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;

/**
* @method ResponseInterface get(string|UriInterface $uri, array $options = [])
Expand Down Expand Up @@ -46,9 +47,8 @@ class Client implements ClientInterface
* wire. The function is called with a Psr7\Http\Message\RequestInterface
* and array of transfer options, and must return a
* GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
* Psr7\Http\Message\ResponseInterface on success. "handler" is a
* constructor only option that cannot be overridden in per/request
* options. If no handler is provided, a default handler will be created
* Psr7\Http\Message\ResponseInterface on success.
* If no handler is provided, a default handler will be created
* that enables all of the request options below by attaching all of the
* default middleware to the handler.
* - base_uri: (string|UriInterface) Base URI of the client that is merged
Expand All @@ -75,6 +75,12 @@ public function __construct(array $config = [])
$this->configureDefaults($config);
}

/**
* @param string $method
* @param array $args
*
* @return Promise\PromiseInterface
*/
public function __call($method, $args)
{
if (count($args) < 1) {
Expand All @@ -89,6 +95,14 @@ public function __call($method, $args)
: $this->request($method, $uri, $opts);
}

/**
* Asynchronously send an HTTP request.
*
* @param array $options Request options to apply to the given
* request and to the transfer. See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
public function sendAsync(RequestInterface $request, array $options = [])
{
// Merge the base URI into the request URI if needed.
Expand All @@ -100,12 +114,35 @@ public function sendAsync(RequestInterface $request, array $options = [])
);
}

/**
* Send an HTTP request.
*
* @param array $options Request options to apply to the given
* request and to the transfer. See \GuzzleHttp\RequestOptions.
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function send(RequestInterface $request, array $options = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
return $this->sendAsync($request, $options)->wait();
}

/**
* Create and send an asynchronous HTTP request.
*
* Use an absolute path to override the base path of the client, or a
* relative path to append to the base path of the client. The URL can
* contain the query string as well. Use an array to provide a URL
* template and additional variables to use in the URL template expansion.
*
* @param string $method HTTP method
* @param string|UriInterface $uri URI object or string.
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
public function requestAsync($method, $uri = '', array $options = [])
{
$options = $this->prepareDefaults($options);
Expand All @@ -125,19 +162,49 @@ public function requestAsync($method, $uri = '', array $options = [])
return $this->transfer($request, $options);
}

/**
* Create and send an HTTP request.
*
* Use an absolute path to override the base path of the client, or a
* relative path to append to the base path of the client. The URL can
* contain the query string as well.
*
* @param string $method HTTP method.
* @param string|UriInterface $uri URI object or string.
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function request($method, $uri = '', array $options = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
return $this->requestAsync($method, $uri, $options)->wait();
}

/**
* Get a client configuration option.
*
* These options include default request options of the client, a "handler"
* (if utilized by the concrete client), and a "base_uri" if utilized by
* the concrete client.
*
* @param string|null $option The config option to retrieve.
*
* @return mixed
*/
public function getConfig($option = null)
{
return $option === null
? $this->config
: (isset($this->config[$option]) ? $this->config[$option] : null);
}

/**
* @param string|null $uri
*
* @return UriInterface
*/
private function buildUri($uri, array $config)
{
// for BC we accept null which would otherwise fail in uri_for
Expand All @@ -147,13 +214,19 @@ private function buildUri($uri, array $config)
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
}

if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
$idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
$uri = Utils::idnUriConvert($uri, $idnOptions);
}

return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
}

/**
* Configures the default options for a client.
*
* @param array $config
* @return void
*/
private function configureDefaults(array $config)
{
Expand All @@ -162,15 +235,16 @@ private function configureDefaults(array $config)
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
'cookies' => false,
'idn_conversion' => true,
];

// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.

// We can only trust the HTTP_PROXY environment variable in a CLI
// process due to the fact that PHP has no reliable mechanism to
// get environment variables that start with "HTTP_".
if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
$defaults['proxy']['http'] = getenv('HTTP_PROXY');
}

Expand Down Expand Up @@ -210,7 +284,7 @@ private function configureDefaults(array $config)
*
* @return array
*/
private function prepareDefaults($options)
private function prepareDefaults(array $options)
{
$defaults = $this->config;

Expand All @@ -225,7 +299,7 @@ private function prepareDefaults($options)
if (array_key_exists('headers', $options)) {
// Allows default headers to be unset.
if ($options['headers'] === null) {
$defaults['_conditional'] = null;
$defaults['_conditional'] = [];
unset($options['headers']);
} elseif (!is_array($options['headers'])) {
throw new \InvalidArgumentException('headers must be an array');
Expand All @@ -251,8 +325,7 @@ private function prepareDefaults($options)
* The URI of the request is not modified and the request options are used
* as-is without merging in default options.
*
* @param RequestInterface $request
* @param array $options
* @param array $options See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
Expand All @@ -271,6 +344,7 @@ private function transfer(RequestInterface $request, array $options)
}

$request = $this->applyOptions($request, $options);
/** @var HandlerStack $handler */
$handler = $options['handler'];

try {
Expand All @@ -290,7 +364,14 @@ private function transfer(RequestInterface $request, array $options)
*/
private function applyOptions(RequestInterface $request, array &$options)
{
$modify = [];
$modify = [
'set_headers' => [],
];

if (isset($options['headers'])) {
$modify['set_headers'] = $options['headers'];
unset($options['headers']);
}

if (isset($options['form_params'])) {
if (isset($options['multipart'])) {
Expand All @@ -302,6 +383,8 @@ private function applyOptions(RequestInterface $request, array &$options)
}
$options['body'] = http_build_query($options['form_params'], '', '&');
unset($options['form_params']);
// Ensure that we don't have the header in different case and set the new value.
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
$options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
}

Expand All @@ -313,24 +396,19 @@ private function applyOptions(RequestInterface $request, array &$options)
if (isset($options['json'])) {
$options['body'] = \GuzzleHttp\json_encode($options['json']);
unset($options['json']);
// Ensure that we don't have the header in different case and set the new value.
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
$options['_conditional']['Content-Type'] = 'application/json';
}

if (!empty($options['decode_content'])
&& $options['decode_content'] !== true
) {
// Ensure that we don't have the header in different case and set the new value.
$options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
$modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
}

if (isset($options['headers'])) {
if (isset($modify['set_headers'])) {
$modify['set_headers'] = $options['headers'] + $modify['set_headers'];
} else {
$modify['set_headers'] = $options['headers'];
}
unset($options['headers']);
}

if (isset($options['body'])) {
if (is_array($options['body'])) {
$this->invalidBody();
Expand All @@ -344,6 +422,8 @@ private function applyOptions(RequestInterface $request, array &$options)
$type = isset($value[2]) ? strtolower($value[2]) : 'basic';
switch ($type) {
case 'basic':
// Ensure that we don't have the header in different case and set the new value.
$modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
$modify['set_headers']['Authorization'] = 'Basic '
. base64_encode("$value[0]:$value[1]");
break;
Expand Down Expand Up @@ -382,6 +462,8 @@ private function applyOptions(RequestInterface $request, array &$options)
$request = Psr7\modify_request($request, $modify);
if ($request->getBody() instanceof Psr7\MultipartStream) {
// Use a multipart/form-data POST if a Content-Type is not set.
// Ensure that we don't have the header in different case and set the new value.
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
$options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
. $request->getBody()->getBoundary();
}
Expand All @@ -403,6 +485,11 @@ private function applyOptions(RequestInterface $request, array &$options)
return $request;
}

/**
* Throw Exception with pre-set message.
* @return void
* @throws \InvalidArgumentException Invalid body.
*/
private function invalidBody()
{
throw new \InvalidArgumentException('Passing in the "body" request '
Expand Down
7 changes: 5 additions & 2 deletions guzzle/GuzzleHttp/ClientInterface.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
namespace GuzzleHttp;

use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
Expand All @@ -12,7 +12,10 @@
*/
interface ClientInterface
{
const VERSION = '6.2.1';
/**
* @deprecated Will be removed in Guzzle 7.0.0
*/
const VERSION = '6.5.5';

/**
* Send an HTTP request.
Expand Down
17 changes: 12 additions & 5 deletions guzzle/GuzzleHttp/Cookie/CookieJar.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,17 @@ public static function shouldPersist(
*/
public function getCookieByName($name)
{
// don't allow a null name
if($name === null) {
// don't allow a non string name
if ($name === null || !is_scalar($name)) {
return null;
}
foreach($this->cookies as $cookie) {
if($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
foreach ($this->cookies as $cookie) {
if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
return $cookie;
}
}

return null;
}

public function toArray()
Expand All @@ -120,7 +122,7 @@ public function clear($domain = null, $path = null, $name = null)
} elseif (!$path) {
$this->cookies = array_filter(
$this->cookies,
function (SetCookie $cookie) use ($path, $domain) {
function (SetCookie $cookie) use ($domain) {
return !$cookie->matchesDomain($domain);
}
);
Expand Down Expand Up @@ -238,6 +240,11 @@ public function extractCookies(
if (0 !== strpos($sc->getPath(), '/')) {
$sc->setPath($this->getCookiePathFromRequest($request));
}
if (!$sc->matchesDomain($request->getUri()->getHost())) {
continue;
}
// Note: At this point `$sc->getDomain()` being a public suffix should
// be rejected, but we don't want to pull in the full PSL dependency.
$this->setCookie($sc);
}
}
Expand Down
6 changes: 3 additions & 3 deletions guzzle/GuzzleHttp/Cookie/CookieJarInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ public function setCookie(SetCookie $cookie);
* arguments, then the cookie with the specified name, path and domain is
* removed.
*
* @param string $domain Clears cookies matching a domain
* @param string $path Clears cookies matching a domain and path
* @param string $name Clears cookies matching a domain, path, and name
* @param string|null $domain Clears cookies matching a domain
* @param string|null $path Clears cookies matching a domain and path
* @param string|null $name Clears cookies matching a domain, path, and name
*
* @return CookieJarInterface
*/
Expand Down
3 changes: 2 additions & 1 deletion guzzle/GuzzleHttp/Cookie/FileCookieJar.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class FileCookieJar extends CookieJar
*/
public function __construct($cookieFile, $storeSessionCookies = false)
{
parent::__construct();
$this->filename = $cookieFile;
$this->storeSessionCookies = $storeSessionCookies;

Expand Down Expand Up @@ -56,7 +57,7 @@ public function save($filename)
}

$jsonStr = \GuzzleHttp\json_encode($json);
if (false === file_put_contents($filename, $jsonStr)) {
if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) {
throw new \RuntimeException("Unable to save file {$filename}");
}
}
Expand Down
Loading