annotate vendor/guzzlehttp/guzzle/src/Middleware.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 5fb285c0d0e3
children
rev   line source
Chris@0 1 <?php
Chris@0 2 namespace GuzzleHttp;
Chris@0 3
Chris@0 4 use GuzzleHttp\Cookie\CookieJarInterface;
Chris@0 5 use GuzzleHttp\Exception\RequestException;
Chris@0 6 use GuzzleHttp\Promise\RejectedPromise;
Chris@0 7 use GuzzleHttp\Psr7;
Chris@0 8 use Psr\Http\Message\ResponseInterface;
Chris@0 9 use Psr\Log\LoggerInterface;
Chris@0 10 use Psr\Log\LogLevel;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * Functions used to create and wrap handlers with handler middleware.
Chris@0 14 */
Chris@0 15 final class Middleware
Chris@0 16 {
Chris@0 17 /**
Chris@0 18 * Middleware that adds cookies to requests.
Chris@0 19 *
Chris@0 20 * The options array must be set to a CookieJarInterface in order to use
Chris@0 21 * cookies. This is typically handled for you by a client.
Chris@0 22 *
Chris@0 23 * @return callable Returns a function that accepts the next handler.
Chris@0 24 */
Chris@0 25 public static function cookies()
Chris@0 26 {
Chris@0 27 return function (callable $handler) {
Chris@0 28 return function ($request, array $options) use ($handler) {
Chris@0 29 if (empty($options['cookies'])) {
Chris@0 30 return $handler($request, $options);
Chris@0 31 } elseif (!($options['cookies'] instanceof CookieJarInterface)) {
Chris@0 32 throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
Chris@0 33 }
Chris@0 34 $cookieJar = $options['cookies'];
Chris@0 35 $request = $cookieJar->withCookieHeader($request);
Chris@0 36 return $handler($request, $options)
Chris@13 37 ->then(
Chris@13 38 function ($response) use ($cookieJar, $request) {
Chris@13 39 $cookieJar->extractCookies($request, $response);
Chris@13 40 return $response;
Chris@13 41 }
Chris@0 42 );
Chris@0 43 };
Chris@0 44 };
Chris@0 45 }
Chris@0 46
Chris@0 47 /**
Chris@0 48 * Middleware that throws exceptions for 4xx or 5xx responses when the
Chris@0 49 * "http_error" request option is set to true.
Chris@0 50 *
Chris@0 51 * @return callable Returns a function that accepts the next handler.
Chris@0 52 */
Chris@0 53 public static function httpErrors()
Chris@0 54 {
Chris@0 55 return function (callable $handler) {
Chris@0 56 return function ($request, array $options) use ($handler) {
Chris@0 57 if (empty($options['http_errors'])) {
Chris@0 58 return $handler($request, $options);
Chris@0 59 }
Chris@0 60 return $handler($request, $options)->then(
Chris@0 61 function (ResponseInterface $response) use ($request, $handler) {
Chris@0 62 $code = $response->getStatusCode();
Chris@0 63 if ($code < 400) {
Chris@0 64 return $response;
Chris@0 65 }
Chris@0 66 throw RequestException::create($request, $response);
Chris@0 67 }
Chris@0 68 );
Chris@0 69 };
Chris@0 70 };
Chris@0 71 }
Chris@0 72
Chris@0 73 /**
Chris@0 74 * Middleware that pushes history data to an ArrayAccess container.
Chris@0 75 *
Chris@13 76 * @param array|\ArrayAccess $container Container to hold the history (by reference).
Chris@0 77 *
Chris@0 78 * @return callable Returns a function that accepts the next handler.
Chris@0 79 * @throws \InvalidArgumentException if container is not an array or ArrayAccess.
Chris@0 80 */
Chris@0 81 public static function history(&$container)
Chris@0 82 {
Chris@0 83 if (!is_array($container) && !$container instanceof \ArrayAccess) {
Chris@0 84 throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
Chris@0 85 }
Chris@0 86
Chris@0 87 return function (callable $handler) use (&$container) {
Chris@0 88 return function ($request, array $options) use ($handler, &$container) {
Chris@0 89 return $handler($request, $options)->then(
Chris@0 90 function ($value) use ($request, &$container, $options) {
Chris@0 91 $container[] = [
Chris@0 92 'request' => $request,
Chris@0 93 'response' => $value,
Chris@0 94 'error' => null,
Chris@0 95 'options' => $options
Chris@0 96 ];
Chris@0 97 return $value;
Chris@0 98 },
Chris@0 99 function ($reason) use ($request, &$container, $options) {
Chris@0 100 $container[] = [
Chris@0 101 'request' => $request,
Chris@0 102 'response' => null,
Chris@0 103 'error' => $reason,
Chris@0 104 'options' => $options
Chris@0 105 ];
Chris@0 106 return \GuzzleHttp\Promise\rejection_for($reason);
Chris@0 107 }
Chris@0 108 );
Chris@0 109 };
Chris@0 110 };
Chris@0 111 }
Chris@0 112
Chris@0 113 /**
Chris@0 114 * Middleware that invokes a callback before and after sending a request.
Chris@0 115 *
Chris@0 116 * The provided listener cannot modify or alter the response. It simply
Chris@0 117 * "taps" into the chain to be notified before returning the promise. The
Chris@0 118 * before listener accepts a request and options array, and the after
Chris@0 119 * listener accepts a request, options array, and response promise.
Chris@0 120 *
Chris@0 121 * @param callable $before Function to invoke before forwarding the request.
Chris@0 122 * @param callable $after Function invoked after forwarding.
Chris@0 123 *
Chris@0 124 * @return callable Returns a function that accepts the next handler.
Chris@0 125 */
Chris@0 126 public static function tap(callable $before = null, callable $after = null)
Chris@0 127 {
Chris@0 128 return function (callable $handler) use ($before, $after) {
Chris@0 129 return function ($request, array $options) use ($handler, $before, $after) {
Chris@0 130 if ($before) {
Chris@0 131 $before($request, $options);
Chris@0 132 }
Chris@0 133 $response = $handler($request, $options);
Chris@0 134 if ($after) {
Chris@0 135 $after($request, $options, $response);
Chris@0 136 }
Chris@0 137 return $response;
Chris@0 138 };
Chris@0 139 };
Chris@0 140 }
Chris@0 141
Chris@0 142 /**
Chris@0 143 * Middleware that handles request redirects.
Chris@0 144 *
Chris@0 145 * @return callable Returns a function that accepts the next handler.
Chris@0 146 */
Chris@0 147 public static function redirect()
Chris@0 148 {
Chris@0 149 return function (callable $handler) {
Chris@0 150 return new RedirectMiddleware($handler);
Chris@0 151 };
Chris@0 152 }
Chris@0 153
Chris@0 154 /**
Chris@0 155 * Middleware that retries requests based on the boolean result of
Chris@0 156 * invoking the provided "decider" function.
Chris@0 157 *
Chris@0 158 * If no delay function is provided, a simple implementation of exponential
Chris@0 159 * backoff will be utilized.
Chris@0 160 *
Chris@0 161 * @param callable $decider Function that accepts the number of retries,
Chris@0 162 * a request, [response], and [exception] and
Chris@0 163 * returns true if the request is to be retried.
Chris@0 164 * @param callable $delay Function that accepts the number of retries and
Chris@0 165 * returns the number of milliseconds to delay.
Chris@0 166 *
Chris@0 167 * @return callable Returns a function that accepts the next handler.
Chris@0 168 */
Chris@0 169 public static function retry(callable $decider, callable $delay = null)
Chris@0 170 {
Chris@0 171 return function (callable $handler) use ($decider, $delay) {
Chris@0 172 return new RetryMiddleware($decider, $handler, $delay);
Chris@0 173 };
Chris@0 174 }
Chris@0 175
Chris@0 176 /**
Chris@0 177 * Middleware that logs requests, responses, and errors using a message
Chris@0 178 * formatter.
Chris@0 179 *
Chris@0 180 * @param LoggerInterface $logger Logs messages.
Chris@0 181 * @param MessageFormatter $formatter Formatter used to create message strings.
Chris@0 182 * @param string $logLevel Level at which to log requests.
Chris@0 183 *
Chris@0 184 * @return callable Returns a function that accepts the next handler.
Chris@0 185 */
Chris@0 186 public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
Chris@0 187 {
Chris@0 188 return function (callable $handler) use ($logger, $formatter, $logLevel) {
Chris@0 189 return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
Chris@0 190 return $handler($request, $options)->then(
Chris@0 191 function ($response) use ($logger, $request, $formatter, $logLevel) {
Chris@0 192 $message = $formatter->format($request, $response);
Chris@0 193 $logger->log($logLevel, $message);
Chris@0 194 return $response;
Chris@0 195 },
Chris@0 196 function ($reason) use ($logger, $request, $formatter) {
Chris@0 197 $response = $reason instanceof RequestException
Chris@0 198 ? $reason->getResponse()
Chris@0 199 : null;
Chris@0 200 $message = $formatter->format($request, $response, $reason);
Chris@0 201 $logger->notice($message);
Chris@0 202 return \GuzzleHttp\Promise\rejection_for($reason);
Chris@0 203 }
Chris@0 204 );
Chris@0 205 };
Chris@0 206 };
Chris@0 207 }
Chris@0 208
Chris@0 209 /**
Chris@0 210 * This middleware adds a default content-type if possible, a default
Chris@0 211 * content-length or transfer-encoding header, and the expect header.
Chris@0 212 *
Chris@0 213 * @return callable
Chris@0 214 */
Chris@0 215 public static function prepareBody()
Chris@0 216 {
Chris@0 217 return function (callable $handler) {
Chris@0 218 return new PrepareBodyMiddleware($handler);
Chris@0 219 };
Chris@0 220 }
Chris@0 221
Chris@0 222 /**
Chris@0 223 * Middleware that applies a map function to the request before passing to
Chris@0 224 * the next handler.
Chris@0 225 *
Chris@0 226 * @param callable $fn Function that accepts a RequestInterface and returns
Chris@0 227 * a RequestInterface.
Chris@0 228 * @return callable
Chris@0 229 */
Chris@0 230 public static function mapRequest(callable $fn)
Chris@0 231 {
Chris@0 232 return function (callable $handler) use ($fn) {
Chris@0 233 return function ($request, array $options) use ($handler, $fn) {
Chris@0 234 return $handler($fn($request), $options);
Chris@0 235 };
Chris@0 236 };
Chris@0 237 }
Chris@0 238
Chris@0 239 /**
Chris@0 240 * Middleware that applies a map function to the resolved promise's
Chris@0 241 * response.
Chris@0 242 *
Chris@0 243 * @param callable $fn Function that accepts a ResponseInterface and
Chris@0 244 * returns a ResponseInterface.
Chris@0 245 * @return callable
Chris@0 246 */
Chris@0 247 public static function mapResponse(callable $fn)
Chris@0 248 {
Chris@0 249 return function (callable $handler) use ($fn) {
Chris@0 250 return function ($request, array $options) use ($handler, $fn) {
Chris@0 251 return $handler($request, $options)->then($fn);
Chris@0 252 };
Chris@0 253 };
Chris@0 254 }
Chris@0 255 }