scratch

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 86  →  ?path2? @ 87
/vendor/guzzlehttp/guzzle/src/Subscriber/Cookie.php
@@ -0,0 +1,59 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\CookieJarInterface;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
 
/**
* Adds, extracts, and persists cookies between HTTP requests
*/
class Cookie implements SubscriberInterface
{
/** @var CookieJarInterface */
private $cookieJar;
 
/**
* @param CookieJarInterface $cookieJar Cookie jar used to hold cookies
*/
public function __construct(CookieJarInterface $cookieJar = null)
{
$this->cookieJar = $cookieJar ?: new CookieJar();
}
 
public function getEvents()
{
// Fire the cookie plugin complete event before redirecting
return [
'before' => ['onBefore'],
'complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE + 10]
];
}
 
/**
* Get the cookie cookieJar
*
* @return CookieJarInterface
*/
public function getCookieJar()
{
return $this->cookieJar;
}
 
public function onBefore(BeforeEvent $event)
{
$this->cookieJar->addCookieHeader($event->getRequest());
}
 
public function onComplete(CompleteEvent $event)
{
$this->cookieJar->extractCookies(
$event->getRequest(),
$event->getResponse()
);
}
}
/vendor/guzzlehttp/guzzle/src/Subscriber/History.php
@@ -0,0 +1,142 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\ErrorEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Message\ResponseInterface;
 
/**
* Maintains a list of requests and responses sent using a request or client
*/
class History implements SubscriberInterface, \IteratorAggregate, \Countable
{
/** @var int The maximum number of requests to maintain in the history */
private $limit;
 
/** @var array Requests and responses that have passed through the plugin */
private $transactions = [];
 
public function __construct($limit = 10)
{
$this->limit = $limit;
}
 
public function getEvents()
{
return [
'complete' => ['onComplete', RequestEvents::EARLY],
'error' => ['onError', RequestEvents::EARLY],
];
}
 
/**
* Convert to a string that contains all request and response headers
*
* @return string
*/
public function __toString()
{
$lines = array();
foreach ($this->transactions as $entry) {
$response = isset($entry['response']) ? $entry['response'] : '';
$lines[] = '> ' . trim($entry['request']) . "\n\n< " . trim($response) . "\n";
}
 
return implode("\n", $lines);
}
 
public function onComplete(CompleteEvent $event)
{
$this->add($event->getRequest(), $event->getResponse());
}
 
public function onError(ErrorEvent $event)
{
// Only track when no response is present, meaning this didn't ever
// emit a complete event
if (!$event->getResponse()) {
$this->add($event->getRequest());
}
}
 
/**
* Returns an Iterator that yields associative array values where each
* associative array contains a 'request' and 'response' key.
*
* @return \Iterator
*/
public function getIterator()
{
return new \ArrayIterator($this->transactions);
}
 
/**
* Get all of the requests sent through the plugin
*
* @return RequestInterface[]
*/
public function getRequests()
{
return array_map(function ($t) {
return $t['request'];
}, $this->transactions);
}
 
/**
* Get the number of requests in the history
*
* @return int
*/
public function count()
{
return count($this->transactions);
}
 
/**
* Get the last request sent
*
* @return RequestInterface
*/
public function getLastRequest()
{
return end($this->transactions)['request'];
}
 
/**
* Get the last response in the history
*
* @return ResponseInterface|null
*/
public function getLastResponse()
{
return end($this->transactions)['response'];
}
 
/**
* Clears the history
*/
public function clear()
{
$this->transactions = array();
}
 
/**
* Add a request to the history
*
* @param RequestInterface $request Request to add
* @param ResponseInterface $response Response of the request
*/
private function add(
RequestInterface $request,
ResponseInterface $response = null
) {
$this->transactions[] = ['request' => $request, 'response' => $response];
if (count($this->transactions) > $this->limit) {
array_shift($this->transactions);
}
}
}
/vendor/guzzlehttp/guzzle/src/Subscriber/HttpError.php
@@ -0,0 +1,34 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Exception\RequestException;
 
/**
* Throws exceptions when a 4xx or 5xx response is received
*/
class HttpError implements SubscriberInterface
{
public function getEvents()
{
return ['complete' => ['onComplete', RequestEvents::VERIFY_RESPONSE]];
}
 
/**
* Throw a RequestException on an HTTP protocol error
*
* @param CompleteEvent $event Emitted event
* @throws RequestException
*/
public function onComplete(CompleteEvent $event)
{
$code = (string) $event->getResponse()->getStatusCode();
// Throw an exception for an unsuccessful response
if ($code[0] === '4' || $code[0] === '5') {
throw RequestException::create($event->getRequest(), $event->getResponse());
}
}
}
/vendor/guzzlehttp/guzzle/src/Subscriber/Mock.php
@@ -0,0 +1,143 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Adapter\Transaction;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\HeadersEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Message\MessageFactory;
use GuzzleHttp\Message\ResponseInterface;
 
/**
* Queues mock responses or exceptions and delivers mock responses or
* exceptions in a fifo order.
*/
class Mock implements SubscriberInterface, \Countable
{
/** @var array Array of mock responses / exceptions */
private $queue = [];
 
/** @var bool Whether or not to consume an entity body when mocking */
private $readBodies;
 
/** @var MessageFactory */
private $factory;
 
/**
* @param array $items Array of responses or exceptions to queue
* @param bool $readBodies Set to false to not consume the entity body of
* a request when a mock is served.
*/
public function __construct(array $items = [], $readBodies = true)
{
$this->factory = new MessageFactory();
$this->readBodies = $readBodies;
$this->addMultiple($items);
}
 
public function getEvents()
{
// Fire the event last, after signing
return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]];
}
 
/**
* @throws \OutOfBoundsException|\Exception
*/
public function onBefore(BeforeEvent $event)
{
if (!$item = array_shift($this->queue)) {
throw new \OutOfBoundsException('Mock queue is empty');
} elseif ($item instanceof RequestException) {
throw $item;
}
 
// Emulate the receiving of the response headers
$request = $event->getRequest();
$transaction = new Transaction($event->getClient(), $request);
$transaction->setResponse($item);
$request->getEmitter()->emit(
'headers',
new HeadersEvent($transaction)
);
 
// Emulate reading a response body
if ($this->readBodies && $request->getBody()) {
while (!$request->getBody()->eof()) {
$request->getBody()->read(8096);
}
}
 
$event->intercept($item);
}
 
public function count()
{
return count($this->queue);
}
 
/**
* Add a response to the end of the queue
*
* @param string|ResponseInterface $response Response or path to response file
*
* @return self
* @throws \InvalidArgumentException if a string or Response is not passed
*/
public function addResponse($response)
{
if (is_string($response)) {
$response = file_exists($response)
? $this->factory->fromMessage(file_get_contents($response))
: $this->factory->fromMessage($response);
} elseif (!($response instanceof ResponseInterface)) {
throw new \InvalidArgumentException('Response must a message '
. 'string, response object, or path to a file');
}
 
$this->queue[] = $response;
 
return $this;
}
 
/**
* Add an exception to the end of the queue
*
* @param RequestException $e Exception to throw when the request is executed
*
* @return self
*/
public function addException(RequestException $e)
{
$this->queue[] = $e;
 
return $this;
}
 
/**
* Add multiple items to the queue
*
* @param array $items Items to add
*/
public function addMultiple(array $items)
{
foreach ($items as $item) {
if ($item instanceof RequestException) {
$this->addException($item);
} else {
$this->addResponse($item);
}
}
}
 
/**
* Clear the queue
*/
public function clearQueue()
{
$this->queue = [];
}
}
/vendor/guzzlehttp/guzzle/src/Subscriber/Prepare.php
@@ -0,0 +1,136 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Mimetypes;
use GuzzleHttp\Post\PostBodyInterface;
use GuzzleHttp\Stream\MetadataStreamInterface;
use GuzzleHttp\Stream\StreamInterface;
 
/**
* Prepares requests with a body before sending
*
* **Request Options**
*
* - expect: Set to true to enable the "Expect: 100-Continue" header for a
* request that send a body. Set to false to disable "Expect: 100-Continue".
* Set to a number so that the size of the payload must be greater than the
* number in order to send the Expect header. Setting to a number will send
* the Expect header for all requests in which the size of the payload cannot
* be determined or where the body is not rewindable.
*/
class Prepare implements SubscriberInterface
{
public function getEvents()
{
return ['before' => ['onBefore', RequestEvents::PREPARE_REQUEST]];
}
 
public function onBefore(BeforeEvent $event)
{
$request = $event->getRequest();
 
// Set the appropriate Content-Type for a request if one is not set and
// there are form fields
if (!($body = $request->getBody())) {
return;
}
 
$this->addContentLength($request, $body);
 
if ($body instanceof PostBodyInterface) {
// Synchronize the POST body with the request's headers
$body->applyRequestHeaders($request);
} elseif (!$request->hasHeader('Content-Type')) {
$this->addContentType($request, $body);
}
 
$this->addExpectHeader($request, $body);
}
 
private function addContentType(
RequestInterface $request,
StreamInterface $body
) {
if (!($body instanceof MetadataStreamInterface)) {
return;
}
 
if (!($uri = $body->getMetadata('uri'))) {
return;
}
 
// Guess the content-type based on the stream's "uri" metadata value.
// The file extension is used to determine the appropriate mime-type.
if ($contentType = Mimetypes::getInstance()->fromFilename($uri)) {
$request->setHeader('Content-Type', $contentType);
}
}
 
private function addContentLength(
RequestInterface $request,
StreamInterface $body
) {
// Set the Content-Length header if it can be determined, and never
// send a Transfer-Encoding: chunked and Content-Length header in
// the same request.
if ($request->hasHeader('Content-Length')) {
// Remove transfer-encoding if content-length is set.
$request->removeHeader('Transfer-Encoding');
return;
}
 
if ($request->hasHeader('Transfer-Encoding')) {
return;
}
 
if (null !== ($size = $body->getSize())) {
$request->setHeader('Content-Length', $size)
->removeHeader('Transfer-Encoding');
} elseif ('1.1' == $request->getProtocolVersion()) {
// Use chunked Transfer-Encoding if there is no determinable
// content-length header and we're using HTTP/1.1.
$request->setHeader('Transfer-Encoding', 'chunked')
->removeHeader('Content-Length');
}
}
 
private function addExpectHeader(
RequestInterface $request,
StreamInterface $body
) {
// Determine if the Expect header should be used
if ($request->hasHeader('Expect')) {
return;
}
 
$expect = $request->getConfig()['expect'];
 
// Return if disabled or if you're not using HTTP/1.1
if ($expect === false || $request->getProtocolVersion() !== '1.1') {
return;
}
 
// The expect header is unconditionally enabled
if ($expect === true) {
$request->setHeader('Expect', '100-Continue');
return;
}
 
// By default, send the expect header when the payload is > 1mb
if ($expect === null) {
$expect = 1048576;
}
 
// Always add if the body cannot be rewound, the size cannot be
// determined, or the size is greater than the cutoff threshold
$size = $body->getSize();
if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
$request->setHeader('Expect', '100-Continue');
}
}
}
/vendor/guzzlehttp/guzzle/src/Subscriber/Redirect.php
@@ -0,0 +1,172 @@
<?php
 
namespace GuzzleHttp\Subscriber;
 
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Exception\CouldNotRewindStreamException;
use GuzzleHttp\Exception\TooManyRedirectsException;
use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Message\ResponseInterface;
use GuzzleHttp\Url;
 
/**
* Subscriber used to implement HTTP redirects.
*
* **Request options**
*
* - redirect: Associative array containing the 'max', 'strict', and 'referer'
* keys.
*
* - max: Maximum number of redirects allowed per-request
* - strict: You can use strict redirects by setting this value to ``true``.
* Strict redirects adhere to strict RFC compliant redirection (e.g.,
* redirect POST with POST) vs doing what most clients do (e.g., redirect
* POST request with a GET request).
* - referer: Set to true to automatically add the "Referer" header when a
* redirect request is sent.
*/
class Redirect implements SubscriberInterface
{
public function getEvents()
{
return ['complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE]];
}
 
/**
* Rewind the entity body of the request if needed
*
* @param RequestInterface $redirectRequest
* @throws CouldNotRewindStreamException
*/
public static function rewindEntityBody(RequestInterface $redirectRequest)
{
// Rewind the entity body of the request if needed
if ($redirectRequest->getBody()) {
$body = $redirectRequest->getBody();
// Only rewind the body if some of it has been read already, and
// throw an exception if the rewind fails
if ($body->tell() && !$body->seek(0)) {
throw new CouldNotRewindStreamException(
'Unable to rewind the non-seekable request body after redirecting',
$redirectRequest
);
}
}
}
 
/**
* Called when a request receives a redirect response
*
* @param CompleteEvent $event Event emitted
* @throws TooManyRedirectsException
*/
public function onComplete(CompleteEvent $event)
{
$response = $event->getResponse();
 
if (substr($response->getStatusCode(), 0, 1) != '3' ||
!$response->hasHeader('Location')
) {
return;
}
 
$redirectCount = 0;
$redirectRequest = $event->getRequest();
$redirectResponse = $response;
$max = $redirectRequest->getConfig()->getPath('redirect/max') ?: 5;
 
do {
if (++$redirectCount > $max) {
throw new TooManyRedirectsException(
"Will not follow more than {$redirectCount} redirects",
$redirectRequest
);
}
$redirectRequest = $this->createRedirectRequest($redirectRequest, $redirectResponse);
$redirectResponse = $event->getClient()->send($redirectRequest);
} while (substr($redirectResponse->getStatusCode(), 0, 1) == '3' &&
$redirectResponse->hasHeader('Location')
);
 
if ($redirectResponse !== $response) {
$event->intercept($redirectResponse);
}
}
 
/**
* Create a redirect request for a specific request object
*
* Takes into account strict RFC compliant redirection (e.g. redirect POST
* with POST) vs doing what most clients do (e.g. redirect POST with GET).
*
* @param RequestInterface $request
* @param ResponseInterface $response
*
* @return RequestInterface Returns a new redirect request
* @throws CouldNotRewindStreamException If the body cannot be rewound.
*/
private function createRedirectRequest(
RequestInterface $request,
ResponseInterface $response
) {
$config = $request->getConfig();
 
// Use a GET request if this is an entity enclosing request and we are
// not forcing RFC compliance, but rather emulating what all browsers
// would do. Be sure to disable redirects on the clone.
$redirectRequest = clone $request;
$redirectRequest->getEmitter()->detach($this);
$statusCode = $response->getStatusCode();
 
if ($statusCode == 303 ||
($statusCode <= 302 && $request->getBody() &&
!$config->getPath('redirect/strict'))
) {
$redirectRequest->setMethod('GET');
$redirectRequest->setBody(null);
}
 
$this->setRedirectUrl($redirectRequest, $response);
$this->rewindEntityBody($redirectRequest);
 
// Add the Referer header if it is told to do so and only
// add the header if we are not redirecting from https to http.
if ($config->getPath('redirect/referer') && (
$redirectRequest->getScheme() == 'https' ||
$redirectRequest->getScheme() == $request->getScheme()
)) {
$url = Url::fromString($request->getUrl());
$url->setUsername(null)->setPassword(null);
$redirectRequest->setHeader('Referer', (string) $url);
}
 
return $redirectRequest;
}
 
/**
* Set the appropriate URL on the request based on the location header
*
* @param RequestInterface $redirectRequest
* @param ResponseInterface $response
*/
private function setRedirectUrl(
RequestInterface $redirectRequest,
ResponseInterface $response
) {
$location = $response->getHeader('Location');
$location = Url::fromString($location);
 
// Combine location with the original URL if it is not absolute.
if (!$location->isAbsolute()) {
$originalUrl = Url::fromString($redirectRequest->getUrl());
// Remove query string parameters and just take what is present on
// the redirect Location header
$originalUrl->getQuery()->clear();
$location = $originalUrl->combine($location);
}
 
$redirectRequest->setUrl($location);
}
}