From c76a68f1232058c7a0a7a616fa05ae47021dfd0f Mon Sep 17 00:00:00 2001 From: Denny Septian Panggabean <97607754+ddevsr@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:17:58 +0700 Subject: [PATCH] feat: CURL option `force_ip_resolve` (#9194) * feat: CURL option force_ip_resolve * test: CURL option force_ip_resolve * docs: CURL option force_ip_resolve * fix: PHPStan error * fix: prevent using empty() * fix: strict check * tests: unknown value in option force_ip_resolve * fix: using default match * fix: PHPUnit option resolved_force_ip --- system/HTTP/CURLRequest.php | 9 +++++ tests/system/HTTP/CURLRequestTest.php | 36 +++++++++++++++++++ .../source/libraries/curlrequest.rst | 9 +++++ .../source/libraries/curlrequest/036.php | 4 +++ 4 files changed, 58 insertions(+) create mode 100644 user_guide_src/source/libraries/curlrequest/036.php diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index 6411e0df6353..3a606be97442 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -649,6 +649,15 @@ protected function setCURLOptions(array $curlOptions = [], array $config = []) $this->setHeader('Content-Length', (string) strlen($json)); } + // Resolve IP + if (array_key_exists('force_ip_resolve', $config)) { + $curlOptions[CURLOPT_IPRESOLVE] = match ($config['force_ip_resolve']) { + 'v4' => CURL_IPRESOLVE_V4, + 'v6' => CURL_IPRESOLVE_V6, + default => CURL_IPRESOLVE_WHATEVER + }; + } + // version if (! empty($config['version'])) { $version = sprintf('%.1F', $config['version']); diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php index 316c111559a7..cba2ab113650 100644 --- a/tests/system/HTTP/CURLRequestTest.php +++ b/tests/system/HTTP/CURLRequestTest.php @@ -1176,6 +1176,42 @@ public function testHTTPv3(): void $this->assertSame(CURL_HTTP_VERSION_3, $options[CURLOPT_HTTP_VERSION]); } + public function testForceResolveIPv4(): void + { + $this->request->request('POST', '/post', [ + 'force_ip_resolve' => 'v4', + ]); + + $options = $this->request->curl_options; + + $this->assertArrayHasKey(CURLOPT_IPRESOLVE, $options); + $this->assertSame(CURL_IPRESOLVE_V4, $options[CURLOPT_IPRESOLVE]); + } + + public function testForceResolveIPv6(): void + { + $this->request->request('POST', '/post', [ + 'force_ip_resolve' => 'v6', + ]); + + $options = $this->request->curl_options; + + $this->assertArrayHasKey(CURLOPT_IPRESOLVE, $options); + $this->assertSame(CURL_IPRESOLVE_V6, $options[CURLOPT_IPRESOLVE]); + } + + public function testForceResolveIPUnknown(): void + { + $this->request->request('POST', '/post', [ + 'force_ip_resolve' => 'v?', + ]); + + $options = $this->request->curl_options; + + $this->assertArrayHasKey(CURLOPT_IPRESOLVE, $options); + $this->assertSame(\CURL_IPRESOLVE_WHATEVER, $options[CURLOPT_IPRESOLVE]); + } + public function testCookieOption(): void { $holder = SUPPORTPATH . 'HTTP/Files/CookiesHolder.txt'; diff --git a/user_guide_src/source/libraries/curlrequest.rst b/user_guide_src/source/libraries/curlrequest.rst index 1e06b69cc484..49540613e1cc 100644 --- a/user_guide_src/source/libraries/curlrequest.rst +++ b/user_guide_src/source/libraries/curlrequest.rst @@ -364,6 +364,15 @@ is true: .. _curlrequest-version: +force_ip_resolve +================ + +.. versionadded:: 4.6.0 + +To set the HTTP handlers to use ``v4`` only ipv4 protocol or ``v6`` for ipv6 protocol: + +.. literalinclude:: curlrequest/036.php + version ======= diff --git a/user_guide_src/source/libraries/curlrequest/036.php b/user_guide_src/source/libraries/curlrequest/036.php new file mode 100644 index 000000000000..a02787d184bb --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/036.php @@ -0,0 +1,4 @@ +request('GET', '/', ['force_ip_resolve' => 'v4']); // v4 or v6