Search code examples
c#c++iishttpmoduleisapi

Approach Using a Front Controller and IIS Serving Static Files?


Background

An IIS ISAPI filter routes all requests to a front controller Java CMS for response. No physical file corresponds to a given URL. Motivations:

  1. Securing URLs
  2. Enforcing SSL

This is a performance bottleneck serving static files such as audio and video. And, pooled application server processing threads are occupied serving the response.

Idea

Have the application server populate an IIS ISAPI Filter, or httpmodule, that can read and then serve the file instead. Possibly populate response header(s) with physical file path, content length, and mime-type.

Questions

  1. Bad design decision not having IIS serve the files directly? If so, suggestions for what to look at in terms of security and SSL enforcement (CMS handles both) .
  2. If going with having IIS respond, what to do to take advantage of IIS static file caching? Or how much benefit is the cache?

Solution

  • I believe that you should allow IIS to serve the static files. You can have HttpModule (or your filter) transferring the control back to IIS - it means that security enforcement code may have to be replicated. Yet another approach can be to make application server transfer control back to IIS to serve the file (security checking would of course happen before). Or lastly, as outlined by you, your app server can inject response headers and then httpmodule would read them and pass control to IIS. Not sure about java but in .NET you can use HttpResponse.TransmitFile method to pass back control to IIS - this should avoid need to make HttpModule serve file.

    Finally, for caching, you can always emit cache headers in response to have down level (proxy or client side caching). If files are changing then you can add file dependency etc.

    EDIT: Not sure if this will work for you. Create an http handler (ashx) and marked it as SSL required in IIS. All media files will be served by this handler. The handler would take file to be served as query parameter. Now, you may pass some file identifier or encrypted partial path (relative to configured base path to file store) so that actual file name or paths are not visible to user. You can even make tokens that would expire in some time (essentially, append file id & time-stamp and encrypt it) so that user cannot request same file again using same parameter. Pseudo-code for handler would be

    void ProcessRequest(HttpContext context)
    {
        // read file id/name token
        var token = context.Request["q"];
    
        // validate/decrypt token etc and get the actual path for file to be served
        string filePath;
    
        // set needed response headers - content-type, content-disposition and cache related
        ...
    
        // ask IIS to serve the file
        context.Response.TransmitFile(filePath);
    }