5 use GuzzleHttp\Exception\GuzzleException;
62 public function __construct(array $config = [])
64 if (!isset($config[
'handler'])) {
65 $config[
'handler'] = HandlerStack::create();
66 } elseif (!is_callable($config[
'handler'])) {
67 throw new \InvalidArgumentException(
'handler must be a callable');
71 if (isset($config[
'base_uri'])) {
72 $config[
'base_uri'] = Psr7\uri_for($config[
'base_uri']);
75 $this->configureDefaults($config);
84 public function __call($method, $args)
86 if (count($args) < 1) {
87 throw new \InvalidArgumentException(
'Magic request methods require a URI and optional options array');
91 $opts = isset($args[1]) ? $args[1] : [];
93 return substr($method, -5) ===
'Async'
94 ? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
95 : $this->request($method, $uri, $opts);
106 public function sendAsync(RequestInterface $request, array $options = [])
109 $options = $this->prepareDefaults($options);
111 return $this->transfer(
112 $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader(
'Host')),
128 $options[RequestOptions::SYNCHRONOUS] =
true;
129 return $this->sendAsync($request, $options)->wait();
146 public function requestAsync($method, $uri =
'', array $options = [])
148 $options = $this->prepareDefaults($options);
150 $headers = isset($options[
'headers']) ? $options[
'headers'] : [];
151 $body = isset($options[
'body']) ? $options[
'body'] :
null;
152 $version = isset($options[
'version']) ? $options[
'version'] :
'1.1';
154 $uri = $this->buildUri($uri, $options);
155 if (is_array($body)) {
156 $this->invalidBody();
158 $request =
new Psr7\Request($method, $uri, $headers, $body, $version);
160 unset($options[
'headers'], $options[
'body'], $options[
'version']);
162 return $this->transfer($request, $options);
179 public function request($method, $uri =
'', array $options = [])
181 $options[RequestOptions::SYNCHRONOUS] =
true;
182 return $this->requestAsync($method, $uri, $options)->wait();
196 public function getConfig($option =
null)
198 return $option ===
null
200 : (isset($this->config[$option]) ? $this->config[$option] :
null);
208 private function buildUri($uri, array $config)
211 $uri = Psr7\uri_for($uri ===
null ?
'' : $uri);
213 if (isset($config[
'base_uri'])) {
214 $uri = Psr7\UriResolver::resolve(Psr7\
uri_for($config[
'base_uri']), $uri);
217 if (isset($config[
'idn_conversion']) && ($config[
'idn_conversion'] !==
false)) {
218 $idnOptions = ($config[
'idn_conversion'] ===
true) ? IDNA_DEFAULT : $config[
'idn_conversion'];
219 $uri = Utils::idnUriConvert($uri, $idnOptions);
222 return $uri->getScheme() ===
'' && $uri->getHost() !==
'' ? $uri->withScheme(
'http') : $uri;
231 private function configureDefaults(array $config)
234 'allow_redirects' => RedirectMiddleware::$defaultSettings,
235 'http_errors' =>
true,
236 'decode_content' =>
true,
239 'idn_conversion' =>
true,
247 if (php_sapi_name() ===
'cli' && getenv(
'HTTP_PROXY')) {
248 $defaults[
'proxy'][
'http'] = getenv(
'HTTP_PROXY');
251 if ($proxy = getenv(
'HTTPS_PROXY')) {
252 $defaults[
'proxy'][
'https'] = $proxy;
255 if ($noProxy = getenv(
'NO_PROXY')) {
256 $cleanedNoProxy = str_replace(
' ',
'', $noProxy);
257 $defaults[
'proxy'][
'no'] = explode(
',', $cleanedNoProxy);
260 $this->config = $config + $defaults;
262 if (!empty($config[
'cookies']) && $config[
'cookies'] ===
true) {
263 $this->config[
'cookies'] =
new CookieJar();
267 if (!isset($this->config[
'headers'])) {
271 foreach (array_keys($this->config[
'headers']) as $name) {
272 if (strtolower($name) ===
'user-agent') {
287 private function prepareDefaults(array $options)
289 $defaults = $this->config;
291 if (!empty($defaults[
'headers'])) {
293 $defaults[
'_conditional'] = $defaults[
'headers'];
294 unset($defaults[
'headers']);
299 if (array_key_exists(
'headers', $options)) {
301 if ($options[
'headers'] ===
null) {
302 $defaults[
'_conditional'] = [];
303 unset($options[
'headers']);
304 } elseif (!is_array($options[
'headers'])) {
305 throw new \InvalidArgumentException(
'headers must be an array');
310 $result = $options + $defaults;
313 foreach ($result as $k => $v) {
332 private function transfer(RequestInterface $request, array $options)
335 if (isset($options[
'save_to'])) {
336 $options[
'sink'] = $options[
'save_to'];
337 unset($options[
'save_to']);
341 if (isset($options[
'exceptions'])) {
342 $options[
'http_errors'] = $options[
'exceptions'];
343 unset($options[
'exceptions']);
346 $request = $this->applyOptions($request, $options);
348 $handler = $options[
'handler'];
351 return Promise\promise_for($handler($request, $options));
352 }
catch (\Exception $e) {
353 return Promise\rejection_for($e);
365 private function applyOptions(RequestInterface $request, array &$options)
371 if (isset($options[
'headers'])) {
372 $modify[
'set_headers'] = $options[
'headers'];
373 unset($options[
'headers']);
376 if (isset($options[
'form_params'])) {
377 if (isset($options[
'multipart'])) {
378 throw new \InvalidArgumentException(
'You cannot use '
379 .
'form_params and multipart at the same time. Use the '
380 .
'form_params option if you want to send application/'
381 .
'x-www-form-urlencoded requests, and the multipart '
382 .
'option to send multipart/form-data requests.');
384 $options[
'body'] = http_build_query($options[
'form_params'],
'',
'&');
385 unset($options[
'form_params']);
387 $options[
'_conditional'] = Psr7\_caseless_remove([
'Content-Type'], $options[
'_conditional']);
388 $options[
'_conditional'][
'Content-Type'] =
'application/x-www-form-urlencoded';
391 if (isset($options[
'multipart'])) {
392 $options[
'body'] =
new Psr7\MultipartStream($options[
'multipart']);
393 unset($options[
'multipart']);
396 if (isset($options[
'json'])) {
397 $options[
'body'] = \GuzzleHttp\json_encode($options[
'json']);
398 unset($options[
'json']);
400 $options[
'_conditional'] = Psr7\_caseless_remove([
'Content-Type'], $options[
'_conditional']);
401 $options[
'_conditional'][
'Content-Type'] =
'application/json';
404 if (!empty($options[
'decode_content'])
405 && $options[
'decode_content'] !==
true
408 $options[
'_conditional'] = Psr7\_caseless_remove([
'Accept-Encoding'], $options[
'_conditional']);
409 $modify[
'set_headers'][
'Accept-Encoding'] = $options[
'decode_content'];
412 if (isset($options[
'body'])) {
413 if (is_array($options[
'body'])) {
414 $this->invalidBody();
416 $modify[
'body'] = Psr7\stream_for($options[
'body']);
417 unset($options[
'body']);
420 if (!empty($options[
'auth']) && is_array($options[
'auth'])) {
421 $value = $options[
'auth'];
422 $type = isset($value[2]) ? strtolower($value[2]) :
'basic';
426 $modify[
'set_headers'] = Psr7\_caseless_remove([
'Authorization'], $modify[
'set_headers']);
427 $modify[
'set_headers'][
'Authorization'] =
'Basic '
428 . base64_encode(
"$value[0]:$value[1]");
432 $options[
'curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
433 $options[
'curl'][CURLOPT_USERPWD] =
"$value[0]:$value[1]";
436 $options[
'curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
437 $options[
'curl'][CURLOPT_USERPWD] =
"$value[0]:$value[1]";
442 if (isset($options[
'query'])) {
443 $value = $options[
'query'];
444 if (is_array($value)) {
445 $value = http_build_query($value,
null,
'&', PHP_QUERY_RFC3986);
447 if (!is_string($value)) {
448 throw new \InvalidArgumentException(
'query must be a string or array');
450 $modify[
'query'] = $value;
451 unset($options[
'query']);
455 if (isset($options[
'sink'])) {
457 if (is_bool($options[
'sink'])) {
458 throw new \InvalidArgumentException(
'sink must not be a boolean');
462 $request = Psr7\modify_request($request, $modify);
463 if ($request->getBody() instanceof Psr7\MultipartStream) {
466 $options[
'_conditional'] = Psr7\_caseless_remove([
'Content-Type'], $options[
'_conditional']);
467 $options[
'_conditional'][
'Content-Type'] =
'multipart/form-data; boundary='
468 . $request->getBody()->getBoundary();
472 if (isset($options[
'_conditional'])) {
475 foreach ($options[
'_conditional'] as $k => $v) {
476 if (!$request->hasHeader($k)) {
477 $modify[
'set_headers'][$k] = $v;
480 $request = Psr7\modify_request($request, $modify);
482 unset($options[
'_conditional']);
493 private function invalidBody()
495 throw new \InvalidArgumentException(
'Passing in the "body" request '
496 .
'option as an array to send a POST request has been deprecated. '
497 .
'Please use the "form_params" request option to send a '
498 .
'application/x-www-form-urlencoded request, or the "multipart" '
499 .
'request option to send a multipart/form-data request.');