From d730acba59156884f7a04428dbe3ce956ea7d337 Mon Sep 17 00:00:00 2001 From: Ceeram Date: Thu, 9 Aug 2012 16:11:32 +0200 Subject: [PATCH] Add onlyAllow() to CakeRequest, to check if the request method matches the allowed ones. Throws exception if not matched, using the required Allow response header. --- lib/Cake/Network/CakeRequest.php | 32 +++++++++++++++++ .../Test/Case/Network/CakeRequestTest.php | 34 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index cadbbbd0c..32d7c9744 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -803,6 +803,38 @@ class CakeRequest implements ArrayAccess { return $input; } +/** + * Only allow certain HTTP request methods, if the request method does not match + * a 405 error will be shown and the required "Allow" response header will be set. + * + * Example: + * + * $this->request->onlyAllow('post', 'delete'); + * or + * $this->request->onlyAllow(array('post', 'delete')); + * + * If the request would be GET, response header "Allow: POST, DELETE" will be set + * and a 405 error will be returned + * + * @param string|array $methods Allowed HTTP request methods + * @return boolean true + * @throws MethodNotAllowedException + */ + public function onlyAllow($methods) { + if (!is_array($methods)) { + $methods = func_get_args(); + } + foreach ($methods as $method) { + if ($this->is($method)) { + return true; + } + } + $allowed = strtoupper(implode(', ', $methods)); + $e = new MethodNotAllowedException(); + $e->responseHeader('Allow', $allowed); + throw $e; + } + /** * Read data from php://input, mocked in tests. * diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 8ef0e1868..7853a048d 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -1857,6 +1857,40 @@ XML; $this->assertFalse($request->isRequested()); } +/** + * TestOnlyAllow + * + * @return void + */ + public function testOnlyAllow() { + $_SERVER['REQUEST_METHOD'] = 'PUT'; + $request = new CakeRequest('/posts/edit/1'); + + $this->assertTrue($request->onlyAllow(array('put'))); + + $_SERVER['REQUEST_METHOD'] = 'DELETE'; + $this->assertTrue($request->onlyAllow('post', 'delete')); + } + +/** + * TestOnlyAllow throwing exception + * + */ + public function testOnlyAllowException() { + $_SERVER['REQUEST_METHOD'] = 'PUT'; + $request = new CakeRequest('/posts/edit/1'); + + try { + $request->onlyAllow('POST', 'DELETE'); + $this->fail('An expected exception has not been raised.'); + } catch (MethodNotAllowedException $e) { + $this->assertEquals(array('Allow' => 'POST, DELETE'), $e->responseHeader()); + } + + $this->setExpectedException('MethodNotAllowedException'); + $request->onlyAllow('POST'); + } + /** * loadEnvironment method *