2

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?
orangepips
  • 9,891
  • 6
  • 33
  • 57

2 Answers2

2

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);
}
VinayC
  • 47,395
  • 5
  • 59
  • 72
  • +1 Any suggestion for how to send security info back and forth between the app server and IIS if I have the latter do the serving? And, if I went with my proposed approach it looks like preSendRequestContent and preSendRequestHeaders are probably the two methods I want to work with on httpmodule? And, I can send information via response headers that IIS can read? – orangepips Dec 13 '10 at 11:32
  • 1
    In your proposed approach, your app server will be an Http Handler, so IMO, you can use 'PostRequestHandlerExecute' in http module - it would mean that App Server has done with the request and might have added headers that would tell your module that this request needs to served by IIS. Also see my edit for alternate approach. Hope this helps! – VinayC Dec 13 '10 at 11:52
1

This may work:

http://www.helicontech.com/ape/

Specifically the x-sendfile piece.

orangepips
  • 9,891
  • 6
  • 33
  • 57