At this year’s PDC, there was one technology on the huge list of announcements that Microsoft made that didn’t quite get the attention it deserved: IIS 7.0 in Longhorn Server. I checked out several of the IIS 7.0 sessions at PDC and recently attended a Microsoft three-day event highlighting the new features of IIS 7.0. The short of it is: I’m impressed by the planned changes, because for the most part the changes are evolutionary and will bring a more solid architecture to IIS. It’s an architecture that formalizes many previously haphazardly thrown together technologies and brings something to IIS as a platform that was previously missing: elegance and simplicity.
IIS 7.0 will offer many very cool new features and a much cleaner architecture that is more extensible and accessible to developers. If you are a managed code developer, some of the integration features are going to make you drool at the possibilities that are opening up by way of this new architecture.
At it’s core level, IIS 7.0 will change drastically by providing a modular core engine. The core engine is light-weight and based on a plug-in architecture. Almost all of the behavior of the Web server will be provided through plug-ins (that is, modules, which is the official name). The name Microsoft chooses here is no accident-modules are similar to ASP.NET HttpModules and you can, in fact, build your modules using the familiar ASP.NET HttpModule architecture (as well as using a new C++-based API).
You can enable and disable modules in an XML configuration file. You can, in effect, create a Web server that does absolutely nothing by removing all modules. Not terribly useful, but hey, it’s very secure! <g> The idea is that you can create a Web server with only those exact modules that you need for the purpose you’re using it for. If your application serves only static pages, you only need to enable the StaticFile module and the Anonymous Authentication module and nothing else. If you need Windows Authentication, you can enable that. If that’s all you need, you’re done. Of course, it’s not quite that simple-there are a few modules like logging and tracing that you probably always want running, but the idea is to allow you to completely customize the Web server down to the lowest level. The real kick is that you can remove default behavior and plug in your own by writing to the new APIs available in IIS 7.0. Think about it-that’s a drastic change and one that can give you incredible power to build a very customized Web server.
The modular architecture uses a hierarchical architecture-Web server, Web site, virtual/application with each of the levels configurable. You can plug these modules and remove them at each level. This way you can exactly customize your Web application down to the virtual directory, reduce the overhead for functionality you don’t need, and minimize your potential security attack surface for modules that you are not using.
Modules are completely pluggable and you can create your own custom modules. Unlike previous versions of IIS, IIS 7.0 introduces a new programming model that is based on a request pipeline that is very similar to ASP.NET’s pipeline. Requests flow through this pipeline and specific hook points are activated by module plug-ins that are configurable via the configuration file. The modules are either system modules that ship with IIS or modules that you can create on your own using C++ or managed APIs.
The new pipeline can run in an Integrated Mode and if managed modules are available, the CLR is automatically loaded into the Application Host process. This means managed code is a first class citizen in IIS 7.0. ASP.NET applications no longer run through an ISAPI extension, but rather are directly hooked into the IIS pipeline which is bound to be much more efficient as ASP.NET can directly access the server components using the standard IIS API components. For the core engine this means there will be a lot less monkeying with ISAPI structures and memory; instead, managed code can use the new optimized Web server APIs that are directly accessible from code. Microsoft is basically opening up the Web server and giving you access to the same tools they use to build these modules, so if you need to build custom Web server extensions, you can now use a much more powerful API compared to an ISAPI extension or filter!
Of course, you can also continue to run apps using the IIS 6 model (called Mixed Mode) and use the same separation of the pipeline as IIS 6 does. ASP.NET still uses ISAPI in this scenario and the ASP.NET pipeline works as part of the HttpApplication object as before.
ASP.NET also becomes a first class citizen-in fact, it really becomes part of the Web server. HttpHandlers and HttpModules plug directly into the IIS pipeline rather than the ASP.NET pipeline. But don’t fret-the old way of ASP.NET running through ISAPI is also still supported although these two code paths require application-wide configuration settings switching on Integrated Mode (the new way) vs. Mixed Mode (classic). According to Microsoft, most existing ASP.NET HttpModules and HttpHandlers are expected to run without changes (depending on how low level your handlers are) in Integrated Mode. If you were previously building ISAPI extensions you can now build HttpHandlers and get all the power that entails. You can do this using either managed code or C++ APIs that are modeled after the ASP.NET interfaces.
Modules are really at the core of IIS 7.0. It makes for a truly componentized architecture that is more customizable and in the same breath more secure. But it also makes IIS much more extensible by providing an easier extensibility mechanism that is standardized and based on a familiar and already successful model: ASP.NET. Gone are the days of cryptic ISAPI interfaces that are C API-based, and difficult to code against. Instead you get two roughly equivalent APIs for both managed code and C++ that use the familiar HttpContext-like architecture with high-level objects like Request, Response, Application, Cache, and so on. And yes, you can extend IIS directly with managed code by writing modules and handlers.
What does that mean for you? Think about it-in managed code right now (ASP.NET 1.x and 2.x), your handlers and modules are limited to requests that fire against ASP.NET mapped extensions-anything must be script-mapped to the ASPNET_ISAPI.DLL in order for your code to fire. In this new pipeline, you don’t have an ISAPI intermediary and your managed code can control every request firing on the application that it is mapped to. This is very powerful and was very difficult to do previously and basically required ISAPI filters which are extremely difficult to write and debug.
A great example that a presenter showed during the three-day seminar was using ASP.NET Forms Authentication with a classic ASP page. You simply enable the Forms Authentication module-which is a managed code module-on the site or virtual directory and it is applied against all files on the site/virtual. It works against ASP files, HTM files or images, or even a third-party tool like PHP.
Along the same lines, in one of my apps a client has image directories for a photo album that is available only for paid customers. Non-paying customers can see the images, but they see them with watermark overlays. In ASP.NET currently we handle this by mapping all the image extensions to the ASP.NET ISAPI dll, then run it against an image HttpHandler that creates a ‘Sample’ overlay with GDI+ on the image. There are a fair number of scriptmaps for all the image types and it’s not easy to port this across sites as each has to be configured. In IIS 7.0 you can create the module and simply hook it to appropriate image types right in the web.config file and you’re done! You can hook this module both at the local application level or more importantly have it apply to the entire Web server! Yes, you heard that right-you can now create modules that are Web server-wide, which is functionality that previously required writing nasty ISAPI filters. And you can use managed code to do it if you choose.
If you are an ISAPI developer, the new APIs will make your life a lot easier as well. I have several core ISAPI extensions that are Application Servers that interface with backend applications-these ISAPI extensions are horribly complex code that deal with raw COM code in C++ and is an absolute nightmare to change and debug. It would be a cinch to actually re-write these ISAPI extensions as managed code HttpHandlers or possibly even as C++ handlers. Why C++? Well, performance is going to be better using C++, especially if you keep managed code out of the pipeline altogether. If you’re building low-level application server type interfaces it’s actually quite likely that this is the case and if so you can take advantage of keeping the pipeline completely in unmanaged code.
Managed Code and Performance
A word of warning tough: It’s also important to understand the potential for doing the wrong thing with all of this power. First keep in mind that managed code is slower than native code in the Web server. By introducing managed code into the core server you are slowing down the performance of the Web server. Specifically, the context switches between managed and unmanged code are expensive when running in Integrated Mode and with managed modules present. I’ve talked to some of the Microsoft developers, and they are taking a hard look at optimizing these context switches by trying to batch calls to managed code components as much as possible, staying in managed code as long as possible.
Managed code is optional by default-all the core modules are native code, so adding managed modules is an explicit decision you have to make. If you’re already using ASP.NET then this decision is probably a no-brainer. But if you’re running raw ISAPI extensions or modules today, you’ll probably have to take a long hard look to see whether managed code is going to be a good fit in terms of performance.
For ASP.NET applications, I will guess that you will regain some of the potential overhead because the whole ISAPI layer is bypassed and the ASP.NET engine can directly talk to the IIS APIs for much of this functionality. You’ll have to wait until Microsoft releases IIS 7.0 and run your own performance tests.
Microsoft will optimize the pipeline for the standard modules, but remember that if you write your own modules it’ll be up to you to write modules that have high performance. With the ability to hook every request flowing through an application or the Web server as a whole, there will be an intense responsibility to make sure your module isn’t a bottleneck to the application. If you’re not careful in your design, any of your custom modules can very easily drag your application and the entire Web server to a crawl.
Configuration in IIS 6 is better than in previous versions but the process of configuring Web sites and managing and moving site configurations is not intuitive with configuration settings stored all over the place and in formats that are often cryptic and unintuitive.
IIS 7.0 is merging IIS and ASP.NET together in such a way that you can perform your configuration in one place. Specifically, IIS 7 introduces ApplicationHost.config, which acts as a top-level configuration container for the Web server, with satellite web.config files that can provide localized configuration for sites and virtual directories. This means you can configure your Web application, including many of the virtual directory settings for an application, in your local web.config file. This is really useful because you can copy this web.config file with your application and immediately apply these settings against the application directory as well. This combined configurability should really simplify deployment of Web applications. You may still need to create virtual directories at the top level (ApplicationHost.config) but individual settings for the virtual directory can be done right in web.config.
Gone too is the metabase.xml file with its horribly convoluted schema that was barely readable by humans. There’s a new schema that uses ApplicationHost.Config which holds the machine’s application pools, Web sites, and virtual directory configuration information. The new schema is a logical hierarchical layout that’s easy to read. If you’re using a schema-aware editor like Visual Studio, you can see strongly-typed IntelliSense options available. This is great for developers but not so great for admins since they’re not likely to have a copy of Visual Studio handy for editing configuration files. Hopefully Microsoft will provide some sort of editor that can provide schema editing beyond Visual Studio.
You can customize ApplicationHost.config at the site or virtual directory level by using web.config files and syntax that should be immediately familiar to ASP.NET developers. Realistically, a web.config file inherits from ApplicationHost.config and from Machine.config. ApplicationHost.config provides the IIS settings while Machine.config provides the traditional ASP.NET and .NET configuration settings. Web.config can then override both. The IIS settings are stored in a new and separate <system.WebServer> section.
In addition, Microsoft is updating the IIS Management Console and replacing it with a dedicated GUI tool that is much more visual and intuitive. The tool provides easier access to many configuration options and does away with the horrible tabbed interface in use now. The user interface for this tool was still in flux but it provides a lot of flexibility in what information is visible. You can assign administrative roles and views into the data so you can allow access to certain users and allow them access to the site with only those specific settings. This tool will provide optimized remote access to the Web server, so it is effectively the configuration front end for the Web server even for remote administration. There will be no Web configuration front end, due to security concerns, according to Microsoft.
Much, Much More…
There’s a lot more to tell, but here are a few more quick features that stuck out for me:
- There’s improved event tracing that greatly simplifies tracing requests and tracking errors. You can log failures and even hook in custom trace modules that can fire against your custom code. If you ever had to debug an IIS error and had to use the IIS Resource Kit tools you will really appreciate this!
- There’s the new WMI provider for automating Web server tasks, and even hooking into the tracing mechanisms, using a much more logical schema than the previous version’s WMI provider.
- You can now use Forms Authentication for IIS in general.
- There’s support for Authorization providers beyond Windows ACLs, including using the ASP.NET Membership Provider, or a custom configuration section user entries (frequently used for ISPs). A number of configuration features are also geared at making IIS more friendly to ISPs in large installations.
To sum up, IIS 6.0 was the first version of IIS that brought a truly stable, fast, and efficient platform to the Windows platform. It looks like IIS 7.0 will improve that platform by bringing a standardized and well-thought-out architecture to bear. Through this architecture, IIS 7.0 provides much more extensibility and a more easily configurable platform. ASP.NET has an elegant design that is logical, powerful and extensible, and I think IIS 7.0 is shaping up to inherit much of that architectural elegance. We can look forward to seeing much of that elegance brought all the way down into the Web server architecture. I can’t wait…