Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Fake ISAPI Handler to Serve Static Files with Extensions that are Rewritten by URL Rewriter

, 22 Apr 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Fake ISAPI Handler to Serve Static Files with Extensions that are Rewritten by URL Rewriter

Introduction

I often map HTML extension to the ASP.NET DLL in order to use URL rewriter with .html extensions. In a recent project, we renamed all URLs to end with .html. This works great, but failed when we used FCK Editor. Static HTML files would not get served because we mapped the HTML extension to the .NET Framework. We can use .html extension with our rewriter but still want to use IIS behavior with static HTML files.

Analysis

I thought that this could be resolved with a simple HTTP handler. We would map URLs of static files in our rewriter to this handler that would read the static file and serve it, just as IIS would do.

Implementation

This is how I coded the class. Note that this may not be bullet proof. I only tested it once and I am sure that the logic behind IIS is more complicated that this. If you find errors or think of possible improvements, let me know.

Imports System.Web
Imports System.Web.Services

' Author: Nicolas Brassard
' For: Solutions Nitriques inc. http://www.nitriques.com
' Date Created: April 18, 2009
' Last Modified: April 18, 2009
' License: CPOL (http://www.codeproject.com/info/cpol10.aspx)
' Files: ISAPIDotNetHandler.ashx
'        ISAPIDotNetHandler.ashx.vb
' Class: ISAPIDotNetHandler
' Description: Fake ISAPI handler to serve static files.
'               Useful when you want to serve static file that has a rewritten extension.
'               Example: It often maps HTML extension to the ASP.NET DLL 
'               in order to use URL rewriter with .html.
'               If you want to still serve static HTML file, 
'               add a rewriter rule to redirect HTML files to this handler

Public Class ISAPIDotNetHandler
    Implements System.Web.IHttpHandler

    Sub ProcessRequest(ByVal context As HttpContext) _
			Implements IHttpHandler.ProcessRequest
        ' Since we are doing the job IIS normally does with HTML files,
        ' we set the content type to match HTML.
        ' You may want to customize this with your own logic, if you want to serve
        ' txt or XML or any other text file
        context.Response.ContentType = "text/html"

        ' We begin a try here. Any error that occurs will result in a 
        ' 404 Page Not Found error.
        ' We replicate the behavior of IIS when it doesn't find the corresponding file.
        Try

            ' Declare a local variable containing the value of the query string
            Dim uri As String = context.Request("fileUri")

            ' If the value in the query string is null,
            ' throw an error to generate a 404
            If String.IsNullOrEmpty(uri) Then
                Throw New ApplicationException("No fileUri")
            End If

            ' If the value in the query string doesn't end with .html, 
	   ' then block the access
            ' This is a HUGE security hole since it could permit full read 
	   ' access to .aspx, .config, etc.
            If Not uri.ToLower.EndsWith(".html") Then
                ' throw an error to generate a 404
                Throw New ApplicationException("Extension not allowed")
            End If

            ' Map the file on the server.
            ' If the file doesn't exists on the server, 
	   ' it will throw an exception and generate a 404.
            Dim fullPath As String = context.Server.MapPath(uri)
            ' Read the actual file
            Dim stream As IO.StreamReader = _
			FileIO.FileSystem.OpenTextFileReader(fullPath)
            ' Write the file into the response
            context.Response.Output.Write(stream.ReadToEnd)
            ' Close and Dispose the stream
            stream.Close()
            stream.Dispose()
            stream = Nothing

        Catch ex As Exception
            ' Set the Status Code of the response
            context.Response.StatusCode = 404 'Page not found

            ' For testing and debugging only ! This may cause a security leak
            ' context.Response.Output.Write(ex.Message)
        Finally
            ' In all cases, flush and end the response
            context.Response.Flush()
            context.Response.End()
        End Try
    End Sub

    ' Automatically generated by Visual Studio
    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

Conclusion

As you see, with our static files mapping to this handler using query string (e.g.: /ISAPIDotNetHandler.ashx?fileUri=index.html) you will have the same behavior as if you ask for the URL/index.html.

Finally, test this only in IIS with the HTML extension map to aspnet_isapi.dll. URL rewriting will work in Casini (Internal Web Server shipped with Visual Studio) but it's not the same as with IIS since EVERY request is handled by .NET.

Versions

  • First release

Category: CodeProject
Published: 4/19/2009 11:25 PM

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Nicolas Brassard
President Solutions Nitriques inc.
Canada Canada
I am the general director of Nitriques Solutions inc. We build software and web solutions for enterprises using .NET 2.0 and 3.5, MS-SQL Server 2005 running on various Server 2003.
 
We offer a variety of products, from simple corporate web site with CMS to complete integration of intranets.
 
I have been working with asp et MS-SQL since 2002. I am particularly interested in web development 2.0, ajax, css, xhtml, asp.net, jQuery, Open Social and other web technologies.
 
In my spare time (when this concept exist in my life), i like to snowboard, skydive or free fall in wind tunnels and learning cool new stuff about anything.
 
Please feel free to contact me. http://www.nitriques.com

Comments and Discussions

 
GeneralMy vote of 1 PinmemberThiagarajan Rajendran28-Oct-10 9:19 
GeneralI could be wrong but PinmemberJeffCirceo27-Apr-09 23:12 
AnswerRe: I could be wrong but PinmemberNicolas Brassard28-Apr-09 6:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411023.1 | Last Updated 22 Apr 2009
Article Copyright 2009 by Nicolas Brassard
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid