Browse Source

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.

Ceeram 13 years ago
parent
commit
d730acba59
2 changed files with 66 additions and 0 deletions
  1. 32 0
      lib/Cake/Network/CakeRequest.php
  2. 34 0
      lib/Cake/Test/Case/Network/CakeRequestTest.php

+ 32 - 0
lib/Cake/Network/CakeRequest.php

@@ -804,6 +804,38 @@ class CakeRequest implements ArrayAccess {
 	}
 
 /**
+ * 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.
  *
  * @return string contents of php://input

+ 34 - 0
lib/Cake/Test/Case/Network/CakeRequestTest.php

@@ -1858,6 +1858,40 @@ XML;
 	}
 
 /**
+ * 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
  *
  * @param array $env