Thursday, December 4, 2008

NWSGI 0.7 Released

NWSGI 0.7 is now available on Codeplex. This release mainly deals with cleaning up some rough edges and incompatibilities with PEP 333, although there are some new features. If you used the installer for NWSGO 0.6, you must manually uninstall it before installing NWSGI 0.7.

Session Support

ASP.NET HttpHandlers must inherit from IRequiresSessionState1 in order to have access to the Session state. This has been added to NwsgiHandler. Now, HttpContext.Session can be used to access the Session state. However, because the Session module adds a cookie, the entire response must be buffered, which is against the WSGI spec. See the section on Extensions for more details.

1 Why did they have to add the first "s"? IRequireSessionState is too clever to pass up.

Proper Unicode Handling

IronPython does not distinguish between str and unicode (and neither does Jython). WSGI requires apps to return str objects, but allows Unicode if there is no other option and only the bottom 8 bits are used. Previously, NWSGI used the incorrect encoding (and not even consistently; I had both ASCII and UTF-8 in different places). PEP 333 specifies ISO 8859-1 (aka Latin1) for all Unicode conversions, as is maps precisely to the first 256 Unicode characters and thus preserves raw bytes (ASCII and UTF-8 mappings are required to move things around).

As a result, raw files can now be passed through NWSGI without the use of wsgi.file_wrapper, such is when generating images on the fly.

Wildcard Mappings

All HttpHandlers must have a target extension so that they can be used; NWSGI uses *.wsgi. This results in URLs such as http://www.example.com/hello/hello.wsgi/Jeff. There are two ways to handle this: URL rewriting, which is the preferred way, and wildcard mapping, which is more of a last resort as it can hurt performance for static files.2

By setting the handler path to "*", all file requests will be sent through NWSGI. To tell NWSGI that this is what you want, set the wildcardModule attribute like so:

<wsgi wildcardModule="~/hello.wsgi">

The equivalent URL would be http://www.example.com/hello/Jeff. NWSGI will handle all requests to that app by remapping SCRIPT_NAME to the application (/hello) and PATH_INFO to the remainder (/Jeff).

The wildcardModule attribute can be either absolute (C:\…) or app-relative (~/…). Using wildcardModule will bypass any script mappings, as they are unnecessary.

2 One option is to move static files to a separate virtual directory or even separate server that does not use NWSGI.

WSGI Extensions

NWSGI implements a couple of non-conforming extensions to WSGI. In the interest of compatibility, these are off by default. To enable them, use the enableExtensions attribute:

<wsgi enableExtensions="true">

The current extensions are:

  • nwsgi.context – provide access to the HttpContext via environ["nwsgi.context"]. This is somewhat moot as it can always be reached from HttpContext.Current.
  • Responses are not flushed – PEP 333 requires the response to be flushed after every iteration of the WSGI callable. This breaks the use of ASP.NET Sessions, and possibly other IIS modules.

IronPython Version

NESGI 0.7 is linked against IronPython 2.0RC2, but RC1 should work as well – the assembly versions are the same. This hasn't been tested, however.