diff --git a/4dev/tests/UrlRequests/CoreLibsUrlRequestsCurlTest.php b/4dev/tests/UrlRequests/CoreLibsUrlRequestsCurlTest.php index 8b33796c..ddc25fe6 100644 --- a/4dev/tests/UrlRequests/CoreLibsUrlRequestsCurlTest.php +++ b/4dev/tests/UrlRequests/CoreLibsUrlRequestsCurlTest.php @@ -990,7 +990,7 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase $curl = new \CoreLibs\UrlRequests\Curl(); $this->expectException(\RuntimeException::class); $this->expectExceptionMessageMatches("/InvalidRequestType/"); - $response = $curl->request('wrong', 'http://foo.bar.com'); + $curl->request('wrong', 'http://foo.bar.com'); } /** @@ -1018,13 +1018,13 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase $this->expectException(\RuntimeException::class); $this->expectExceptionMessageMatches("/CurlExecError/"); // invalid yrl - $response = $curl->request('get', 'as-4939345!#$%'); + $curl->request('get', 'as-4939345!#$%'); } /** - * TODO: Exception:BadRequest + * Exception:ClientError * - * @testdox UrlRequests\Curl Exception:BadRequest + * @testdox UrlRequests\Curl Exception:ClientError * * @return void */ @@ -1033,12 +1033,72 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase $curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => true]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessageMatches("/ClientError/"); + $curl->get($this->url_basic, [ + "headers" => [ + "Authorization" => "schmalztiegel", + "RunAuthTest" => "yes", + ] + ]); + } + + /** + * Exception:ClientError + * + * @testdox UrlRequests\Curl Exception:ClientError on call enable + * + * @return void + */ + public function testExceptionBadRequestEnable(): void + { + $curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => false]); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessageMatches("/ClientError/"); + $curl->get($this->url_basic, [ + "headers" => [ + "Authorization" => "schmalztiegel", + "RunAuthTest" => "yes", + ], + "http_errors" => true + ]); + } + + /** + * Exception:ClientError + * + * @testdox UrlRequests\Curl Exception:ClientError unset on call + * + * @return void + */ + public function testExceptionBadRequestUnset(): void + { + // if true, with false it has to be off + $curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => true]); $response = $curl->get($this->url_basic, [ "headers" => [ "Authorization" => "schmalztiegel", - "RunAuthTest" => "yes", - ] + "RunAuthTest" => "yes", + ], + "http_errors" => false, ]); + $this->assertEquals( + "401", + $response['code'], + 'Unset Exception failed with false' + ); + // if false, null should not change it + $curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => false]); + $response = $curl->get($this->url_basic, [ + "headers" => [ + "Authorization" => "schmalztiegel", + "RunAuthTest" => "yes", + ], + "http_errors" => null, + ]); + $this->assertEquals( + "401", + $response['code'], + 'Unset Exception failed with null' + ); } /** diff --git a/www/admin/class_test.url-requests.curl.php b/www/admin/class_test.url-requests.curl.php index ed6918dd..87fa0053 100644 --- a/www/admin/class_test.url-requests.curl.php +++ b/www/admin/class_test.url-requests.curl.php @@ -276,6 +276,24 @@ try { } catch (Exception $e) { print "Exception:
" . print_r(json_decode($e->getMessage(), true), true) . "

"; } +print "AUTH REQUEST WITH EXCEPTION (UNSET):
"; +try { + $uc = new Curl([ + "base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/', + "http_errors" => true, + "headers" => [ + "Authorization" => "schmalztiegel", + "RunAuthTest" => "yes", + ] + ]); + $response = $uc->get('UrlRequests.target.php', ['http_errors' => false]); + print "AUTH REQUEST (UNSET):
" . print_r($response, true) . "
"; + print "[uc] SENT URL: " . $uc->getUrlSent() . "
"; + print "[uc] SENT URL PARSED:
" . print_r($uc->getUrlParsedSent(), true) . "
"; + print "[uc] SENT HEADERS:
" . print_r($uc->getHeadersSent(), true) . "
"; +} catch (Exception $e) { + print "Exception:
" . print_r(json_decode($e->getMessage(), true), true) . "

"; +} print "
"; $uc = new Curl([ diff --git a/www/lib/CoreLibs/UrlRequests/Curl.php b/www/lib/CoreLibs/UrlRequests/Curl.php index 80ab9af3..f9110054 100644 --- a/www/lib/CoreLibs/UrlRequests/Curl.php +++ b/www/lib/CoreLibs/UrlRequests/Curl.php @@ -458,22 +458,25 @@ class Curl implements Interface\RequestsInterface /** * Overall request call * - * @param string $type get, post, pathc, put, delete: - * if not set or invalid throw error - * @param string $url The URL being requested, - * including domain and protocol - * @param null|array> $headers [default=[]] Headers to be used in the request - * @param null|array $query [default=null] Optinal query parameters - * @param null|string|array $body [default=null] Data body, converted to JSON + * @param string $type get, post, pathc, put, delete: + * if not set or invalid throw error + * @param string $url The URL being requested, + * including domain and protocol + * @param null|array> $headers Headers to be used in the request + * @param null|array $query Optinal query parameters + * @param null|string|array $body Data body, converted to JSON + * @param null|bool $http_errors Throw exception on http response + * 400 or higher if set to true * @return array{code:string,headers:array>,content:string} * @throws \RuntimeException if type param is not valid */ private function curlRequest( string $type, string $url, - null|array $headers = [], - null|array $query = null, - null|string|array $body = null + null|array $headers, + null|array $query, + null|string|array $body, + null|bool $http_errors, ): array { $this->url = $this->buildQuery($url, $query); $this->headers = $this->convertHeaders($this->buildHeaders($headers)); @@ -514,7 +517,7 @@ class Curl implements Interface\RequestsInterface // for debug // print "CURLINFO_HEADER_OUT:
" . curl_getinfo($handle, CURLINFO_HEADER_OUT) . "
"; // get response code and bail on not authorized - $http_response = $this->handleCurlResponse($http_result, $handle); + $http_response = $this->handleCurlResponse($http_result, $http_errors, $handle); // close handler $this->handleCurlClose($handle); // return response and result @@ -685,17 +688,19 @@ class Curl implements Interface\RequestsInterface * can be turned off by setting http_errors to false * * @param string $http_result result string from the url call + * @param ?bool $http_errors if we should throw an exception on error, override config setting * @param \CurlHandle $handle Curl handler * @return string http response code * @throws \RuntimeException if http_errors is true then will throw exception on any response code >= 400 */ private function handleCurlResponse( string $http_result, + ?bool $http_errors, \CurlHandle $handle ): string { $http_response = curl_getinfo($handle, CURLINFO_RESPONSE_CODE); if ( - empty($this->config['http_errors']) || + empty($http_errors ?? $this->config['http_errors']) || $http_response < self::HTTP_BAD_REQUEST ) { return (string)$http_response; @@ -942,7 +947,7 @@ class Curl implements Interface\RequestsInterface * phpcs:disable Generic.Files.LineLength * @param string $type * @param string $url - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options * @return array{code:string,headers:array>,content:string} Result code, headers and content as array, content is json * @throws \UnexpectedValueException on missing body data when body data is needed * phpcs:enable Generic.Files.LineLength @@ -964,7 +969,8 @@ class Curl implements Interface\RequestsInterface $url, !array_key_exists('headers', $options) ? [] : $options['headers'], $options['query'] ?? null, - $options['body'] ?? null + $options['body'] ?? null, + !array_key_exists('http_errors', $options) ? null : $options['http_errors'], ); } } diff --git a/www/lib/CoreLibs/UrlRequests/CurlTrait.php b/www/lib/CoreLibs/UrlRequests/CurlTrait.php index 5010e2fa..b75b3ab3 100644 --- a/www/lib/CoreLibs/UrlRequests/CurlTrait.php +++ b/www/lib/CoreLibs/UrlRequests/CurlTrait.php @@ -25,8 +25,8 @@ trait CurlTrait * "get" calls do not set any body * * @param string $type if set as get do not add body, else add body - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Request options - * @return array{headers?:null|array>,query?:null|array,body?:null|string|array} + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Request options + * @return array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} */ private function setOptions(string $type, array $options): array { @@ -34,12 +34,14 @@ trait CurlTrait return [ "headers" => !array_key_exists('headers', $options) ? [] : $options['headers'], "query" => $options['query'] ?? null, + "http_errors" => !array_key_exists('http_errors', $options) ? null : $options['http_errors'], ]; } else { return [ "headers" => !array_key_exists('headers', $options) ? [] : $options['headers'], "query" => $options['query'] ?? null, "body" => $options['body'] ?? null, + "http_errors" => !array_key_exists('http_errors', $options) ? null : $options['http_errors'], ]; } } @@ -53,7 +55,7 @@ trait CurlTrait * * @param string $type What type of request we send, will throw exception if not a valid one * @param string $url The url to send - * @param array{headers?:null|array>,query?:null|string|array,body?:null|string|array} $options Request options + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Request options * @return array{code:string,headers:array>,content:string} [default=[]] Result code, headers and content as array, content is json * @throws \UnexpectedValueException on missing body data when body data is needed */ @@ -65,7 +67,7 @@ trait CurlTrait * * @param string $url The URL being requested, * including domain and protocol - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Options to set + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Options to set * @return array{code:string,headers:array>,content:string} [default=[]] Result code, headers and content as array, content is json */ public function get(string $url, array $options = []): array @@ -86,7 +88,7 @@ trait CurlTrait * * @param string $url The URL being requested, * including domain and protocol - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Options to set + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Options to set * @return array{code:string,headers:array>,content:string} Result code, headers and content as array, content is json */ public function post(string $url, array $options): array @@ -104,7 +106,7 @@ trait CurlTrait * * @param string $url The URL being requested, * including domain and protocol - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Options to set + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Options to set * @return array{code:string,headers:array>,content:string} Result code, headers and content as array, content is json */ public function put(string $url, array $options): array @@ -122,7 +124,7 @@ trait CurlTrait * * @param string $url The URL being requested, * including domain and protocol - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Options to set + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Options to set * @return array{code:string,headers:array>,content:string} Result code, headers and content as array, content is json */ public function patch(string $url, array $options): array @@ -141,7 +143,7 @@ trait CurlTrait * * @param string $url The URL being requested, * including domain and protocol - * @param array{headers?:null|array>,query?:null|array,body?:null|string|array} $options Options to set + * @param array{headers?:null|array>,query?:null|array,body?:null|string|array,http_errors?:null|bool} $options Options to set * @return array{code:string,headers:array>,content:string} [default=[]] Result code, headers and content as array, content is json */ public function delete(string $url, array $options = []): array