Merge pull request #12472 from owncloud/modifyCookies

Add functions to modify cookies to response class
This commit is contained in:
Morris Jobke 2014-11-28 10:16:22 +01:00
commit b188710af3
9 changed files with 207 additions and 25 deletions

View File

@ -466,7 +466,7 @@ class OC {
}
// setup the basic server
self::$server = new \OC\Server();
self::$server = new \OC\Server(\OC::$WEBROOT);
\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
\OC::$server->getEventLogger()->start('boot', 'Initialize');

View File

@ -53,7 +53,7 @@ class App {
// initialize the dispatcher and run all the middleware before the controller
$dispatcher = $container['Dispatcher'];
list($httpHeaders, $responseHeaders, $output) =
list($httpHeaders, $responseHeaders, $responseCookies, $output) =
$dispatcher->dispatch($controller, $methodName);
if(!is_null($httpHeaders)) {
@ -64,6 +64,14 @@ class App {
header($name . ': ' . $value);
}
foreach($responseCookies as $name => $value) {
$expireDate = null;
if($value['expireDate'] instanceof \DateTime) {
$expireDate = $value['expireDate']->getTimestamp();
}
setcookie($name, $value['value'], $expireDate, $container->getServer()->getWebRoot(), null, $container->getServer()->getConfig()->getSystemValue('forcessl', false), true);
}
if(!is_null($output)) {
header('Content-Length: ' . strlen($output));
print($output);

View File

@ -48,7 +48,7 @@ class Dispatcher {
* @param Http $protocol the http protocol with contains all status headers
* @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which
* runs the middleware
* @param ControllerMethodReflector the reflector that is used to inject
* @param ControllerMethodReflector $reflector the reflector that is used to inject
* the arguments for the controller
* @param IRequest $request the incoming request
*/
@ -71,6 +71,7 @@ class Dispatcher {
* @return array $array[0] contains a string with the http main header,
* $array[1] contains headers in the form: $key => value, $array[2] contains
* the response output
* @throws \Exception
*/
public function dispatch(Controller $controller, $methodName) {
$out = array(null, array(), null);
@ -102,13 +103,14 @@ class Dispatcher {
// get the output which should be printed and run the after output
// middleware to modify the response
$output = $response->render();
$out[2] = $this->middlewareDispatcher->beforeOutput(
$out[3] = $this->middlewareDispatcher->beforeOutput(
$controller, $methodName, $output);
// depending on the cache object the headers need to be changed
$out[0] = $this->protocol->getStatusHeader($response->getStatus(),
$response->getLastModified(), $response->getETag());
$out[1] = $response->getHeaders();
$out[1] = array_merge($response->getHeaders());
$out[2] = $response->getCookies();
return $out;
}

View File

@ -29,19 +29,27 @@ use OC\Tagging\TagMapper;
* TODO: hookup all manager classes
*/
class Server extends SimpleContainer implements IServerContainer {
function __construct() {
/** @var string */
private $webRoot;
/**
* @param string $webRoot
*/
function __construct($webRoot) {
$this->webRoot = $webRoot;
$this->registerService('ContactsManager', function ($c) {
return new ContactsManager();
});
$this->registerService('Request', function ($c) {
$this->registerService('Request', function (Server $c) {
if (isset($c['urlParams'])) {
$urlParams = $c['urlParams'];
} else {
$urlParams = array();
}
if (\OC::$server->getSession()->exists('requesttoken')) {
$requestToken = \OC::$server->getSession()->get('requesttoken');
if ($c->getSession()->exists('requesttoken')) {
$requestToken = $c->getSession()->get('requesttoken');
} else {
$requestToken = false;
}
@ -233,8 +241,7 @@ class Server extends SimpleContainer implements IServerContainer {
return new NullQueryLogger();
}
});
$this->registerService('TempManager', function ($c) {
/** @var Server $c */
$this->registerService('TempManager', function (Server $c) {
return new TempManager(get_temp_dir(), $c->getLogger());
});
$this->registerService('AppManager', function(Server $c) {
@ -631,4 +638,13 @@ class Server extends SimpleContainer implements IServerContainer {
function getAppManager() {
return $this->query('AppManager');
}
/**
* Get the webroot
*
* @return string
*/
function getWebRoot() {
return $this->webRoot;
}
}

View File

@ -45,9 +45,16 @@ class Response {
);
/**
* Cookies that will be need to be constructed as header
* @var array
*/
private $cookies = array();
/**
* HTTP status code - defaults to STATUS OK
* @var string
* @var int
*/
private $status = Http::STATUS_OK;
@ -70,6 +77,7 @@ class Response {
* Caches the response
* @param int $cacheSeconds the amount of seconds that should be cached
* if 0 then caching will be disabled
* @return $this
*/
public function cacheFor($cacheSeconds) {
@ -83,13 +91,68 @@ class Response {
return $this;
}
/**
* Adds a new cookie to the response
* @param string $name The name of the cookie
* @param string $value The value of the cookie
* @param \DateTime|null $expireDate Date on that the cookie should expire, if set
* to null cookie will be considered as session
* cookie.
* @return $this
*/
public function addCookie($name, $value, \DateTime $expireDate = null) {
$this->cookies[$name] = array('value' => $value, 'expireDate' => $expireDate);
return $this;
}
/**
* Set the specified cookies
* @param array $cookies array('foo' => array('value' => 'bar', 'expire' => null))
* @return $this
*/
public function setCookies(array $cookies) {
$this->cookies = $cookies;
return $this;
}
/**
* Invalidates the specified cookie
* @param string $name
* @return $this
*/
public function invalidateCookie($name) {
$this->addCookie($name, 'expired', new \DateTime('1971-01-01 00:00'));
return $this;
}
/**
* Invalidates the specified cookies
* @param array $cookieNames array('foo', 'bar')
* @return $this
*/
public function invalidateCookies(array $cookieNames) {
foreach($cookieNames as $cookieName) {
$this->invalidateCookie($cookieName);
}
return $this;
}
/**
* Returns the cookies
* @return array
*/
public function getCookies() {
return $this->cookies;
}
/**
* Adds a new header to the response that will be called before the render
* function
* @param string $name The name of the HTTP header
* @param string $value The value, null will delete it
* @return Response Reference to this object
* @return $this
*/
public function addHeader($name, $value) {
$name = trim($name); // always remove leading and trailing whitespace
@ -108,10 +171,10 @@ class Response {
/**
* Set the headers
* @param array key value header pairs
* @return Response Reference to this object
* @param array $headers value header pairs
* @return $this
*/
public function setHeaders($headers) {
public function setHeaders(array $headers) {
$this->headers = $headers;
return $this;

View File

@ -298,4 +298,11 @@ interface IServerContainer {
* @return \OCP\App\IAppManager
*/
function getAppManager();
/**
* Get the webroot
*
* @return string
*/
function getWebRoot();
}

View File

@ -63,7 +63,7 @@ class AppTest extends \Test\TestCase {
public function testControllerNameAndMethodAreBeingPassed(){
$return = array(null, array(), null);
$return = array(null, array(), array(), null);
$this->dispatcher->expects($this->once())
->method('dispatch')
->with($this->equalTo($this->controller),

View File

@ -227,7 +227,7 @@ class DispatcherTest extends \Test\TestCase {
$this->assertEquals($httpHeaders, $response[0]);
$this->assertEquals($responseHeaders, $response[1]);
$this->assertEquals($out, $response[2]);
$this->assertEquals($out, $response[3]);
}
@ -246,7 +246,7 @@ class DispatcherTest extends \Test\TestCase {
$this->assertEquals($httpHeaders, $response[0]);
$this->assertEquals($responseHeaders, $response[1]);
$this->assertEquals($out, $response[2]);
$this->assertEquals($out, $response[3]);
}
@ -301,7 +301,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'exec');
$this->assertEquals('[3,true,4,1]', $response[2]);
$this->assertEquals('[3,true,4,1]', $response[3]);
}
@ -324,7 +324,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'exec');
$this->assertEquals('[3,true,4,7]', $response[2]);
$this->assertEquals('[3,true,4,7]', $response[3]);
}
@ -350,7 +350,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'exec');
$this->assertEquals('{"text":[3,false,4,1]}', $response[2]);
$this->assertEquals('{"text":[3,false,4,1]}', $response[3]);
}
@ -375,7 +375,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'execDataResponse');
$this->assertEquals('{"text":[3,false,4,1]}', $response[2]);
$this->assertEquals('{"text":[3,false,4,1]}', $response[3]);
}
@ -401,7 +401,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'exec');
$this->assertEquals('{"text":[3,false,4,1]}', $response[2]);
$this->assertEquals('{"text":[3,false,4,1]}', $response[3]);
}
@ -429,7 +429,7 @@ class DispatcherTest extends \Test\TestCase {
$this->dispatcherPassthrough();
$response = $this->dispatcher->dispatch($controller, 'exec');
$this->assertEquals('{"text":[3,true,4,1]}', $response[2]);
$this->assertEquals('{"text":[3,true,4,1]}', $response[3]);
}

View File

@ -76,6 +76,92 @@ class ResponseTest extends \Test\TestCase {
}
public function testAddCookie() {
$this->childResponse->addCookie('foo', 'bar');
$this->childResponse->addCookie('bar', 'foo', new \DateTime('1970-01-01'));
$expectedResponse = array(
'foo' => array(
'value' => 'bar',
'expireDate' => null,
),
'bar' => array(
'value' => 'foo',
'expireDate' => new \DateTime('1970-01-01')
)
);
$this->assertEquals($expectedResponse, $this->childResponse->getCookies());
}
function testSetCookies() {
$expected = array(
'foo' => array(
'value' => 'bar',
'expireDate' => null,
),
'bar' => array(
'value' => 'foo',
'expireDate' => new \DateTime('1970-01-01')
)
);
$this->childResponse->setCookies($expected);
$cookies = $this->childResponse->getCookies();
$this->assertEquals($expected, $cookies);
}
function testInvalidateCookie() {
$this->childResponse->addCookie('foo', 'bar');
$this->childResponse->invalidateCookie('foo');
$expected = array(
'foo' => array(
'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01')
)
);
$cookies = $this->childResponse->getCookies();
$this->assertEquals($expected, $cookies);
}
function testInvalidateCookies() {
$this->childResponse->addCookie('foo', 'bar');
$this->childResponse->addCookie('bar', 'foo');
$expected = array(
'foo' => array(
'value' => 'bar',
'expireDate' => null
),
'bar' => array(
'value' => 'foo',
'expireDate' => null
)
);
$cookies = $this->childResponse->getCookies();
$this->assertEquals($expected, $cookies);
$this->childResponse->invalidateCookies(array('foo', 'bar'));
$expected = array(
'foo' => array(
'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01')
),
'bar' => array(
'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01')
)
);
$cookies = $this->childResponse->getCookies();
$this->assertEquals($expected, $cookies);
}
public function testRenderReturnNullByDefault(){
$this->assertEquals(null, $this->childResponse->render());
}