ZF-4491: Support the new Microsoft URL Rewrite Module for IIS 7.0

Issue Type: New Feature Created: 2008-10-05T10:21:15.000+0000 Last Updated: 2012-06-14T17:23:43.000+0000 Status: Closed Fix version(s): - 1.12.0 (27/Aug/12)

Reporter: Erwin Derksen (erwind) Assignee: Rob Allen (rob) Tags: - Zend_Controller

  • FixForZF1.12

Related issues: Attachments:


Microsoft has recently released its own rewrite module for IIS7.0. (See:…). I was trying to get it to work with your quick start application and found out that it is not completely working as expected. This because this new module uses the HTTP_X_ORIGINAL_URL header instead of the HTTP_X_REWRITE_URL header as used by the isapi_rewrite extension. As a consequence I always got the index controller and action for every request made and thus never got the error page for calls to bogus controllers/actions. Exception: when using the http://localhost/myapplication/index.php/… syntax, it already works fine.

As a newbie to the Zend framework I have no idea if what I did is correct and works in all cases, but as an experienced developer I managed to get it to work by doing a global search for all uses of HTTP_X_REWRITE_URL and adding an additional if branch for the HTTP_X_ORIGINAL_URL as well:

Find results: Zend\Controller\Request\Apache404.php(50): if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch Zend\Controller\Request\Apache404.php(51): $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; Zend\Controller\Request\Http.php(381): * $_SERVER['HTTP_X_REWRITE_URL'], or $_SERVER['ORIG_PATH_INFO'] + $_SERVER['QUERY_STRING']. Zend\Controller\Request\Http.php(389): if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch Zend\Controller\Request\Http.php(390): $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; Zend\OpenId.php(110): if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { Zend\OpenId.php(111): $url .= $_SERVER['HTTP_X_REWRITE_URL'];

Changes made (this is for OpenId.php, other files have similar changes) (basically add an if elseif for the new HTTP_X_ORIGINAL_URL header): if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { // check this first so IIS will catch $url .= $_SERVER['HTTP_X_ORIGINAL_URL']; } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch


Posted by Brian Reich (breich) on 2009-03-16T09:41:47.000+0000

The simplest way that I've found to get around this issue is to add the following lines to my bootstrap file, prior to any calls to Zend_Controller_Front::getInstance():

/* * For IIS 7.0 Rewrite Module - allows use of "clean" URL syntax instead of * index.php/controller/action/ by copying original URL value set by the rewrite * module to the server variable expected by the Rewrite Router. */ if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {



Posted by Bruno B B Magalhães (brunobbmagalhaes) on 2009-08-12T09:23:03.000+0000

To fix this issue, the method setRequestUri within Zend_Controller_Request_Http class must be changed as this (line 383):

<pre class="highlight"> 
     * Set the REQUEST_URI on which the instance operates
     * If no request URI is passed, uses the value in $_SERVER['REQUEST_URI'],
     * @param string $requestUri
     * @return Zend_Controller_Request_Http
    public function setRequestUri($requestUri = null)
        if ($requestUri === null) {
            if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { // check IIS 7.x with Microsoft Rewrite Module
                $requestUri = $_SERVER['HTTP_X_ORIGINAL_URL'];
            elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check IIS with ISAPI_Rewrite, etc
                $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
            } elseif (isset($_SERVER['REQUEST_URI'])) {
                $requestUri = $_SERVER['REQUEST_URI'];
                // Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
                $schemeAndHttpHost = $this->getScheme() . '://' . $this->getHttpHost();
                if (strpos($requestUri, $schemeAndHttpHost) === 0) {
                    $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
            } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
                $requestUri = $_SERVER['ORIG_PATH_INFO'];
                if (!empty($_SERVER['QUERY_STRING'])) {
                    $requestUri .= '?' . $_SERVER['QUERY_STRING'];
            } else {
                return $this;
        } elseif (!is_string($requestUri)) {
            return $this;
        } else {
            // Set GET items, if available
            if (false !== ($pos = strpos($requestUri, '?'))) {
                // Get key => value pairs and set $_GET
                $query = substr($requestUri, $pos + 1);
                parse_str($query, $vars);

        $this->_requestUri = $requestUri;
        return $this;

I've already tested it in a development server running Windows Server 2003 SP3 + IIS 7.0 + Rewrite Module, and worked as expercted.

Best Regards, Bruno B B Magalhães

Posted by Matthew Weier O'Phinney (matthew) on 2009-08-15T13:57:52.000+0000

Reopening, as no patch has been applied. :)

Posted by Ian Unruh (iunruh) on 2012-05-31T16:05:23.000+0000

This needs to be fixed. IIS 7.0+ is default in Windows Server 2003, Server 2008, Server 2008 R2, and Windows 7. This issue affects anyone using those operating systems with IIS and the URL Rewrite module.

Posted by Evan Coury ( on 2012-06-13T16:57:37.000+0000

This is fixed in ZF2 with PR 1424.

Posted by Frank Brückner (frosch) on 2012-06-14T17:22:47.000+0000

Fixed in svn r24842 by rob (Rob Allen).

Have you found an issue?

See the Overview section for more details.


© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.