= Running Trac on IIS 6 using Isapi-wsgi = Contributed by:[[br]] Seb Patane, Insight Informatics, Brisbane, Australia. I did this with: * Windows Server 2003 SP2 * Python 2.7 * IIS 6 * Trac 0.12 It may work for other versions. I also haven't tested standard authentication as I use the [http://trac-hacks.org/wiki/AccountManagerPlugin AccountManagerPlugin]. I also found this to be significantly faster than the TracOnWindowsIisAjp. The only downside is that whenever a plugin is manually installed/code is changed a full `iisreset` needs to be done to reload the ISAPI dll. Restarting the IIS Site alone doesn't seem to be enough. 1. Download & install the latest [http://code.google.com/p/isapi-wsgi/ Isapi-wsgi] (I used 0.4.2 exe), depends on [http://sourceforge.net/projects/pywin32/files/pywin32 pywin32] (I used Build 216 exe) 1. Generate a `trac.wsgi` script using `trac-admin deploy ` (see TracInstall#cgi-bin) 1. copy `trac.wsgi` into a new file called `trac_wsgi.py` for Isapi-wsgi. Append these extra bits so Isapi-wsgi can generate an ISAPI DLL: {{{ #!C:\Python27\python.exe import isapi_wsgi # The entry points for the ISAPI extension. def __ExtensionFactory__(): # can also be isapi_wsgi.ISAPISimpleHandler return isapi_wsgi.ISAPIThreadPoolHandler(application) if __name__=='__main__': # If run from the command-line, install ourselves. from isapi.install import * params = ISAPIParameters() # Setup the virtual directories - this is a list of directories our # extension uses - in this case only 1. # Each extension has a "script map" - this is the mapping of ISAPI # extensions. sm = [ ScriptMapParams(Extension="*", Flags=0) ] # To serve from root, just set Name="/" vd = VirtualDirParameters(Name="/trac", Description = "ISAPI-WSGI Trac", ScriptMaps = sm, ScriptMapUpdate = "replace" ) params.VirtualDirs = [vd] HandleCommandLine(params) }}} 1. Ensure everything has the right Permissions for the IIS Site user. * READ/EXECUTE: imports from site-packages (including eggs), generated ISAPI dll, trac directory & subdirectories * WRITE/MODIFY: trac/conf/trac.ini, trac/log directory, trac/plugins directory, trac/attachments directory (?), trac/db directory (?), .htpasswd file (if using Account Manager) 1. Generate and Install the ISAPI dll using `python trac_wsgi.py install [--server=]`. Don't forget to do an `iisreset` whenever the filter is reinstalled. * This will automatically create the Virtual Directory, install the ISAPI filter and allow it in Web Service Extensions 1. That's it, everything should work! If there are problems you can enable debugging by inserting the following at the top of `trac_wsgi.py`, reinstalling the ISAPI dll and running `python -m win32traceutil` (will also display TracLogging to `stderr`). {{{ #!C:\Python27\python.exe import sys if hasattr(sys, "isapidllhandle"): import win32traceutil }}} TracModWSGI is probably a good starting point as well, even though it deals with Apache. == Broken Authentication == I had a problem with the [http://trac-hacks.org/wiki/AccountManagerPlugin AccountManagerPlugin] always returning `Invalid Username or Password`. This is because the `REMOTE_USER` environment variable is set (I'm not sure why, since it seems to be empty). In any event, putting `del environ['REMOTE_USER']` in `trac_wsgi.py` solved the problem. == Appendix A - My working trac_wsgi.py (with useful extras) == {{{ #!C:\Python27\python.exe # -*- coding: utf-8 -*- # # Copyright (C)2008-2009 Edgewall Software # Copyright (C) 2008 Noah Kantrowitz # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. # # Author: Noah Kantrowitz # # IMPORTANT: when you make changes to this file you need to # update the ISAPI filter with the following commands - # C:\Inetpub\trac\cgi-bin> python trac_wsgi.py install --server=Trac # C:\Inetpub\trac\cgi-bin> iisreset # import os """ # Uncommenting this enables debug output # you can see it by opening up a command prompt and executing # > python -m win32traceutil import sys if hasattr(sys, "isapidllhandle"): import win32traceutil """ def application(environ, start_request): if not 'trac.env_parent_dir' in environ: environ.setdefault('trac.env_path', 'C:\\Inetpub\\trac') if 'PYTHON_EGG_CACHE' in environ: os.environ['PYTHON_EGG_CACHE'] = environ['PYTHON_EGG_CACHE'] elif 'trac.env_path' in environ: os.environ['PYTHON_EGG_CACHE'] = \ os.path.join(environ['trac.env_path'], '.egg-cache') elif 'trac.env_parent_dir' in environ: os.environ['PYTHON_EGG_CACHE'] = \ os.path.join(environ['trac.env_parent_dir'], '.egg-cache') # Required for Account Manager logins to work del environ['REMOTE_USER'] from trac.web.main import dispatch_request return dispatch_request(environ, start_request) """ # Uncommenting this enables middleware profiling at /__profile__ # Requires the repoze.profiler egg to be installed from repoze.profile.profiler import AccumulatingProfileMiddleware application = AccumulatingProfileMiddleware(application, log_filename='C:\\repoze.log', discard_first_request=True, flush_at_shutdown=True, path='/__profile__') """ import isapi_wsgi # The entry points for the ISAPI extension. def __ExtensionFactory__(): return isapi_wsgi.ISAPIThreadPoolHandler(application) if __name__=='__main__': # If run from the command-line, install ourselves. from isapi.install import * params = ISAPIParameters() # Setup the virtual directories - this is a list of directories our # extension uses - in this case only 1. # Each extension has a "script map" - this is the mapping of ISAPI # extensions. sm = [ ScriptMapParams(Extension="*", Flags=0) ] # To serve from root, just set Name="/" vd = VirtualDirParameters(Name="/trac", Description = "ISAPI-WSGI Trac", ScriptMaps = sm, ScriptMapUpdate = "replace" ) params.VirtualDirs = [vd] HandleCommandLine(params) }}}