Skip to content

Commit 4c5875e

Browse files
JonPurvisSammyjo20
andauthored
Swap header to use psrResponse (#535)
* swap header to use psrResponse * Improved checking of isJson and isXml and standardised the header lookup * Revert Sammy's silly changes * Fixed mb_trim issue * Fixed another issue --------- Co-authored-by: Sammyjo20 <29132017+Sammyjo20@users.noreply.github.com>
1 parent bdd2ab9 commit 4c5875e

2 files changed

Lines changed: 57 additions & 7 deletions

File tree

src/Http/Response.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
use Throwable;
88
use LogicException;
9+
use function implode;
910
use SimpleXMLElement;
11+
use function is_array;
12+
use function mb_strtolower;
1013
use Saloon\Traits\Macroable;
1114
use InvalidArgumentException;
1215
use Saloon\Helpers\ArrayHelpers;
@@ -486,35 +489,49 @@ public function throw(): static
486489
*/
487490
public function header(string $header): string|array|null
488491
{
489-
return $this->headers()->get($header);
492+
if (! $this->psrResponse->hasHeader($header)) {
493+
return null;
494+
}
495+
496+
$values = $this->psrResponse->getHeader($header);
497+
498+
return count($values) === 1 ? $values[0] : $values;
490499
}
491500

492501
/**
493502
* Determine if the response is in JSON format.
494503
*/
495504
public function isJson(): bool
496505
{
497-
$contentType = $this->psrResponse->getHeaderLine('Content-Type');
506+
$contentType = $this->header('Content-Type');
498507

499-
if ($contentType === '') {
508+
if (empty($contentType)) {
500509
return false;
501510
}
502511

503-
return str_contains($contentType, 'json');
512+
if (is_array($contentType)) {
513+
$contentType = implode(',', $contentType);
514+
}
515+
516+
return str_contains(mb_strtolower($contentType), 'json');
504517
}
505518

506519
/**
507520
* Determine if the response is in XML format.
508521
*/
509522
public function isXml(): bool
510523
{
511-
$contentType = $this->psrResponse->getHeaderLine('Content-Type');
524+
$contentType = $this->header('Content-Type');
512525

513-
if ($contentType === '') {
526+
if (empty($contentType)) {
514527
return false;
515528
}
516529

517-
return str_contains($contentType, 'xml');
530+
if (is_array($contentType)) {
531+
$contentType = implode(',', $contentType);
532+
}
533+
534+
return str_contains(mb_strtolower($contentType), 'xml');
518535
}
519536

520537
/**

tests/Unit/ResponseTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,3 +472,36 @@
472472
$response = $connector->send(new UserRequest, $mockClient);
473473
expect($response->isXml())->toBeFalse();
474474
});
475+
476+
test('header lookup is case-insensitive per HTTP RFC', function () {
477+
$mockClient = new MockClient([
478+
MockResponse::make([], 200, ['x-my-custom-header' => 'custom-value']),
479+
]);
480+
481+
$response = connector()->send(new UserRequest, $mockClient);
482+
483+
expect($response->header('X-My-Custom-Header'))->toEqual('custom-value');
484+
expect($response->header('x-my-custom-header'))->toEqual('custom-value');
485+
});
486+
487+
test('isJson lookup can use case insensitive headers', function () {
488+
$mockClient = new MockClient([
489+
MockResponse::make([], 200, ['content-type' => 'application/JSON']),
490+
]);
491+
492+
$response = connector()->send(new UserRequest, $mockClient);
493+
494+
expect($response->isJson())->toBeTrue();
495+
expect($response->isXml())->toBeFalse();
496+
});
497+
498+
test('isXml lookup can use case insensitive headers', function () {
499+
$mockClient = new MockClient([
500+
MockResponse::make([], 200, ['content-type' => 'text/xml']),
501+
]);
502+
503+
$response = connector()->send(new UserRequest, $mockClient);
504+
505+
expect($response->isXml())->toBeTrue();
506+
expect($response->isJson())->toBeFalse();
507+
});

0 commit comments

Comments
 (0)