Mike Volodarsky's blog

Formerly the core server PM for IIS 7.0 and ASP.NET, now I run LeanSentry.
UPDATES: New troubleshooting guide released! Fix IIS website hangs →

Turbo-charge your PHP applications with IIS FastCGI Technical Preview 2

After 3 months of community feedback and development, the FastCGI Techical Preview 2 has just been released! 

Before I jump into the juicy details, I want to thank everyone who has tried out the original release, and given us bug and feature feedback on the FastCGI forums.  This has been incredibly valuable in driving the feature forward, and I look forward to more of it as we move towards FastCGI beta (more on this later in the post).

*******************************
UPDATE:
- 2/10/2007: The Windows-optimized PHP 5.2.1 is now available from www.php.net/downloads.  Learn more about it here.
- 2/18/2007: Instructions on how to run Ruby on Rails with IIS FastCGI TP2 have been published.
*******************************

First things first

The FastCGI Technical Preview 2 release is an update for the first ever release of Microsoft IIS FastCGI feature in October 2006, providing a platform for high-performance and reliable way to run application frameworks like PHP on IIS (see my other posts about FastCGI and PHP). 

It is now available from the FastCGI main page on www.iis.net, with the following packages:

  1. FastCGI for IIS 5.x / IIS 6.0 - for Windows XP, and Windows Server 2003
  2. FastCGI for IIS 7 - for Windows Vista (RC1+), and Windows Server codenamed "Longhorn"

This release supports both 32-bit and 64-bit operating systems, so be sure to download the appropriate flavor of the package for your operating system.  The 64-bit package will work "out of the box" in both native 64-bit and 32-bit WOW64 IIS application pools on your 64-bit Windows OS, so you dont need to worry about any additional configuration.

FastCGI Tech Preview 2 is fully compatible with PHP 5.2, currently available from www.php.net/downloads.  You can install the FastCGI package and configure it to work with PHP by following the updated instructions in the updated Using IIS FastCGI with PHP article.  It should also work with PHP 4, although we havent extensively tested it, so if you run into any issues, please report them on the Forums.  

So, what am I getting?

The original technical preview release from October 30th of last year provided basic FastCGI functionality for running PHP applications.  Technical Preview 2 contains the following bug fixes and enhancements:

  1. Native support for 64 bit Windows operating systems.  The 64-bit packages provide full installation support for 64-bit OS, and enable both native 64-bit and 32-bit WOW64-based IIS applications.  The FastCGI application, such as PHP, can be either 32 bit or 64 bit.
  2. Additional server variables used by PHP and other FastCGI frameworks.  These include DOCUMENT_ROOT, REQUEST_URI, and SCRIPT_FILENAME.
  3. Support for PHP's fcgi.impersonate.  This enables PHP applications on Windows to impersonate the authenticated user making the request, enabling the PHP scripts to execute as that user instead of the identity of the IIS worker process.
  4. Improved error handling.  Added a number of error messages for common error conditions such as miconfiguration.  This is primarily done in the IIS7 package version.  Also, provided proper handling for FastCGI application errors, such as PHP script errors. 
  5. Improved FastCGI application process management.  The FastCGI component is now resilient to shutting down or killing the IIS worker process, or stopping the IIS service, making sure to terminate the child FastCGI application processes.  This means that you should no longer see orphaned php-cgi.exe processes when you do any of the things above.
  6. Improved timeouts.  Several changes to make the timeouts more flexible / correct, including the added the activityTimeout setting, which insures that the child FastCGI process remains responsive.  Also added the idleTimeout setting, which controls how long the process can be idle before its terminated,
  7. Enabled the TCP transport mechanism.  This provides support for TCP-based FastCGI application implementations.
  8. Removed the response entity-body, and request POST entity-body size limitations.  Previously, internal constraints limited this to 1 Mb each.
  9. Support for passing command line arguments to FastCGI application processes.  Allows FastCGI applications that require command line arguments to be specified to be used with the FastCGI feature.
  10. Experimental Ruby support.  More on this including setup instructions in the next post!

Look to the next post for more details on the configuration options, and advanced functionality, including how to set up Ruby with FastCGI on IIS.

Installation

In order to use the FastCGI package, do the following:

  1. Download the appropriate FastCGI TP2 package for your IIS version (IIS6 vs. IIS7) and OS bitness (32-bit vs. 64-bit)
  2. Unzip it to a local directory on your machine
  3. Use fcgisetup.js (IIS6) or fcgisetup.exe (IIS7) to install it:

    IIS6: cscript fcgisetup.js /install
    IIS7: fcgisetup.exe /install

    Note that the TP2 installation automatically replaces the TP1 installation if present.  It also does not require TP1 to be installed.

  4. Then, configure FastCGI TP2 with your scripting environment, like PHP, for example:

    IIS6: cscript fcgisetup.js /r /add c:phpphp-cgi.exe php  
    IIS7: fcgisetup.exe /add c:phpphp-cgi.exe php

This is the short of it.  Please read the detailed how-to in the Use PHP with FastCGI article.  If you need last minute reference, the instructions are also available in the included "readme.txt" file, and from the fcgisetup installer as command line help.

What's next? The FastCGI roadmap

The Technical Preview 2 release is still in the tech preview stage, and as such is not meant for production environments.  It is an opportunity for us to get the fixes out to the community for evaluation, and gather more feedback as we move forward to a well-tested, stable beta release suitable for production environments.

We are hoping to be ready for the Beta release for both IIS6 and IIS7 platforms sometime around April.  This is currently tentative, and since our first priority right now is getting IIS7 ready for primetime in Longhorn Server, plans may change.  Keep watching the FastCGI forums and this blog for more news as time goes on.

Another incredibly exciting event is the anticipated arrival of PHP 5.2.1 (you can get the dev builds right now from www.php.net), which will contain the majority of Zend's core PHP fixes designed to significantly improve its performance on Windows.  Combined with the IIS FastCGI feature, this should provide unparallelled PHP performance on the Windows / IIS platform.  As soon as this is available, be sure to grab it - I will also post some performance numbers to show it off.

Now, go download the FastCGI Tech Preview and let me know how it goes.  You can get support, and report issues on the IIS6 FastCGI forums and the IIS7 FastCGI forums.  Watch my blog for more details over the next week ...

We are all looking forward to your feedback!

Get nice looking directory listings for your IIS website with DirectoryListingModule

*************************************************
(NEW) Update - 2/1/09:
Clarified installation instructions (see post).
Fixed bugs:
 - Occasional icons missing / icons missing during heavy load due to MTA problems with SHGetFileInfo (http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=337530)
 - Directory listing template has broken icons in some configurations 
*************************************************
Update - 4/26/08:
IconHandler 2.0 released. Use IconHandler to build your own directory listing,
or any other app that needs file icons.

************************************************** 

Do you hate bland directory listing pages that most web servers have these days?  The Internet has gone through many evolutions, yet web directory listings somehow got left out to the point where sometimes they appear to predate the http protocol itself (gopher, anyone?).  Here is the default IIS7 directory listing:

Almost two years ago, this exact emotion led Bill Staples to write a sample directory listing module for our first set of early IIS7 demos.  This module read the directory contents of a url, and generated a nice-looking gallery view of the images in that directory.  It was a much needed improvement!

Since then, several other people on the team modified and re-wrote the module, adding visual bells and whistles and otherwise changing the way it looked.  Everyone thought it looked best their way.  The module grew and grew into a mess of c# code and HTML fragments, to the point where noone ever wanted to show the code for it, just how cool it made the site look.  For fun, here is a code excerpt from the original module:

                //write out links to paths leading up to directory

                Response.Write("<h3>g a l l e r y : ");

                    for (int i = 0; i<strpaths.Length-1;i++) {

                        strURL = strURL + strpaths[i] ;

                        Response.Write("<a href="" + strURL + "/" + "">" + strpaths[i] + "/" + "</a>");

                        strURL = strURL + "/";

                    }

                Response.Write("</h3>n");

I've always wanted to take the module, and rewrite it so that it provided complete separation of the module infrastructure / directory reading code, and the actual HTML content.  This way, a designer could go in and change the layout and the look and feel of the directory listing without having to change the code itself ... And since I try to stay away from actual website design as much as possible, this would give me all the pleasure of writing some server code and none of the pain of trying to make it look good.  That's the designer's job!

With that in mind, I wrote this directory listing module that uses an ASPX page as a template for generating the actual output, so the look and feel is entirely in the designers control.  The module simply provides the directory listing as a bindable collection of directory entries, each of which contains useful properties that can be used inside the the page to generate the UI.

In a nutshell, here is what the module does:

  1. Intercepts requests to "directory" urls within your application, like "http://example.com/files/"
  2. Reads the directory contents, and creates a collection of DirectoryListingEntry objects
  3. Stores this collection inside the HttpContext.Items collection
  4. Executes the configured template page, which databinds to the directory listing collection and produces the desired UI for your custom directory listing
  5. Hardcodes Absolutely No HTML content in the module ...

The sample page I wrote has a DataList control that I databind to the collection inside Page_Load():

void Page_Load()

{  

    DirectoryListingEntryCollection listing =         

Context.Items[DirectoryListingModule.DirectoryListingContextKey] as DirectoryListingEntryCollection;

   

    DirectoryListing.DataSource = listing;

    DirectoryListing.DataBind();

}

 

<asp:DataList id="DirectoryListing" runat="server">

    <ItemTemplate>

        <a href="<%# ((DirectoryListingEntry)Container.DataItem).VirtualPath  %>"><%# ((DirectoryListingEntry)

        Container.DataItem).Filename %></a>

    </ItemTemplate>

</asp:DataList>

On top of this, I threw in some sorting capabilities (The DirectoryListingEntry object provides a number of IComparer delegates that can be used to sort the collection on date modified, file size, and file name, but you can of course implement your own), and nice looking file icons using the IconHandler.  With minimal HTML design, here is what I got:

I want it!

You can view this app running live on my server here: http://mvolo.com/directorylisting/ (since I dont have VS installed on the server, ASPX shows with text icons). 

Download the sample app containing both the DirectoryListingModule, my simple template, and the IconHandler. 

Installation instructions:

IIS7:

  0.  Install ASP.NET if you havent already (DUH?)

  1.  Run the following from a command prompt (open it with the "run as Administrator" option):

  %windir%System32inetsrvappcmd set module DirectoryListingModule /lockItem:false

  (this is done to unlock the built-in DirectoryListingModule for removal in the application, so that it can be replaced with our custom one)

  2.  Create an application, and unzip the contents of the app into its root directory.  That's it!

IIS6:

  0.  Install ASP.NET if you havent already (DUH?)

  1.  Create an application, and configure ASP.NET 2.0 to be a wildcard mapping for it. 

  2.  Unzip the contents of the app into the root directory of your application, and you are good to go.

What else is there to do?

Right now, the module is only aware of the physical file system directory structure for the directory you are viewing.  So, if your directory has a virtual subdirectory that maps to a physical location somewhere else, it won't show up in the directory list.  For example, if your application http://example.com/myapp has a root in c:myapp, and you have a virtual directory http://example.com/myapp/files that points to c:files, you are not going to see "files" in the directory listing for /myapp.  To fix this, the directory listing module needs to be Virtual Path Provider aware, which will also have a bonus in being able to provide directory listings of sharepoint sites.  This is coming soon ...

Also, since I am sure you are a better designer then me, if you end up making a cool directory listing template you want to share, please post it here.  If you make the coolest one, there may even be a prize involved ...