Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
569 views
in Technique[技术] by (71.8m points)

tomcat - ColdFusion 10 + IIS: Non-existant URLs that are CFM files. Retrieving original URL after executing 404 page

We have a server setup as follows:

  • Windows 2012 R2
  • Coldfusion 10, Enterprise
  • IIS, configure with custom 404 page (execute on server)

The custom 404 page (a CFM file) handles missing URLs and checks them against custom URLs in the database. If it finds a match, it will display the relevant data. The problem occurs when the custom URL maps to a non-existant CFM file; for example.

/home/map.cfm (not a real file or directory)

Now, when a user requests this URL, the server sees that it is a CFM file and correctly passes it to ColdFusion (via the ISAPI redirect). Tomcat sees that this file does not actually exist, and returns a 404. IIS sees this 404 message and executes the custom error page (/errors/404.cfm).

The resulting CGI variables do not infact allow us to retrieve the original URL (to map it to a virtual URL in the database), usually provided as part of the CGI.QUERY_STRING variable. Instead, the QUERY_STRING variable contains the path to the 'isapi_rewrite.dll' file, in the 'jakarta' directory.

Is there any way to retain the originally requested URL (of a CFM file), after Tomcat has returned a 404 error for said page?

Solution, put together by myself, inspired by Thomas Gorgolione

As suspected, the issue invariably came down to the request being forwarded to the ISAPI_REDIRECT module, even if the file in question did not exist.

As Thomas suggested, an elegant solution is to utilize rewrites to check that the file / directory actually exists, before passing it through to the ISAPI_REDIRECT module.

While the software Thomas suggested would of done the trick, I was unable to get it to install on a 64bit Windows 2012 R2 machine. I've managed however to fall back to utilize the URL Rewrite module included with IIS8 (and possibly earlier versions).

See my web.config entry below that provides a solution.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors>
            <remove statusCode="404" subStatusCode="-1" />
        </httpErrors>
        <rewrite>
            <rules>
                <rule name="404 HTTP">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{REQUEST_URI}" pattern="CFFileServlet/(.*)" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{SERVER_PORT_SECURE}" pattern="0" />
                    </conditions>
                    <action type="Rewrite" url="/404.cfm?404;http://{HTTP_HOST}:{SERVER_PORT}{REQUEST_URI}" />
                </rule>
                <rule name="404 HTTPS">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{REQUEST_URI}" pattern="CFFileServlet/(.*)" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{SERVER_PORT_SECURE}" pattern="1" />
                    </conditions>
                    <action type="Rewrite" url="/404.cfm?404;https://{HTTP_HOST}:{SERVER_PORT}{REQUEST_URI}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

The above configuration file takes into account both HTTP and HTTPS requests. It will also take into account the the CFFileServlet directory, which ColdFusion uses to host temporary images and assets. If the URL starts with this directory, it will be passed on as a normal request.

Thanks for your input everyone.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

NOTE: Question above includes a solution as well.

I think this is an error with the Coldfusion Connector. I would post a bug report to Adobe (https://bugbase.adobe.com/). I do have a workaround though. I have the same issue, but I use IIRF (Ionic IIS Redirector - http://iirf.codeplex.com/), and I found a way to use that to avoid the bug for now:

  1. Remove any previous 404 file configuration in IIS/Coldfusion
  2. Install IIRF normally, according to it's install instructions.
  3. In the IirfGlobal.ini file (normally located in C:WindowsSystem32inetsrvIIRF), add the following line:

    RewriteFilterPriority HIGH
    

    This will allow IIRF to handle 404 requests before it even hits ColdFusion/Tomcat.

  4. In the site-specific Iirf.ini (usually you create one in the root folder of your web files -- see the IIRF docs for details), add the following rules:

    RewriteCond %{SCRIPT_TRANSLATED} !-f
    RewriteCond %{SCRIPT_TRANSLATED} !-d
    RewriteRule ^(.+)$ page_to_redirect_to.cfm?404;$1 [L]
    

    That will redirect all files/directories that don't exist to page_to_redirect_to.cfm, and add the 404 query string like normal.

  5. EDIT: Added a following step: Go into the IIS Manager and select either the server or the Web Site that was configured to use IIRF, then go into the ISAPI Filters section. Click on "View Ordered List", then move the IIRF filter up to the top.

EDIT 2: Just posted a bug to Adobe. See https://bugbase.adobe.com/index.cfm?event=bug&id=3630245

Hope that helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...