Skip to content

Commit a97fa06

Browse files
[12.x] Add allowedUrls through preventStrayRequests (#56645)
* 👷‍♂️ Support allowed Urls through StrayRequest * 🧪 Add test for allowedUrls * 🧹 Remove comment * 🧪 Add missing test to Facade * formatting * Update PendingRequest.php --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent d8f38d8 commit a97fa06

File tree

4 files changed

+87
-5
lines changed

4 files changed

+87
-5
lines changed

src/Illuminate/Http/Client/Factory.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ class Factory
8080
*/
8181
protected $preventStrayRequests = false;
8282

83+
/**
84+
* A list of URL patterns that are allowed to bypass the stray request guard.
85+
*
86+
* @var array<int, string>
87+
*/
88+
protected $allowedStrayRequestUrls = [];
89+
8390
/**
8491
* Create a new factory instance.
8592
*
@@ -333,13 +340,22 @@ public function preventingStrayRequests()
333340
}
334341

335342
/**
336-
* Indicate that an exception should not be thrown if any request is not faked.
343+
* Allow stray, unfaked requests entirely, or optionally allow only specific URLs.
337344
*
345+
* @param array<int, string>|null $only
338346
* @return $this
339347
*/
340-
public function allowStrayRequests()
348+
public function allowStrayRequests(?array $only = null)
341349
{
342-
return $this->preventStrayRequests(false);
350+
if (is_null($only)) {
351+
$this->preventStrayRequests(false);
352+
353+
$this->allowedStrayRequestUrls = [];
354+
} else {
355+
$this->allowedStrayRequestUrls = array_values($only);
356+
}
357+
358+
return $this;
343359
}
344360

345361
/**
@@ -486,7 +502,10 @@ public function recorded($callback = null)
486502
public function createPendingRequest()
487503
{
488504
return tap($this->newPendingRequest(), function ($request) {
489-
$request->stub($this->stubCallbacks)->preventStrayRequests($this->preventStrayRequests);
505+
$request
506+
->stub($this->stubCallbacks)
507+
->preventStrayRequests($this->preventStrayRequests)
508+
->allowStrayRequests($this->allowedStrayRequestUrls);
490509
});
491510
}
492511

src/Illuminate/Http/Client/PendingRequest.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ class PendingRequest
172172
*/
173173
protected $preventStrayRequests = false;
174174

175+
/**
176+
* A list of URL patterns that are allowed to bypass the stray request guard.
177+
*
178+
* @var array<int, string>
179+
*/
180+
protected $allowedStrayRequestUrls = [];
181+
175182
/**
176183
* The middleware callables added by users that will handle requests.
177184
*
@@ -1376,7 +1383,7 @@ public function buildStubHandler()
13761383
->first();
13771384

13781385
if (is_null($response)) {
1379-
if ($this->preventStrayRequests) {
1386+
if (! $this->isAllowedRequestUrl((string) $request->getUri())) {
13801387
throw new StrayRequestException((string) $request->getUri());
13811388
}
13821389

@@ -1501,6 +1508,40 @@ public function preventStrayRequests($prevent = true)
15011508
return $this;
15021509
}
15031510

1511+
/**
1512+
* Allow stray, unfaked requests entirely, or optionally allow only specific URLs.
1513+
*
1514+
* @param array<int, string> $only
1515+
* @return $this
1516+
*/
1517+
public function allowStrayRequests(array $only)
1518+
{
1519+
$this->allowedStrayRequestUrls = array_values($only);
1520+
1521+
return $this;
1522+
}
1523+
1524+
/**
1525+
* Determine if the given URL is allowed as a stray request.
1526+
*
1527+
* @param string $url
1528+
* @return bool
1529+
*/
1530+
public function isAllowedRequestUrl($url)
1531+
{
1532+
if (! $this->preventStrayRequests) {
1533+
return true;
1534+
}
1535+
1536+
foreach ($this->allowedStrayRequestUrls as $pattern) {
1537+
if (Str::is($pattern, $url)) {
1538+
return true;
1539+
}
1540+
}
1541+
1542+
return false;
1543+
}
1544+
15041545
/**
15051546
* Toggle asynchronicity in requests.
15061547
*

tests/Http/HttpClientTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,6 +3464,21 @@ public function testPreventingStrayRequests()
34643464
$this->assertTrue($this->factory->preventingStrayRequests());
34653465
}
34663466

3467+
public function testAllowingStrayRequestUrls()
3468+
{
3469+
$this->assertFalse($this->factory->preventingStrayRequests());
3470+
$this->assertTrue($this->factory->isAllowedRequestUrl('127.0.0.1'));
3471+
3472+
$this->factory->preventStrayRequests();
3473+
$this->assertFalse($this->factory->isAllowedRequestUrl('127.0.0.1'));
3474+
$this->factory->allowStrayRequests([
3475+
'127.0.0.1',
3476+
]);
3477+
3478+
$this->assertTrue($this->factory->preventingStrayRequests());
3479+
$this->assertTrue($this->factory->isAllowedRequestUrl('127.0.0.1'));
3480+
}
3481+
34673482
public function testItCanAddAuthorizationHeaderIntoRequestUsingBeforeSendingCallback()
34683483
{
34693484
$this->factory->fake();

tests/Support/SupportFacadesHttpTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public function testFacadeRootIsSharedWhenEnforcingFaking(): void
5656
$this->assertSame($client, $this->app->make(Factory::class));
5757
}
5858

59+
public function testFacadeRootIsSharedWhenEnforcingFakingWithAllowedUrls(): void
60+
{
61+
$client = Http::preventStrayRequests()->allowStrayRequests(['127.0.0.1']);
62+
63+
$this->assertSame($client, $this->app->make(Factory::class));
64+
}
65+
5966
public function test_can_set_prevents_to_prevents_stray_requests(): void
6067
{
6168
Http::preventStrayRequests(true);

0 commit comments

Comments
 (0)