Browse Source

Merge pull request #311 from challet/HttpSocket_handle_redirect

optionnaly handles redirect before return the response
José Lorenzo Rodríguez 14 years ago
parent
commit
497ada8895

+ 9 - 0
lib/Cake/Network/Http/HttpResponse.php

@@ -123,6 +123,15 @@ class HttpResponse implements ArrayAccess {
 	public function isOk() {
 		return $this->code == 200;
 	}
+	
+/**
+ * If return is a valid 3xx (Redirection)
+ *
+ * @return boolean
+ */
+	public function isRedirect() {
+		return in_array($this->code, array(301, 302, 303, 307)) && !is_null($this->getHeader('Location'));
+	}
 
 /**
  * Parses the given message and breaks it down in parts.

+ 5 - 0
lib/Cake/Network/Http/HttpSocket.php

@@ -91,6 +91,7 @@ class HttpSocket extends CakeSocket {
 		'protocol' => 'tcp',
 		'port' => 80,
 		'timeout' => 30,
+		'redirect' => false,
 		'request' => array(
 			'uri' => array(
 				'scheme' => 'http',
@@ -377,6 +378,10 @@ class HttpSocket extends CakeSocket {
 			}
 			$this->config['request']['cookies'][$Host] = array_merge($this->config['request']['cookies'][$Host], $this->response->cookies);
 		}
+		if($this->config['redirect'] && $this->response->isRedirect()) {
+			$request['uri'] = $this->response->getHeader('Location');
+			$this->response = $this->request($request);
+		}
 
 		return $this->response;
 	}

+ 36 - 0
lib/Cake/Test/Case/Network/Http/HttpResponseTest.php

@@ -165,6 +165,42 @@ class HttpResponseTest extends CakeTestCase {
 	}
 
 /**
+ * testIsRedirect
+ *
+ * @return void
+ */
+	public function testIsRedirect() {
+		$this->HttpResponse->code = 0;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = -1;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 201;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 'what?';
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 301;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 302;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 303;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 307;
+		$this->assertFalse($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 301;
+		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
+		$this->assertTrue($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 302;
+		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
+		$this->assertTrue($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 303;
+		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
+		$this->assertTrue($this->HttpResponse->isRedirect());
+		$this->HttpResponse->code = 307;
+		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
+		$this->assertTrue($this->HttpResponse->isRedirect());
+	}
+
+/**
  * Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
  *
  * @return void

+ 24 - 1
lib/Cake/Test/Case/Network/Http/HttpSocketTest.php

@@ -252,6 +252,7 @@ class HttpSocketTest extends CakeTestCase {
 			'protocol' => 'tcp',
 			'port' => 23,
 			'timeout' => 30,
+			'redirect' => false,
 			'request' => array(
 				'uri' => array(
 					'scheme' => 'https',
@@ -276,6 +277,7 @@ class HttpSocketTest extends CakeTestCase {
 			'protocol' => 'tcp',
 			'port' => 80,
 			'timeout' => 30,
+			'redirect' => false,
 			'request' => array(
 				'uri' => array(
 					'scheme' => 'http',
@@ -316,13 +318,14 @@ class HttpSocketTest extends CakeTestCase {
 						'protocol' => 'tcp',
 						'port' => 80,
 						'timeout' => 30,
+						'redirect' => false,
 						'request' => array(
 							'uri' => array (
 								'scheme' => 'http',
 								'host' => 'www.cakephp.org',
 								'port' => 80
 							),
-							'cookies' => array(),
+							'cookies' => array()
 						)
 					),
 					'request' => array(
@@ -712,6 +715,26 @@ class HttpSocketTest extends CakeTestCase {
 		$this->assertIsA($response, 'CustomResponse');
 		$this->assertEqual($response->first10, 'HTTP/1.x 2');
 	}
+ 
+
+/**
+ * testRequestWithRedirect method
+ *
+ * @return void
+ */
+	public function testRequestWithRedirect() {
+		$request = array(
+			'uri' => 'http://localhost/oneuri'
+		);
+		$serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
+		$serverResponse2 = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>You have been redirected</h1>";
+		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
+		$this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
+		$this->Socket->config['redirect'] = true;
+	
+		$response = $this->Socket->request($request);
+		$this->assertEquals('<h1>You have been redirected</h1>', $response->body());
+	}
 
 /**
  * testProxy method