3fd72faa84295d4acec13d3cc7efadc8ac886455
[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 = __NAMESPACE__ . '\\ClientException';
85         } elseif ($level === 5) {
86             $label = 'Server error';
87             $className = __NAMESPACE__ . '\\ServerException';
88         } else {
89             $label = 'Unsuccessful request';
90             $className = __CLASS__;
91         }
92
93         $uri = $request->getUri();
94         $uri = static::obfuscateUri($uri);
95
96         // Server Error: `GET /` resulted in a `404 Not Found` response:
97         // <html> ... (truncated)
98         $message = sprintf(
99             '%s: `%s` resulted in a `%s` response',
100             $label,
101             $request->getMethod() . ' ' . $uri,
102             $response->getStatusCode() . ' ' . $response->getReasonPhrase()
103         );
104
105         $summary = static::getResponseBodySummary($response);
106
107         if ($summary !== null) {
108             $message .= ":\n{$summary}\n";
109         }
110
111         return new $className($message, $request, $response, $previous, $ctx);
112     }
113
114     /**
115      * Get a short summary of the response
116      *
117      * Will return `null` if the response is not printable.
118      *
119      * @param ResponseInterface $response
120      *
121      * @return string|null
122      */
123     public static function getResponseBodySummary(ResponseInterface $response)
124     {
125         $body = $response->getBody();
126
127         if (!$body->isSeekable()) {
128             return null;
129         }
130
131         $size = $body->getSize();
132         $summary = $body->read(120);
133         $body->rewind();
134
135         if ($size > 120) {
136             $summary .= ' (truncated...)';
137         }
138
139         // Matches any printable character, including unicode characters:
140         // letters, marks, numbers, punctuation, spacing, and separators.
141         if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
142             return null;
143         }
144
145         return $summary;
146     }
147
148     /**
149      * Obfuscates URI if there is an username and a password present
150      *
151      * @param UriInterface $uri
152      *
153      * @return UriInterface
154      */
155     private static function obfuscateUri($uri)
156     {
157         $userInfo = $uri->getUserInfo();
158
159         if (false !== ($pos = strpos($userInfo, ':'))) {
160             return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
161         }
162
163         return $uri;
164     }
165
166     /**
167      * Get the request that caused the exception
168      *
169      * @return RequestInterface
170      */
171     public function getRequest()
172     {
173         return $this->request;
174     }
175
176     /**
177      * Get the associated response
178      *
179      * @return ResponseInterface|null
180      */
181     public function getResponse()
182     {
183         return $this->response;
184     }
185
186     /**
187      * Check if a response was received
188      *
189      * @return bool
190      */
191     public function hasResponse()
192     {
193         return $this->response !== null;
194     }
195
196     /**
197      * Get contextual information about the error from the underlying handler.
198      *
199      * The contents of this array will vary depending on which handler you are
200      * using. It may also be just an empty array. Relying on this data will
201      * couple you to a specific handler, but can give more debug information
202      * when needed.
203      *
204      * @return array
205      */
206     public function getHandlerContext()
207     {
208         return $this->handlerContext;
209     }
210 }