zendframework / zend-mvc

Mvc component from Zend Framework
BSD 3-Clause "New" or "Revised" License
105 stars 90 forks source link

Using forward/dispatch results in different RouteMatch class object #174

Open GeeH opened 8 years ago

GeeH commented 8 years ago

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7389 User: @kuldeep-k Created On: 2015-03-31T08:32:24Z Updated At: 2015-11-06T21:05:11Z Body I am building a rest based auth forwarding. So I do code like below in listener class

public function __invoke(MvcEvent $event)
{
    print_r($event->getRouteMatch());
    $result = $this->adapter->authenticate();
    $routeMatch = $event->getRouteMatch();

    if (!$result->isValid()) {

        $response = $event->getResponse();

        $response->setStatusCode(401);

        /*$routeMatch = $event->getRouteMatch();
        $routeMatch->setParam('controller', 'Rest\Controller\Error');
        $routeMatch->setParam('action', 'auth');
        */

        $cpm = $this->getServiceLocator()->get('ControllerPluginManager');
        $fwd = $cpm->get('forward');
        return $fwd->dispatch('Rest\Controller\Error', array('action' => 'auth'));
    }
}

So first time request comes for controller Rest\Controller\Index action index (matched route "rest") but due to authentication failure forward happens to controller Rest\Controller\Error action auth (matched route "rest-error")

However what is printed is below

Zend\Mvc\Router\Http\RouteMatch Object
(
    [length:protected] => 5
    [params:protected] => Array
        (
            [controller] => Rest\Controller\Index
        )

    [matchedRouteName:protected] => rest
)
Zend\Mvc\Router\RouteMatch Object
(
    [params:protected] => Array
        (
            [action] => auth
        )

    [matchedRouteName:protected] => rest
)
Zend\Mvc\Router\RouteMatch Object
(
    [params:protected] => Array
        (
            [action] => auth
        )

    [matchedRouteName:protected] => rest
)

Which show that first request go to Zend\Mvc\Router\Http\RouteMatch while subsequent request goes to Zend\Mvc\Router\RouteMatch ( Due to not check of safe route request recursively goes end throw expected error "Circular forwarding detected")

Now from second request do not have controller information also, It matched to wrong matchedRouteName.

module.config.php have these routes

'routes' => array(
    'rest' => array(
        'type' => 'Zend\Mvc\Router\Http\Segment',
        'options' => array(
            'route'    => '/rest[/:id]',
            'constraints' => array(
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'Rest\Controller\Index'
            ),
        ),
    ),
    'rest-error' => array(
        'type' => 'Zend\Mvc\Router\Http\Segment',
        'options' => array(
            'route'    => '/resterror',
            'constraints' => array(
                'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'Rest\Controller\Error',
                'action'     => 'auth',
            ),
        ),
    )
),

I tried on Zend Framework v2.3.4 & v2.2.4 .


weierophinney commented 4 years ago

This repository has been closed and moved to laminas/laminas-mvc; a new issue has been opened at https://github.com/laminas/laminas-mvc/issues/27.