Edgewall Software

Changes between Initial Version and Version 1 of TracOnWindowsIisIsapi


Ignore:
Timestamp:
May 1, 2011, 5:11:12 AM (13 years ago)
Author:
seb@…
Comment:

Initial instructions

Legend:

Unmodified
Added
Removed
Modified
  • TracOnWindowsIisIsapi

    v1 v1  
     1= Running Trac on IIS 6 using Isapi-wsgi =
     2
     3Contributed by:[[br]]
     4Seb Patane, Insight Informatics, Brisbane, Australia.
     5
     6I did this with:
     7 * Windows Server 2003 SP2
     8 * Python 2.7
     9 * IIS 6
     10 * Trac 0.12
     11It may work for other versions.
     12
     13I 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.
     14
     15The 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.
     16
     171. Download & install the latest [http://code.google.com/p/isapi-wsgi/ Isapi-wsgi] (I used 0.4.2 exe)
     181. Generate a `trac.wsgi` script using `trac-admin <env> deploy <dir>` (see TracInstall#cgi-bin)
     191. 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:
     20{{{
     21#!C:\Python27\python.exe
     22import isapi_wsgi
     23# The entry points for the ISAPI extension.
     24def __ExtensionFactory__():
     25    # can also be isapi_wsgi.ISAPISimpleHandler
     26    return isapi_wsgi.ISAPIThreadPoolHandler(application)
     27
     28if __name__=='__main__':
     29    # If run from the command-line, install ourselves.
     30    from isapi.install import *
     31    params = ISAPIParameters()
     32    # Setup the virtual directories - this is a list of directories our
     33    # extension uses - in this case only 1.
     34    # Each extension has a "script map" - this is the mapping of ISAPI
     35    # extensions.
     36    sm = [
     37        ScriptMapParams(Extension="*", Flags=0)
     38    ]
     39    # To serve from root, just set Name="/"
     40    vd = VirtualDirParameters(Name="/trac",
     41                              Description = "ISAPI-WSGI Trac",
     42                              ScriptMaps = sm,
     43                              ScriptMapUpdate = "replace"
     44                              )
     45    params.VirtualDirs = [vd]
     46    HandleCommandLine(params)
     47}}}
     481. Ensure everything has the right Permissions for the IIS Site user.
     49 * READ/EXECUTE: imports from site-packages (including eggs), generated ISAPI dll, trac directory & subdirectories
     50 * WRITE/MODIFY: trac/conf/trac.ini, trac/log directory, trac/plugins directory, trac/attachments directory (?), trac/db directory (?), .htpasswd file (if using Account Manager)
     511. Generate and Install the ISAPI dll using `python trac_wsgi.py install [--server=<IIS Web Site Name>]`. Don't forget to do an `iisreset` whenever the filter is reinstalled.
     52 * This will automatically create the Virtual Directory, install the ISAPI filter and allow it in Web Service Extensions
     531. That's it, everything should work!
     54
     55If 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`).
     56{{{
     57#!C:\Python27\python.exe
     58import sys
     59
     60if hasattr(sys, "isapidllhandle"):
     61    import win32traceutil
     62}}}
     63
     64TracModWSGI is probably a good starting point as well, even though it deals with Apache.
     65
     66== Broken Authentication ==
     67I 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).
     68
     69In any event, putting `del environ['REMOTE_USER']` in `trac_wsgi.py` solved the problem.
     70
     71== Appendix A - My working trac_wsgi.py (with useful extras) ==
     72{{{
     73#!C:\Python27\python.exe
     74# -*- coding: utf-8 -*-
     75#
     76# Copyright (C)2008-2009 Edgewall Software
     77# Copyright (C) 2008 Noah Kantrowitz <noah@coderanger.net>
     78# All rights reserved.
     79#
     80# This software is licensed as described in the file COPYING, which
     81# you should have received as part of this distribution. The terms
     82# are also available at http://trac.edgewall.org/wiki/TracLicense.
     83#
     84# This software consists of voluntary contributions made by many
     85# individuals. For the exact contribution history, see the revision
     86# history and logs, available at http://trac.edgewall.org/log/.
     87#
     88# Author: Noah Kantrowitz <noah@coderanger.net>
     89#
     90# IMPORTANT: when you make changes to this file you need to
     91#            update the ISAPI filter with the following commands -
     92#   C:\Inetpub\trac\cgi-bin> python trac_wsgi.py install --server=Trac
     93#   C:\Inetpub\trac\cgi-bin> iisreset
     94#
     95import os
     96
     97"""
     98# Uncommenting this enables debug output
     99# you can see it by opening up a command prompt and executing
     100#       > python -m win32traceutil
     101import sys
     102
     103if hasattr(sys, "isapidllhandle"):
     104    import win32traceutil
     105"""
     106
     107def application(environ, start_request):
     108    if not 'trac.env_parent_dir' in environ:
     109        environ.setdefault('trac.env_path', 'C:\\Inetpub\\trac')
     110    if 'PYTHON_EGG_CACHE' in environ:                                           
     111        os.environ['PYTHON_EGG_CACHE'] = environ['PYTHON_EGG_CACHE']
     112    elif 'trac.env_path' in environ:
     113        os.environ['PYTHON_EGG_CACHE'] = \
     114            os.path.join(environ['trac.env_path'], '.egg-cache')
     115    elif 'trac.env_parent_dir' in environ:
     116        os.environ['PYTHON_EGG_CACHE'] = \
     117            os.path.join(environ['trac.env_parent_dir'], '.egg-cache')
     118
     119    # Required for Account Manager logins to work
     120    del environ['REMOTE_USER']
     121
     122    from trac.web.main import dispatch_request
     123    return dispatch_request(environ, start_request)
     124
     125"""
     126# Uncommenting this enables middleware profiling at /__profile__
     127# Requires the repoze.profiler egg to be installed
     128from repoze.profile.profiler import AccumulatingProfileMiddleware
     129application = AccumulatingProfileMiddleware(application,
     130                                            log_filename='C:\\repoze.log',
     131                                            discard_first_request=True,
     132                                            flush_at_shutdown=True,
     133                                            path='/__profile__')
     134"""
     135
     136import isapi_wsgi
     137# The entry points for the ISAPI extension.
     138def __ExtensionFactory__():
     139    return isapi_wsgi.ISAPIThreadPoolHandler(application)
     140
     141if __name__=='__main__':
     142    # If run from the command-line, install ourselves.
     143    from isapi.install import *
     144    params = ISAPIParameters()
     145    # Setup the virtual directories - this is a list of directories our
     146    # extension uses - in this case only 1.
     147    # Each extension has a "script map" - this is the mapping of ISAPI
     148    # extensions.
     149    sm = [
     150        ScriptMapParams(Extension="*", Flags=0)
     151    ]
     152    # To serve from root, just set Name="/"
     153    vd = VirtualDirParameters(Name="/trac",
     154                              Description = "ISAPI-WSGI Trac",
     155                              ScriptMaps = sm,
     156                              ScriptMapUpdate = "replace"
     157                              )
     158    params.VirtualDirs = [vd]
     159    HandleCommandLine(params)
     160}}}