From b9ee4fc9f1abd1639bc20a5536f87ad7a5318dea Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 29 Oct 2012 22:28:12 -0400 Subject: [PATCH] URL decode redirect urls. Some servers send url encoded Location headers. Decode location headers before processing a redirect. Fixes #3310 --- lib/Cake/Network/Http/HttpSocket.php | 2 +- .../Test/Case/Network/Http/HttpSocketTest.php | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php index 502505676a9..bda8ec4c766 100644 --- a/lib/Cake/Network/Http/HttpSocket.php +++ b/lib/Cake/Network/Http/HttpSocket.php @@ -403,7 +403,7 @@ public function request($request = array()) { } if ($this->request['redirect'] && $this->response->isRedirect()) { - $request['uri'] = $this->response->getHeader('Location'); + $request['uri'] = trim(urldecode($this->response->getHeader('Location')), '='); $request['redirect'] = is_int($this->request['redirect']) ? $this->request['redirect'] - 1 : $this->request['redirect']; $this->response = $this->request($request); } diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index dfd7db98b21..3fc70d74247 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -762,6 +762,38 @@ public function testRequestCustomResponse() { $this->assertEquals('HTTP/1.x 2', $response->first10); } +/** + * Test that redirect urls are urldecoded + * + * @return void + */ + public function testRequestWithRedirectUrlEncoded() { + $request = array( + 'uri' => 'http://localhost/oneuri', + 'redirect' => 1 + ); + $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://i.cmpnet.com%2Ftechonline%2Fpdf%2Fa.pdf=\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

You have been redirected

"; + + $this->Socket->expects($this->at(1)) + ->method('read') + ->will($this->returnValue($serverResponse1)); + + $this->Socket->expects($this->at(3)) + ->method('write') + ->with($this->logicalAnd( + $this->stringContains('Host: i.cmpnet.com'), + $this->stringContains('GET /techonline/pdf/a.pdf') + )); + + $this->Socket->expects($this->at(4)) + ->method('read') + ->will($this->returnValue($serverResponse2)); + + $response = $this->Socket->request($request); + $this->assertEquals('

You have been redirected

', $response->body()); + } + /** * testRequestWithRedirect method * @@ -781,6 +813,11 @@ public function testRequestWithRedirectAsTrue() { $this->assertEquals('

You have been redirected

', $response->body()); } +/** + * Test that redirects with a count limit are decremented. + * + * @return void + */ public function testRequestWithRedirectAsInt() { $request = array( 'uri' => 'http://localhost/oneuri', @@ -795,6 +832,11 @@ public function testRequestWithRedirectAsInt() { $this->assertEquals(1, $this->Socket->request['redirect']); } +/** + * Test that redirects after the redirect count reaches 9 are not followed. + * + * @return void + */ public function testRequestWithRedirectAsIntReachingZero() { $request = array( 'uri' => 'http://localhost/oneuri',