|
4 | 4 |
|
5 | 5 | use Closure;
|
6 | 6 | use Illuminate\Container\Container;
|
7 |
| -use Illuminate\Contracts\Container\BindingResolutionException; |
8 | 7 | use Illuminate\Http\Request;
|
| 8 | +use Nyholm\Psr7\Factory\Psr17Factory; |
9 | 9 | use Psr\Http\Message\ServerRequestInterface;
|
10 | 10 | use Sentry\State\HubInterface;
|
| 11 | +use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; |
11 | 12 |
|
12 | 13 | /**
|
13 | 14 | * This middleware caches a PSR-7 version of the request as early as possible.
|
14 | 15 | * This is done to prevent running into (mostly uploaded file) parsing failures.
|
15 | 16 | */
|
16 | 17 | class SetRequestMiddleware
|
17 | 18 | {
|
18 |
| - /** |
19 |
| - * Handle an incoming request. |
20 |
| - * |
21 |
| - * @param \Illuminate\Http\Request $request |
22 |
| - * @param \Closure $next |
23 |
| - * |
24 |
| - * @return mixed |
25 |
| - */ |
26 | 19 | public function handle(Request $request, Closure $next)
|
27 | 20 | {
|
28 | 21 | $container = Container::getInstance();
|
29 | 22 |
|
30 | 23 | 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); |
39 | 28 | }
|
40 | 29 | }
|
41 | 30 |
|
42 | 31 | return $next($request);
|
43 | 32 | }
|
| 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 | + } |
44 | 58 | }
|
0 commit comments