skip to Main Content

So I have a custom PHP MVC framework which works perfectly fine in Apache, but having a hard time adapting it to IIS 10 FastCGI.

Here’s my structure:

/website/
- htaccess / web.config
- app folder -> Libraries (Core, Controller, Database), Controllers, Models, Views, Includes, Helpers, etc
- public folder -> css, js, index.php, htaccess / web.config

Root htaccess looks like this:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule ^$ public/ [L]
  RewriteRule (.*) public/$1 [L]
</IfModule>

Translated that into this web.config:

<rules>
  <rule name="Imported Rule 1" stopProcessing="true">
    <match url="^$" />
    <action type="Rewrite" url="public/" />
  </rule>
  <rule name="Imported Rule 2" stopProcessing="true">
    <match url="(.*)" />
    <action type="Rewrite" url="public/{R:1}" />
  </rule>
</rules>

So, hitting “website” which routes to “website/public” works perfectly fine.

The issue is with the Public web.config. Here’s the htaccess for it:

<IfModule mod_rewrite.c>
  Options -Multiviews
  RewriteEngine On
  RewriteBase /website/public
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
</IfModule>

Web.config translation:

<rule name="Imported Rule 1-1" stopProcessing="true">
  <match url="^(.+)$" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
  </conditions>
  <action type="Rewrite" url="index.php?url={R:1}" appendQueryString="true" />
</rule>

Now I should be able to visit “website/jobs” or “website/jobs/list/0” for instance. Works perfectly fine in Apache, but I get a 404 on IIS. Haven’t been able to resolve in two days.

Appreciate any tips please! Thanks.

[EDIT] Is there any way I can trace the request? I’ve tried the Failed Requests Tracing in IIS as per this link https://wengier.com/debugging-iis-rewrite-rules/ but IIS doesn’t seem to output any 404 errors to the logs. My FRT settings seem to be missing the “RequestRouting” and “Rewrite” options as shown in the link.

[EDIT2] It would seem there is a conflict between the two web.config files. If I disable the root web.config file and then type “website/public/jobs” (instead of “website/jobs” it works.

2

Answers


  1. Chosen as BEST ANSWER

    I fixed it. The two web.configs are conflicting with each other. So, I dropped the public/web.config completely.

    My root web.config now looks like this:

    <rules>
        <rule name="Imported Rule 1" stopProcessing="true">
            <match url="^$" />
            <action type="Rewrite" url="public/" />
        </rule>
        <rule name="Imported Rule 2" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
            </conditions>
            <action type="Rewrite" url="public/index.php?url={R:1}" appendQueryString="true" />
        </rule>
    </rules>
    

  2. Open iis select /website/public open URL Rewrite Import Rules UI, comment out the rewrite base /website/public line and import remaining rules. This will result in rewrite rules saved into the web.config file located in that directory. That will give you the same behavior as a rewrite base gives on apache.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search