Minor dependency updates
[yaffs-website] / vendor / guzzlehttp / guzzle / src / Exception / RequestException.php
1 <?php
2 namespace GuzzleHttp\Exception;
3
4 use Psr\Http\Message\RequestInterface;
5 use Psr\Http\Message\ResponseInterface;
6 use GuzzleHttp\Promise\PromiseInterface;
7 use Psr\Http\Message\UriInterface;
8
9 /**
10  * HTTP Request exception
11  */
12 class RequestException extends TransferException
13 {
14     /** @var RequestInterface */
15     private $request;
16
17     /** @var ResponseInterface */
18     private $response;
19
20     /** @var array */
21     private $handlerContext;
22
23     public function __construct(
24         $message,
25         RequestInterface $request,
26         ResponseInterface $response = null,
27         \Exception $previous = null,
28         array $handlerContext = []
29     ) {
30         // Set the code of the exception if the response is set and not future.
31         $code = $response && !($response instanceof PromiseInterface)
32             ? $response->getStatusCode()
33             : 0;
34         parent::__construct($message, $code, $previous);
35         $this->request = $request;
36         $this->response = $response;
37         $this->handlerContext = $handlerContext;
38     }
39
40     /**
41      * Wrap non-RequestExceptions with a RequestException
42      *
43      * @param RequestInterface $request
44      * @param \Exception       $e
45      *
46      * @return RequestException
47      */
48     public static function wrapException(RequestInterface $request, \Exception $e)
49     {
50         return $e instanceof RequestException
51             ? $e
52             : new RequestException($e->getMessage(), $request, null, $e);
53     }
54
55     /**
56      * Factory method to create a new exception with a normalized error message
57      *
58      * @param RequestInterface  $request  Request
59      * @param ResponseInterface $response Response received
60      * @param \Exception        $previous Previous exception
61      * @param array             $ctx      Optional handler context.
62      *
63      * @return self
64      */
65     public static function create(
66         RequestInterface $request,
67         ResponseInterface $response = null,
68         \Exception $previous = null,
69         array $ctx = []
70     ) {
71         if (!$response) {
72             return new self(
73                 'Error completing request',
74                 $request,
75                 null,
76                 $previous,
77                 $ctx
78             );
79         }
80
81         $level = (int) floor($response->getStatusCode() / 100);
82         if ($level === 4) {
83             $label = 'Client error';
84             $className = ClientException::class;
85         } elseif ($level === 5) {
86             $label = 'Server error';
87             $className = ServerException::class;
88         } else {
89             $label = 'Unsuccessful request';
90             $className = __CLASS__;
91         }
92
93         $uri = $request->getUri();
94         $uri = static::obfuscateUri($uri);
95
96         // Client Error: `GET /` resulted in a `404 Not Found` response:
97         // <html> ... (truncated)
98         $message = sprintf(
99             '%s: `%s %s` resulted in a `%s %s` response',
100             $label,
101             $request->getMethod(),
102             $uri,
103             $response->getStatusCode(),
104             $response->getReasonPhrase()
105         );
106
107         $summary = static::getResponseBodySummary($response);
108
109         if ($summary !== null) {
110             $message .= ":\n{$summary}\n";
111         }
112
113         return new $className($message, $request, $response, $previous, $ctx);
114     }
115
116     /**
117      * Get a short summary of the response
118      *
119      * Will return `null` if the response is not printable.
120      *
121      * @param ResponseInterface $response
122      *
123      * @return string|null
124      */
125     public static function getResponseBodySummary(ResponseInterface $response)
126     {
127         $body = $response->getBody();
128
129         if (!$body->isSeekable()) {
130             return null;
131         }
132
133         $size = $body->getSize();
134
135         if ($size === 0) {
136             return null;
137         }
138
139         $summary = $body->read(120);
140         $body->rewind();
141
142         if ($size > 120) {
143             $summary .= ' (truncated...)';
144         }
145
146         // Matches any printable character, including unicode characters:
147         // letters, marks, numbers, punctuation, spacing, and separators.
148         if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
149             return null;
150         }
151
152         return $summary;
153     }
154
155     /**
156      * Obfuscates URI if there is an username and a password present
157      *
158      * @param UriInterface $uri
159      *
160      * @return UriInterface
161      */
162     private static function obfuscateUri($uri)
163     {
164         $userInfo = $uri->getUserInfo();
165
166         if (false !== ($pos = strpos($userInfo, ':'))) {
167             return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
168         }
169
170         return $uri;
171     }
172
173     /**
174      * Get the request that caused the exception
175      *
176      * @return RequestInterface
177      */
178     public function getRequest()
179     {
180         return $this->request;
181     }
182
183     /**
184      * Get the associated response
185      *
186      * @return ResponseInterface|null
187      */
188     public function getResponse()
189     {
190         return $this->response;
191     }
192
193     /**
194      * Check if a response was received
195      *
196      * @return bool
197      */
198     public function hasResponse()
199     {
200         return $this->response !== null;
201     }
202
203     /**
204      * Get contextual information about the error from the underlying handler.
205      *
206      * The contents of this array will vary depending on which handler you are
207      * using. It may also be just an empty array. Relying on this data will
208      * couple you to a specific handler, but can give more debug information
209      * when needed.
210      *
211      * @return array
212      */
213     public function getHandlerContext()
214     {
215         return $this->handlerContext;
216     }
217 }