Browse Source

Merge pull request #7515 into master.

Fixes requesthandler incorrectly handling query string data when
converting redirects into requestaction.
Mark Story 10 years ago
parent
commit
62f30de3e5

+ 7 - 1
src/Controller/Component/RequestHandlerComponent.php

@@ -259,13 +259,19 @@ class RequestHandlerComponent extends Component
         if (is_array($url)) {
             $url = Router::url($url + ['_base' => false]);
         }
+        $query = [];
+        if (strpos($url, '?') !== false) {
+            list($url, $querystr) = explode('?', $url, 2);
+            parse_str($querystr, $query);
+        }
         $controller = $event->subject();
         $response->body($controller->requestAction($url, [
             'return',
             'bare' => false,
             'environment' => [
                 'REQUEST_METHOD' => 'GET'
-            ]
+            ],
+            'query' => $query
         ]));
         $response->statusCode(200);
         return $response;

+ 39 - 0
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -903,6 +903,45 @@ class RequestHandlerComponentTest extends TestCase
     }
 
     /**
+     * Test that AJAX requests involving redirects handle querystrings
+     *
+     * @return void
+     * @triggers Controller.beforeRedirect $this->Controller
+     */
+    public function testAjaxRedirectAsRequestActionWithQueryString()
+    {
+        Configure::write('App.namespace', 'TestApp');
+        Router::connect('/:controller/:action');
+        $event = new Event('Controller.beforeRedirect', $this->Controller);
+
+        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->Controller->request = $this->getMock('Cake\Network\Request', ['is']);
+        $this->Controller->response = $this->getMock('Cake\Network\Response', ['_sendHeader', 'stop']);
+        $this->Controller->RequestHandler->request = $this->Controller->request;
+        $this->Controller->RequestHandler->response = $this->Controller->response;
+        $this->Controller->request->expects($this->any())
+            ->method('is')
+            ->with('ajax')
+            ->will($this->returnValue(true));
+
+        $response = $this->Controller->RequestHandler->beforeRedirect(
+            $event,
+            '/request_action/params_pass?a=b&x=y?ish',
+            $this->Controller->response
+        );
+        $data = json_decode($response, true);
+        $this->assertEquals('/request_action/params_pass', $data['here']);
+
+        $response = $this->Controller->RequestHandler->beforeRedirect(
+            $event,
+            '/request_action/query_pass?a=b&x=y?ish',
+            $this->Controller->response
+        );
+        $data = json_decode($response, true);
+        $this->assertEquals('y?ish', $data['x']);
+    }
+
+    /**
      * Tests that AJAX requests involving redirects don't let the status code bleed through.
      *
      * @return void

+ 1 - 0
tests/test_app/TestApp/Controller/RequestActionController.php

@@ -118,6 +118,7 @@ class RequestActionController extends AppController
         $this->response->body(json_encode([
             'params' => $this->request->params,
             'base' => $this->request->base,
+            'here' => $this->request->here,
             'webroot' => $this->request->webroot,
             'params' => $this->request->params,
             'query' => $this->request->query,