Skip to content

Commit 2224e80

Browse files
authored
fix: Broken SetRequestMiddleware on Laravel < 6.0 (#575)
1 parent 52e4011 commit 2224e80

File tree

5 files changed

+36
-21
lines changed

5 files changed

+36
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Fix not listening to queue events because `QueueManager` is registered as `queue` in the container and not by it's class name (#568)
66
- Fix status code not populated on transaction if response did not inherit from `Illuminate\Http\Response` like `Illuminate\Http\JsonResponse` (#573)
7+
- Fix broken `SetRequestMiddleware` on Laravel < 6.0 (#575)
78

89
## 2.13.0
910

composer.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
"Sentry\\Laravel\\": "src/"
3434
}
3535
},
36-
"suggest": {
37-
"zendframework/zend-diactoros": "When using Laravel >=5.1 - <=6.9 this package can help get more accurate request info, not used on Laravel >=6.10 anymore (https://laravel.com/docs/5.8/requests#psr7-requests)"
38-
},
3936
"require-dev": {
4037
"phpunit/phpunit": "^5.7 | ^6.5 | ^7.5 | ^8.4 | ^9.3",
4138
"laravel/framework": "5.0 - 5.8 | ^6.0 | ^7.0 | ^8.0 | ^9.0",

src/Sentry/Laravel/Http/LaravelRequestFetcher.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public function fetchRequest(): ?ServerRequestInterface
1818
{
1919
$container = Container::getInstance();
2020

21+
// If there is no request bound to the container
22+
// we are not dealing with a HTTP request and there
23+
// is no request to fetch for us so we can exit early.
2124
if (!$container->bound('request')) {
2225
return null;
2326
}

src/Sentry/Laravel/Http/SetRequestMiddleware.php

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,55 @@
44

55
use Closure;
66
use Illuminate\Container\Container;
7-
use Illuminate\Contracts\Container\BindingResolutionException;
87
use Illuminate\Http\Request;
8+
use Nyholm\Psr7\Factory\Psr17Factory;
99
use Psr\Http\Message\ServerRequestInterface;
1010
use Sentry\State\HubInterface;
11+
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
1112

1213
/**
1314
* This middleware caches a PSR-7 version of the request as early as possible.
1415
* This is done to prevent running into (mostly uploaded file) parsing failures.
1516
*/
1617
class SetRequestMiddleware
1718
{
18-
/**
19-
* Handle an incoming request.
20-
*
21-
* @param \Illuminate\Http\Request $request
22-
* @param \Closure $next
23-
*
24-
* @return mixed
25-
*/
2619
public function handle(Request $request, Closure $next)
2720
{
2821
$container = Container::getInstance();
2922

3023
if ($container->bound(HubInterface::class)) {
31-
try {
32-
$container->instance(
33-
LaravelRequestFetcher::CONTAINER_PSR7_INSTANCE_KEY,
34-
$container->make(ServerRequestInterface::class)
35-
);
36-
} catch (BindingResolutionException $e) {
37-
// Ignore problems getting the PSR-7 server request instance here
38-
// In the Laravel request fetcher we have other fallbacks for that
24+
$psrRequest = $this->resolvePsrRequest($request);
25+
26+
if ($psrRequest !== null) {
27+
$container->instance(LaravelRequestFetcher::CONTAINER_PSR7_INSTANCE_KEY, $psrRequest);
3928
}
4029
}
4130

4231
return $next($request);
4332
}
33+
34+
/**
35+
* This code was copied from the Laravel codebase which was introduced in Laravel 6.
36+
*
37+
* The reason we have it copied here is because older (<6.0) versions of Laravel use a different
38+
* method to construct the PSR-7 request object which requires other packages to create that object
39+
* but most importantly it does not function when those packages are not available resulting in errors
40+
*
41+
* So long story short, this is here to backport functionality to Laravel <6.0
42+
* if we drop support for those versions in the future we can reconsider this and
43+
* move back to using the container binding provided by Laravel for the PSR-7 object
44+
*
45+
* @see https://github.com/laravel/framework/blob/cb550b5bdc2b2c4cf077082adabde0144a72d190/src/Illuminate/Routing/RoutingServiceProvider.php#L127-L146
46+
*/
47+
private function resolvePsrRequest(Request $request): ?ServerRequestInterface
48+
{
49+
if (class_exists(Psr17Factory::class) && class_exists(PsrHttpFactory::class)) {
50+
$psr17Factory = new Psr17Factory;
51+
52+
return (new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory))
53+
->createRequest($request);
54+
}
55+
56+
return null;
57+
}
4458
}

src/Sentry/Laravel/ServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ protected function configureAndRegisterClient(): void
206206
});
207207

208208
$integrations[] = new SdkIntegration\RequestIntegration(
209-
new LaravelRequestFetcher($app)
209+
new LaravelRequestFetcher
210210
);
211211
}
212212

0 commit comments

Comments
 (0)