Skip to content

Commit

Permalink
fixed session management in functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Apr 13, 2011
1 parent 6957dae commit ea84bb0
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 53 deletions.
Expand Up @@ -85,7 +85,7 @@ public function load(array $configs, ContainerBuilder $container)
if (!empty($config['test'])) {
$loader->load('test.xml');
if (isset($config['session'])) {
$config['session']['storage_id'] = 'array';
$config['session']['storage_id'] = 'filesystem';
}
}

Expand Down

This file was deleted.

Expand Up @@ -10,8 +10,8 @@
<parameter key="session.storage.native.options" type="collection" />
<parameter key="session.storage.pdo.class">Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage</parameter>
<parameter key="session.storage.pdo.options" type="collection" />
<parameter key="session.storage.array.class">Symfony\Component\HttpFoundation\SessionStorage\ArraySessionStorage</parameter>
<parameter key="session.storage.array.options" type="collection" />
<parameter key="session.storage.filesystem.class">Symfony\Component\HttpFoundation\SessionStorage\FilesystemSessionStorage</parameter>
<parameter key="session.storage.filesystem.options" type="collection" />
</parameters>

<services>
Expand All @@ -29,8 +29,9 @@
<argument>%session.storage.pdo.options%</argument>
</service>

<service id="session.storage.array" class="%session.storage.array.class%" public="false">
<argument>%session.storage.array.options%</argument>
<service id="session.storage.filesystem" class="%session.storage.filesystem.class%" public="false">
<argument>%kernel.cache_dir%/sessions</argument>

This comment has been minimized.

Copy link
@greg0ire

greg0ire Jul 24, 2015

Contributor

@fabpot : what is the rationale behind this choice ? As a result, every user is logged out on every delivery, that's why I'm asking. Maybe there should be a dedicated directory outside the cache (app/data/sessions? var/sessions? )?

This comment has been minimized.

Copy link
@sstok

sstok Jul 25, 2015

Contributor

fabpot authored on 13 Apr 2011

I think its better to open an new issue with the actual problem you have rather then adding your question on an 4 year old commit 😄

This comment has been minimized.

Copy link
@greg0ire

greg0ire Jul 25, 2015

Contributor

Fair enough. See #15359

<argument>%session.storage.filesystem.options%</argument>
</service>

<service id="session.storage" alias="session.storage.native" public="false" />
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml
Expand Up @@ -9,7 +9,7 @@
<parameter key="test.client.parameters" type="collection"></parameter>
<parameter key="test.client.history.class">Symfony\Component\BrowserKit\History</parameter>
<parameter key="test.client.cookiejar.class">Symfony\Component\BrowserKit\CookieJar</parameter>
<parameter key="test.session.listener.class">Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener</parameter>
<parameter key="test.session.listener.class">Symfony\Bundle\FrameworkBundle\Test\SessionListener</parameter>
</parameters>

<services>
Expand All @@ -25,6 +25,8 @@
<service id="test.client.cookiejar" class="%test.client.cookiejar.class%" scope="prototype" />

<service id="test.session.listener" class="%test.session.listener.class%">
<argument type="service" id="service_container" />
<tag name="kernel.listener" event="onCoreRequest" priority="128" />
<tag name="kernel.listener" event="onCoreResponse" priority="-128" />
</service>
</services>
Expand Down
76 changes: 76 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Test/SessionListener.php
@@ -0,0 +1,76 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\FrameworkBundle\Test;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* SessionListener.
*
* Saves session in test environment.
*
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
* @author Fabien Potencier <fabien@symfony.com>
*/
class SessionListener
{
protected $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function onCoreRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}

// bootstrap the session
if ($this->container->has('session')) {
$this->container->get('session');
}

$cookies = $event->getRequest()->cookies;
if ($cookies->has(session_name())) {
session_id($cookies->get(session_name()));
}
}

/**
* Checks if session was initialized and saves if current request is master
* Runs on 'onCoreResponse' in test environment
*
* @param FilterResponseEvent $event
*/
public function onCoreResponse(FilterResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}

if ($session = $event->getRequest()->getSession()) {
$session->save();

$params = session_get_cookie_params();

$event->getResponse()->headers->setCookie(new Cookie(session_name(), session_id(), time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
}
}
}
Expand Up @@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\FrameworkBundle\Tests\HttpFoundation;
namespace Symfony\Bundle\FrameworkBundle\Tests\Test;

use Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener;
use Symfony\Bundle\FrameworkBundle\Test\SessionListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
Expand All @@ -31,7 +31,7 @@ class SessionListenerTest extends \PHPUnit_Framework_TestCase

public function setUp()
{
$this->listener = new SessionListener();
$this->listener = new SessionListener($this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'));
$this->session = $this->getSession();
}

Expand Down
Empty file.
@@ -0,0 +1,90 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpFoundation\SessionStorage;

/**
* FilesystemSessionStorage.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class FilesystemSessionStorage extends NativeSessionStorage
{
private $path;
private $data;

public function __construct($path, array $options = array())
{
$this->path = $path;

parent::__construct($options);
}

public function start()
{
if (self::$sessionStarted) {

This comment has been minimized.

Copy link
@kriswallsmith

kriswallsmith Apr 20, 2011

Contributor

This variable is never set to true and session_start() is never called -- are these things intentional?

return;
}

session_set_cookie_params(
$this->options['lifetime'],
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
);

if (!ini_get('session.use_cookies') && $this->options['id'] && $this->options['id'] != session_id()) {
session_id($this->options['id']);
}

if (!session_id()) {
session_id(hash('md5', uniqid(mt_rand(), true)));
}

if (!is_dir($this->path)) {
mkdir($this->path, 0777, true);
}

$file = $this->path.'/'.session_id().'.session';

$this->data = file_exists($file) ? unserialize(file_get_contents($file)) : array();
}

public function read($key, $default = null)
{
return array_key_exists($key, $this->data) ? $this->data[$key] : $default;
}

public function remove($key)
{
$retval = $this->data[$key];

unset($this->data[$key]);

return $retval;
}

public function write($key, $data)
{
$this->data[$key] = $data;

file_put_contents($this->path.'/'.session_id().'.session', serialize($this->data));
}

public function regenerate($destroy = false)
{
if ($destroy) {
$this->data = array();
}
return true;
}
}

1 comment on commit ea84bb0

@avalanche123
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is huge, thank you for that

Please sign in to comment.