Skip to content

Commit 68edcf7

Browse files
authored
Fix errors while parsing the PSR-7 request with moved uploaded files (#487)
1 parent 25a01ed commit 68edcf7

File tree

5 files changed

+88
-2
lines changed

5 files changed

+88
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Fix problem with parsing uploaded files from request after they have been moved (#487)
6+
57
## 2.5.1
68

79
- Fix problem with queue tracing when triggered from unit tests or when missing a queue name in the event

src/Sentry/Laravel/Http/LaravelRequestFetcher.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
class LaravelRequestFetcher implements RequestFetcherInterface
1212
{
13+
/**
14+
* They key in the container where a PSR-7 instance of the current request could be stored.
15+
*/
16+
public const CONTAINER_PSR7_INSTANCE_KEY = 'sentry-laravel.psr7.request';
17+
1318
/**
1419
* The Laravel container.
1520
*
@@ -28,6 +33,10 @@ public function fetchRequest(): ?ServerRequestInterface
2833
return null;
2934
}
3035

36+
if ($this->container->bound(self::CONTAINER_PSR7_INSTANCE_KEY)) {
37+
return $this->container->make(self::CONTAINER_PSR7_INSTANCE_KEY);
38+
}
39+
3140
try {
3241
return $this->container->make(ServerRequestInterface::class);
3342
} catch (BindingResolutionException $e) {

src/Sentry/Laravel/Http/SetRequestIpMiddleware.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@
33
namespace Sentry\Laravel\Http;
44

55
use Closure;
6+
use Illuminate\Contracts\Container\Container;
67
use Illuminate\Http\Request;
78
use Sentry\State\HubInterface;
89
use Sentry\State\Scope;
910

11+
/**
12+
* This middleware enriches the Sentry scope with the IP address of the request.
13+
* We do this ourself instead of letting the PHP SDK handle this because we want
14+
* the IP from the Laravel request because it takes into account trusted proxies.
15+
*/
1016
class SetRequestIpMiddleware
1117
{
18+
/**
19+
* The Laravel container.
20+
*
21+
* @var \Illuminate\Contracts\Container\Container
22+
*/
23+
private $container;
24+
25+
public function __construct(Container $container)
26+
{
27+
$this->container = $container;
28+
}
29+
1230
/**
1331
* Handle an incoming request.
1432
*
@@ -19,9 +37,9 @@ class SetRequestIpMiddleware
1937
*/
2038
public function handle(Request $request, Closure $next)
2139
{
22-
if (app()->bound(HubInterface::class)) {
40+
if ($this->container->bound(HubInterface::class)) {
2341
/** @var \Sentry\State\HubInterface $sentry */
24-
$sentry = app(HubInterface::class);
42+
$sentry = $this->container->make(HubInterface::class);
2543

2644
$client = $sentry->getClient();
2745

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Sentry\Laravel\Http;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Container\BindingResolutionException;
7+
use Illuminate\Contracts\Container\Container;
8+
use Illuminate\Http\Request;
9+
use Psr\Http\Message\ServerRequestInterface;
10+
use Sentry\State\HubInterface;
11+
12+
/**
13+
* This middleware caches a PSR-7 version of the request as early as possible.
14+
* This is done to prevent running into (mostly uploaded file) parsing failures.
15+
*/
16+
class SetRequestMiddleware
17+
{
18+
/**
19+
* The Laravel container.
20+
*
21+
* @var \Illuminate\Contracts\Container\Container
22+
*/
23+
private $container;
24+
25+
public function __construct(Container $container)
26+
{
27+
$this->container = $container;
28+
}
29+
30+
/**
31+
* Handle an incoming request.
32+
*
33+
* @param \Illuminate\Http\Request $request
34+
* @param \Closure $next
35+
*
36+
* @return mixed
37+
*/
38+
public function handle(Request $request, Closure $next)
39+
{
40+
if ($this->container->bound(HubInterface::class)) {
41+
try {
42+
$this->container->instance(
43+
LaravelRequestFetcher::CONTAINER_PSR7_INSTANCE_KEY,
44+
$this->container->make(ServerRequestInterface::class)
45+
);
46+
} catch (BindingResolutionException $e) {
47+
// Ignore problems getting the PSR-7 server request instance here
48+
// In the Laravel request fetcher we have other fallbacks for that
49+
}
50+
}
51+
52+
return $next($request);
53+
}
54+
}

src/Sentry/Laravel/ServiceProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Sentry\Integration as SdkIntegration;
1313
use Sentry\Laravel\Http\LaravelRequestFetcher;
1414
use Sentry\Laravel\Http\SetRequestIpMiddleware;
15+
use Sentry\Laravel\Http\SetRequestMiddleware;
1516
use Sentry\SentrySdk;
1617
use Sentry\State\Hub;
1718
use Sentry\State\HubInterface;
@@ -44,12 +45,14 @@ public function boot(): void
4445
$this->bindEvents();
4546

4647
if ($this->app instanceof Lumen) {
48+
$this->app->middleware(SetRequestMiddleware::class);
4749
$this->app->middleware(SetRequestIpMiddleware::class);
4850
} elseif ($this->app->bound(HttpKernelInterface::class)) {
4951
/** @var \Illuminate\Foundation\Http\Kernel $httpKernel */
5052
$httpKernel = $this->app->make(HttpKernelInterface::class);
5153

5254
if ($httpKernel instanceof HttpKernel) {
55+
$httpKernel->pushMiddleware(SetRequestMiddleware::class);
5356
$httpKernel->pushMiddleware(SetRequestIpMiddleware::class);
5457
}
5558
}

0 commit comments

Comments
 (0)