Client.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * @package Grav\Common\HTTP
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\HTTP;
  9. use Grav\Common\Grav;
  10. use Symfony\Component\HttpClient\CurlHttpClient;
  11. use Symfony\Component\HttpClient\HttpClient;
  12. use Symfony\Component\HttpClient\HttpOptions;
  13. use Symfony\Component\HttpClient\NativeHttpClient;
  14. use Symfony\Contracts\HttpClient\HttpClientInterface;
  15. class Client
  16. {
  17. /** @var callable The callback for the progress, either a function or callback in array notation */
  18. public static $callback = null;
  19. /** @var string[] */
  20. private static $headers = [
  21. 'User-Agent' => 'Grav CMS'
  22. ];
  23. public static function getClient(array $overrides = [], int $connections = 6, callable $callback = null): HttpClientInterface
  24. {
  25. $config = Grav::instance()['config'];
  26. $options = static::getOptions();
  27. // Use callback if provided
  28. if ($callback) {
  29. self::$callback = $callback;
  30. $options->setOnProgress([Client::class, 'progress']);
  31. }
  32. $settings = array_merge($options->toArray(), $overrides);
  33. $preferred_method = $config->get('system.http.method');
  34. // Try old GPM setting if value is the same as system default
  35. if ($preferred_method === 'auto') {
  36. $preferred_method = $config->get('system.gpm.method', 'auto');
  37. }
  38. switch ($preferred_method) {
  39. case 'curl':
  40. $client = new CurlHttpClient($settings, $connections);
  41. break;
  42. case 'fopen':
  43. case 'native':
  44. $client = new NativeHttpClient($settings, $connections);
  45. break;
  46. default:
  47. $client = HttpClient::create($settings, $connections);
  48. }
  49. return $client;
  50. }
  51. /**
  52. * Get HTTP Options
  53. *
  54. * @return HttpOptions
  55. */
  56. public static function getOptions(): HttpOptions
  57. {
  58. $config = Grav::instance()['config'];
  59. $referer = defined('GRAV_CLI') ? 'grav_cli' : Grav::instance()['uri']->rootUrl(true);
  60. $options = new HttpOptions();
  61. // Set default Headers
  62. $options->setHeaders(array_merge([ 'Referer' => $referer ], self::$headers));
  63. // Disable verify Peer if required
  64. $verify_peer = $config->get('system.http.verify_peer');
  65. // Try old GPM setting if value is default
  66. if ($verify_peer === true) {
  67. $verify_peer = $config->get('system.gpm.verify_peer', null) ?? $verify_peer;
  68. }
  69. $options->verifyPeer($verify_peer);
  70. // Set verify Host
  71. $verify_host = $config->get('system.http.verify_host', true);
  72. $options->verifyHost($verify_host);
  73. // New setting and must be enabled for Proxy to work
  74. if ($config->get('system.http.enable_proxy', true)) {
  75. // Set proxy url if provided
  76. $proxy_url = $config->get('system.http.proxy_url', $config->get('system.gpm.proxy_url', null));
  77. if ($proxy_url !== null) {
  78. $options->setProxy($proxy_url);
  79. }
  80. // Certificate
  81. $proxy_cert = $config->get('system.http.proxy_cert_path', null);
  82. if ($proxy_cert !== null) {
  83. $options->setCaPath($proxy_cert);
  84. }
  85. }
  86. return $options;
  87. }
  88. /**
  89. * Progress normalized for cURL and Fopen
  90. * Accepts a variable length of arguments passed in by stream method
  91. *
  92. * @return void
  93. */
  94. public static function progress(int $bytes_transferred, int $filesize, array $info)
  95. {
  96. if ($bytes_transferred > 0) {
  97. $percent = $filesize <= 0 ? 0 : (int)(($bytes_transferred * 100) / $filesize);
  98. $progress = [
  99. 'code' => $info['http_code'],
  100. 'filesize' => $filesize,
  101. 'transferred' => $bytes_transferred,
  102. 'percent' => $percent < 100 ? $percent : 100
  103. ];
  104. if (self::$callback !== null) {
  105. call_user_func(self::$callback, $progress);
  106. }
  107. }
  108. }
  109. }