Skip to content

Commit 307bbc4

Browse files
authored
Use own cookie logic to avoid regenaration issues with Laravel driver (#1662)
* Use own cookie logic to avoid regenaration issues with Laravel driver * Add SessionDriver * Deprecate old one * Defer loading of httpdriver until needed, use old driver for Lumen * Add cookie middleware to tests * Tweak comments
1 parent ea96a38 commit 307bbc4

File tree

5 files changed

+163
-14
lines changed

5 files changed

+163
-14
lines changed

src/LaravelDebugbar.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
use DebugBar\DataCollector\RequestDataCollector;
3333
use DebugBar\DataCollector\TimeDataCollector;
3434
use DebugBar\DebugBar;
35+
use DebugBar\HttpDriverInterface;
36+
use DebugBar\PhpHttpDriver;
3537
use DebugBar\Storage\PdoStorage;
3638
use DebugBar\Storage\RedisStorage;
3739
use Exception;
@@ -118,6 +120,26 @@ public function __construct($app = null)
118120
}
119121
}
120122

123+
/**
124+
* Returns the HTTP driver
125+
*
126+
* If no http driver where defined, a PhpHttpDriver is automatically created
127+
*
128+
* @return HttpDriverInterface
129+
*/
130+
public function getHttpDriver()
131+
{
132+
if ($this->httpDriver === null) {
133+
if ($this->app->bound('cookie')) {
134+
$this->httpDriver = $this->app->make(SessionHttpDriver::class);
135+
} else {
136+
$this->httpDriver = $this->app->make(SymfonyHttpDriver::class);
137+
}
138+
}
139+
140+
return $this->httpDriver;
141+
}
142+
121143
/**
122144
* Enable the Debugbar and boot, if not already booted.
123145
*/
@@ -736,13 +758,10 @@ public function modifyResponse(Request $request, Response $response)
736758
$sessionHiddens = $app['config']->get('debugbar.options.session.hiddens', []);
737759
if ($app->bound(SessionManager::class)) {
738760

739-
/** @var \Illuminate\Session\SessionManager $sessionManager */
740-
$sessionManager = $app->make(SessionManager::class);
741-
$httpDriver = new SymfonyHttpDriver($sessionManager, $response);
742-
$this->setHttpDriver($httpDriver);
743-
744761
if ($this->shouldCollect('session') && ! $this->hasCollector('session')) {
745762
try {
763+
/** @var \Illuminate\Session\SessionManager $sessionManager */
764+
$sessionManager = $app->make(SessionManager::class);
746765
$this->addCollector(new SessionCollector($sessionManager, $sessionHiddens));
747766
} catch (Exception $e) {
748767
$this->addCollectorException('Cannot add SessionCollector', $e);

src/ServiceProvider.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Contracts\Http\Kernel;
1111
use Illuminate\Routing\Events\ResponsePrepared;
1212
use Illuminate\Routing\Router;
13+
use Illuminate\Session\CookieSessionHandler;
1314
use Illuminate\Session\SessionManager;
1415
use Illuminate\Support\Collection;
1516

@@ -31,15 +32,19 @@ public function register()
3132
);
3233

3334
$this->app->singleton(LaravelDebugbar::class, function ($app) {
34-
$debugbar = new LaravelDebugbar($app);
35+
return new LaravelDebugbar($app);
36+
});
3537

36-
if ($app->bound(SessionManager::class)) {
37-
$sessionManager = $app->make(SessionManager::class);
38-
$httpDriver = new SymfonyHttpDriver($sessionManager);
39-
$debugbar->setHttpDriver($httpDriver);
40-
}
38+
$this->app->singleton(SessionHttpDriver::class, function ($app) {
39+
// Attach the Cookie Handler with Request
40+
$cookieHandler = new CookieSessionHandler($app->make('cookie'), 0, true);
41+
$cookieHandler->setRequest($app['request']);
42+
43+
return new SessionHttpDriver($cookieHandler);
44+
});
4145

42-
return $debugbar;
46+
$this->app->singleton(SymfonyHttpDriver::class, function ($app) {
47+
return new SymfonyHttpDriver($app->make(SessionManager::class));
4348
});
4449

4550
$this->app->alias(LaravelDebugbar::class, 'debugbar');
@@ -171,6 +176,12 @@ protected function registerResponseListener()
171176
/** @var LaravelDebugbar $debugbar */
172177
$debugbar = $this->app->make(LaravelDebugbar::class);
173178
if ($debugbar->isEnabled()) {
179+
// Now that we have a Response, set it on the Driver
180+
$httpDriver = $debugbar->getHttpDriver();
181+
if ($httpDriver instanceof SessionHttpDriver || $httpDriver instanceof SymfonyHttpDriver) {
182+
$httpDriver->setResponse($event->response);
183+
}
184+
174185
if ($event->response->isRedirection()) {
175186
$debugbar->modifyResponse($event->request, $event->response);
176187
} else {

src/SessionHttpDriver.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
namespace Barryvdh\Debugbar;
4+
5+
use DebugBar\HttpDriverInterface;
6+
use Illuminate\Session\Store;
7+
use Symfony\Component\HttpFoundation\Response;
8+
use Symfony\Component\HttpFoundation\Session\Session;
9+
10+
/**
11+
* HTTP driver for Larave Request/Session using Cookies
12+
*/
13+
class SessionHttpDriver implements HttpDriverInterface
14+
{
15+
/** @var \SessionHandlerInterface */
16+
protected $session;
17+
18+
/** @var \Symfony\Component\HttpFoundation\Response */
19+
protected $response;
20+
21+
protected $data = null;
22+
23+
protected $id = '_debugbar';
24+
25+
public function __construct($session, $response = null)
26+
{
27+
$this->session = $session;
28+
$this->response = $response;
29+
}
30+
31+
/**
32+
* @param \Symfony\Component\HttpFoundation\Response $response
33+
* @return void
34+
*/
35+
public function setResponse($response)
36+
{
37+
$this->response = $response;
38+
}
39+
40+
/**
41+
* {@inheritDoc}
42+
*/
43+
public function setHeaders(array $headers)
44+
{
45+
if (!is_null($this->response)) {
46+
$this->response->headers->add($headers);
47+
}
48+
}
49+
50+
protected function ensureStarted()
51+
{
52+
if ($this->data === null) {
53+
$this->data = json_decode($this->session->read($this->id), true) ?: [];
54+
}
55+
}
56+
57+
/**
58+
* {@inheritDoc}
59+
*/
60+
public function isSessionStarted()
61+
{
62+
$this->ensureStarted();
63+
return true;
64+
}
65+
66+
/**
67+
* {@inheritDoc}
68+
*/
69+
public function setSessionValue($name, $value)
70+
{
71+
$this->isSessionStarted();
72+
73+
$this->data[$name] = $value;
74+
$this->session->write($this->id, json_encode($this->data));
75+
}
76+
77+
/**
78+
* {@inheritDoc}
79+
*/
80+
public function hasSessionValue($name)
81+
{
82+
$this->ensureStarted();
83+
84+
return array_key_exists($name, $this->data);
85+
}
86+
87+
/**
88+
* {@inheritDoc}
89+
*/
90+
public function getSessionValue($name)
91+
{
92+
$this->ensureStarted();
93+
94+
return $this->data[$name] ?? null;
95+
}
96+
97+
/**
98+
* {@inheritDoc}
99+
*/
100+
public function deleteSessionValue($name)
101+
{$this->isSessionStarted();
102+
103+
unset($this->data[$name]);
104+
105+
$this->session->write($this->id, json_encode($this->data));
106+
}
107+
}

src/SymfonyHttpDriver.php

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

99
/**
1010
* HTTP driver for Symfony Request/Session
11+
*
12+
* @deprecated
1113
*/
1214
class SymfonyHttpDriver implements HttpDriverInterface
1315
{
@@ -23,6 +25,15 @@ public function __construct($session, $response = null)
2325
$this->response = $response;
2426
}
2527

28+
/**
29+
* @param \Symfony\Component\HttpFoundation\Response $response
30+
* @return void
31+
*/
32+
public function setResponse($response)
33+
{
34+
$this->response = $response;
35+
}
36+
2637
/**
2738
* {@inheritDoc}
2839
*/

tests/DebugbarBrowserTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ protected function getEnvironmentSetUp($app)
2929
$this->addWebRoutes($router);
3030
$this->addApiRoutes($router);
3131

32-
$kernel = app('Illuminate\Contracts\Http\Kernel');
33-
$kernel->pushMiddleware('Illuminate\Session\Middleware\StartSession');
32+
$kernel = app(\Illuminate\Contracts\Http\Kernel::class);
33+
$kernel->pushMiddleware(\Illuminate\Session\Middleware\StartSession::class);
34+
$kernel->pushMiddleware(\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class);
3435

3536
\Orchestra\Testbench\Dusk\Options::withoutUI();
3637
}

0 commit comments

Comments
 (0)