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