diff --git a/src/Client.php b/src/Client.php index 37659eb..2f0f367 100644 --- a/src/Client.php +++ b/src/Client.php @@ -37,6 +37,19 @@ class Client private array $retryStatusCodes = [500, 503]; private mixed $jsonEncodeFlags; + protected string $baseUrl = ''; + + public function setBaseUrl(string $baseUrl): self + { + $this->baseUrl = $baseUrl; + return $this; + } + + public function getBaseUrl(): string + { + return $this->baseUrl; + } + /** * @param string $key * @param string $value @@ -127,7 +140,7 @@ public function setMaxRetries(int $maxRetries): self * * @param array $flags * @return self - */ + */ public function setJsonEncodeFlags(array $flags): self { $this->jsonEncodeFlags = implode('|', $flags); @@ -248,6 +261,10 @@ public function fetch( ?int $timeoutMs = null, ?int $connectTimeoutMs = null, ): Response { + if (!empty($this->baseUrl) && !preg_match('~^https?://~i', $url)) { + $url = rtrim($this->baseUrl, '/') . '/' . ltrim($url, '/'); + } + if (!in_array($method, [self::METHOD_PATCH, self::METHOD_GET, self::METHOD_CONNECT, self::METHOD_DELETE, self::METHOD_POST, self::METHOD_HEAD, self::METHOD_OPTIONS, self::METHOD_PUT, self::METHOD_TRACE])) { throw new Exception("Unsupported HTTP method"); } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 028670e..989274e 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -271,6 +271,141 @@ public function testSetGetUserAgent(): void $this->assertEquals($userAgent, $client->getUserAgent()); } + /** + * Test setting and getting the base URL. + * @return void + */ + public function testSetGetBaseUrl(): void + { + $client = new Client(); + $baseUrl = "http://localhost:8000"; + + $client->setBaseUrl($baseUrl); + + $this->assertEquals($baseUrl, $client->getBaseUrl()); + } + + /** + * Test base URL prepending to relative URLs. + * @return void + */ + public function testBaseUrlWithRelativePath(): void + { + $client = new Client(); + $client->setBaseUrl('http://localhost:8000'); + + $resp = $client->fetch( + url: '', + method: Client::METHOD_GET + ); + + if ($resp->getStatusCode() === 200) { + $respData = $resp->json(); + $this->assertEquals($respData['method'], Client::METHOD_GET); + $this->assertEquals($respData['url'], 'localhost:8000'); + } else { + echo "Please configure your PHP inbuilt SERVER"; + } + } + + /** + * Test base URL with path appending. + * @return void + */ + public function testBaseUrlWithPath(): void + { + $client = new Client(); + $client->setBaseUrl('http://localhost:8000'); + + $resp = $client->fetch( + url: 'redirect', + method: Client::METHOD_GET + ); + + if ($resp->getStatusCode() === 200) { + $respData = $resp->json(); + $this->assertEquals($respData['page'], "redirectedPage"); + } else { + echo "Please configure your PHP inbuilt SERVER"; + } + } + + /** + * Test base URL doesn't interfere with absolute URLs. + * @return void + */ + public function testBaseUrlWithAbsoluteUrl(): void + { + $client = new Client(); + $client->setBaseUrl('http://example.com'); + + $resp = $client->fetch( + url: 'http://localhost:8000', + method: Client::METHOD_GET + ); + + if ($resp->getStatusCode() === 200) { + $respData = $resp->json(); + $this->assertEquals($respData['method'], Client::METHOD_GET); + $this->assertEquals($respData['url'], 'localhost:8000'); + } else { + echo "Please configure your PHP inbuilt SERVER"; + } + } + + /** + * Test base URL with query parameters. + * @return void + */ + public function testBaseUrlWithQuery(): void + { + $client = new Client(); + $client->setBaseUrl('http://localhost:8000'); + + $resp = $client->fetch( + url: '', + method: Client::METHOD_GET, + query: [ + 'name' => 'John Doe', + 'age' => '30', + ] + ); + + if ($resp->getStatusCode() === 200) { + $respData = $resp->json(); + $this->assertEquals($respData['method'], Client::METHOD_GET); + $this->assertEquals( + json_encode($respData['query']), + json_encode(['name' => 'John Doe', 'age' => '30']) + ); + } else { + echo "Please configure your PHP inbuilt SERVER"; + } + } + + /** + * Test base URL with trailing slash normalization. + * @return void + */ + public function testBaseUrlTrailingSlashNormalization(): void + { + $client = new Client(); + + // Test with trailing slash in base URL + $client->setBaseUrl('http://localhost:8000/'); + $resp = $client->fetch( + url: '/redirect', + method: Client::METHOD_GET + ); + + if ($resp->getStatusCode() === 200) { + $respData = $resp->json(); + $this->assertEquals($respData['page'], "redirectedPage"); + } else { + echo "Please configure your PHP inbuilt SERVER"; + } + } + /** * Data provider for testFetch * @return array>