Ok, I have been pretty busy the past 10 days with both work and life, and I have not had a chance to post any blog entries. While I cannot say that I am any less busy now, I definitely have a lot of catchup and posts to make... so here goes.
This question was originally posted in the microsoft.public.platformsdk.internet.server.isapi-dev newsgroup on the msnews.microsoft.com NNTP server. Since all the technical previews at events like TechEd and PDC will be high-level concepts/details, the astute reader will always have some unanswered questions.
Now, while I cannot promise that I will answer everything about IIS7, nor can I promise that my answers will forever be correct (remember, we are talking about IIS7, an unreleased beta product), I will try to give as much currently-correct technical information as I can.
Hi!I know this is kinda not the right group for this question, but if you know one that will be better suited, please let me know... That aside, though:
I have written a couple of ISAPI filters for our company, and they work just fine. Seeing the changes being made in IIS7, though, I thought I better get familiar with HTTPModules :-). So I just wrote an HTTPModule for IIS 6, using C#. This of course utilizes the old (current) architecture, and I'm somewhat confused about how the ISAPI callback functions "map" to the HTTPModule members.
In my current ISAPI filter, I reserve a piece of memory in GetFilterVersion, let's say 5 MB. GetFilterVersion was called on every load of the filter, so once per worker process; this means I have [#w3wp.exe} times 5 MB allocated. If I understand the HTTPModule structure right, the best match equivalent to GetFilterVersion would be the constructor, or possibly the Init() member, so the logical thing to do would be to "allocate" (as far as .NET lets me) my memory there now. There's quita a problem with this though...
As I saw it, the constructor of my module will be called once for every ASP.NET application that is being requested, and this gives me some headaches. In my case, we have about 50 worker process on the server, serving about 2500 websites. Each website has at least one appliaction, possibly more. Of course they're not all running at the same time, but still: We have a whole lot more of applications than we have worker processes. Let's just say that 800 ASP.NET appliactions are running at the time, so this would mean I'd end up with using 800 x 5 MB of memory. Definitely not desirable... The fact that I can't deliberately free my memory makes this even worse, but that's a problem I always struggle with in C# ;-)
So, is this "once per application" problem that I have now just an ASP.NET thing, because the module still lives inside the aspnet_isapi.dll? Will the behaviour be different in IIS7, and will there be a place that's only called once per w3wp.exe startup?
Thanks in advance,
Since IIS7 is not available publicly and the API is beta (i.e. it is subject to change, and I know that it must have changed significantly since your point of reference...), I really would not spend TOO much time thinking about the details yet... ;-) But since you are interested, this is a perfectly fine forum to ask.
Based on your line of questioning, the main points I want to emphasize are that:
For example, I would not assume that things in IIS6 such as ISAPI Filter, ISAPI Extension, and CGI automatically transform into an HttpModule or HttpHandler in IIS7 because they definitely do not. If you think about it a little, you should realize that something like a global ISAPI Filter which triggers on every single request can never map to an HttpModule. Security considerations alone should be reason enough.
Now, in your case, I think your design requires a native code global module because it has the behavior that you need. Here is the crux of what is going on:
Conceptually, you can view IIS7 as a componentization of the IIS6 server core accomplished by:
At this point, the astute reader should be wondering why global modules MUST be in native code and not managed code. After all, the managed code in an HttpModule now has direct access to the native IIS7 request pipeline through the ASP.Net global module "shim" that is provided out of the box, and since the global module can execute managed code at any point, it *should* be able to run an HttpModule "globally".
Well, yes, that idea is possible, but after long design considerations, we decided to stick with the ASP.Net paradigm of application isolation through AppDomains for managed applications, so there is no such thing as "global" managed code. The security, performance, and complexity ramifications of global managed modules were just too problematic. For example, here are some of our thoughts and counterpoints:
In the end, we decided that the implementation cost, performance penalty, and the resulting security ramifications were simply too complex. There are good situations for both native and managed modules, and we attempted to strike a reasonable balance between functionality and ease. Allowing managed code a chance to manipulate the incoming request URL/headers, participate in request authentication/authorization inline, and perform caching/logging logic cover most users' needs. Besides, we want global module developers to be a little more "responsible" since it carries huge consequences on server behavior... so native code serves to weed that out a bit. :-)
Now, if you have a bright idea on how to implement global managed modules in a secure, performant, reliable, and functional manner without destroying basic IIS tenets and remain easy to use, feel free to share your thoughts... :-) Until then, global managed modules are not allowed in IIS7.