Index: editor/filemanager/upload/test.html
===================================================================
--- editor/filemanager/upload/test.html	(revisin: 387)
+++ editor/filemanager/upload/test.html	(copia de trabajo)
@@ -91,7 +91,8 @@
 									<option value="aspx/upload.aspx">ASP.Net</option>
 									<option value="cfm/upload.cfm">ColdFusion</option>
 									<option value="lasso/upload.lasso">Lasso</option>
									<option value="php/upload.php">PHP</option>
+									<option value="py/upload.py">Python</option>
 									<option value="">(Custom)</option>
 								</select>
 							</td>
Index: editor/filemanager/upload/py/upload.py
===================================================================
--- editor/filemanager/upload/py/upload.py	(revisin: 0)
+++ editor/filemanager/upload/py/upload.py	(revisin: 0)
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+"""
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the "File Uploader" for Python (Standalone CGI and WSGI).
+ *
+ * Tested with:
+ *  - Apache/2.2.3 (Win32) mod_python/3.2.10 Python/2.5 
+ *  - Apache/2.2.3 (Debian Etch) mod_python/3.2.10 Python/2.4.4 
+ *
+ * You shouldn't need to make any change to this file, instead see
+ *  config.py and .htaccess
+ *
+"""
+import config as Config
+
+import cgi
+import cgitb; cgitb.enable()
+import os, sys, re
+try: # Windows needs stdio set for binary mode.
+	import msvcrt
+	msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
+	msvcrt.setmode (1, os.O_BINARY) # stdout = 1
+except ImportError:
+	pass
+
+def WSGIApp(environ, start_response): # entry point
+
+	# This is the function that sends the results of the uploading process 
+	# WSGI compilant (generator)
+	def SendResults( errorNumber, fileUrl = '', fileName = '', customMsg = '' ):
+		yield """<script type="text/javascript">
+			window.parent.OnUploadCompleted(%(errorNumber)s,"%(fileUrl)s","%(fileName)s","%(customMsg)s"); 
+			</script>""" % {
+			'errorNumber': errorNumber,
+			'fileUrl': fileUrl.replace ('"', '\\"'),
+			'fileName': fileName.replace ( '"', '\\"' ) , 
+			'customMsg': customMsg.replace ( '"', '\\"' ),
+			}
+	
+	def GetRootPath():
+		# WARNING: this is not be thread safe, and doesn't work w/ VirtualServer/mod_python
+		# Use Config.UserFilesAbsolutePath instead
+		if environ.has_key('DOCUMENT_ROOT'):
+			return environ['DOCUMENT_ROOT']
+		else:
+			sRealPath = os.path.realpath( './' ) 
+			sSelfPath = environ['SCRIPT_FILENAME']
+			sSelfPath = sSelfPath [ :  sSelfPath.rfind( '/' ) ] 
+			sRealPath = sRealPath [ : len(sRealPath) - len(sSelfPath) ]
+			return sRealPath
+
+
+	# Start WSGI response:
+	start_response ("200 Ok",[("Content-type","text/html")])
+	
+	# Check if this uploader has been enabled.
+	if not Config.Enabled:	
+		return SendResults( '1', '', '', 'This file uploader is disabled. Please check the "editor/filemanager/upload/py/config.py" file' )
+
+	# Get the posted form data
+	oForm = cgi.FieldStorage(fp=environ['wsgi.input'],
+							environ=environ,
+							keep_blank_values=1)
+
+	# Check if the file has been correctly uploaded.
+	if not oForm.has_key('NewFile') or not oForm['NewFile'].file:
+		return SendResults( '202' ) 
+
+	# Get the posted file.
+	oFile = oForm['NewFile']
+
+	# Get the uploaded file name extension.
+	sFileName = oFile.filename
+
+	# Replace dots in the name with underscores (only one dot can be there... security issue).
+	if ( Config.ForceSingleExtension ):
+		sFileName = re.sub( r'\.(?![^.]*$)', '_', sFileName ) 
+	
+	sFileName = sFileName.replace('\\','/')			# convert windows to unix path
+	sFileName = os.path.basename (sFileName)	# strip directories
+	sOriginalFileName = sFileName ;
+
+	# Get the extension.
+	sExtension = sFileName[ sFileName.rfind('.') + 1 : ]
+	sExtension = sExtension.lower
+
+	# The the file type (from the QueryString, by default 'File').
+	sType = oForm.has_key('Type') and oForm('Type') or 'File' 
+
+	# Check if it is an allowed type.
+	if not sType in ('File','Image','Flash','Media'):
+		return SendResults( 1, '', '', 'Invalid type specified' ) 
+
+	# Get the allowed and denied extensions arrays.
+	arAllowed	= Config.AllowedExtensions[sType] ;
+	arDenied	= Config.DeniedExtensions[sType] ;
+
+	# Check if it is an allowed extension.
+	if ( len(arAllowed) > 0 and not sExtension in arAllowed  ) or ( len(arDenied) > 0 and sExtension in arDenied ):
+		return SendResults( '202' )
+
+	sErrorNumber	= '0' ;
+	sFileUrl	= '' ;
+
+	# Initializes the counter used to rename the file, if another one with the same name already exists.
+	iCounter = 0 
+
+	# Get the target directory.
+	if ( Config.UserFilesAbsolutePath ):
+		sServerDir = Config.UserFilesAbsolutePath[sType]
+	else:
+		sServerDir = GetRootPath() + Config.UserFilesPath[sType]
+
+	if ( Config.UseFileType ):
+		sServerDir = sServerDir + sType + '/' 
+
+	while True:
+		# Compose the file path.
+		sFilePath = sServerDir + sFileName 
+
+		# If a file with that name already exists.
+		if os.path.exists( sFilePath ):
+			iCounter+=1
+			sFileName = sOriginalFileName.replace('.','(%d).' % iCounter ) 
+			sErrorNumber = '201' 
+		else:
+			# Read file contents and write to the desired path (similar to php's move_uploaded_file)
+			fout = file(sFilePath, 'wb')
+			while 1:
+				chunk = oFile.file.read(100000)
+				if not chunk: break
+				fout.write (chunk)
+			fout.close()
+
+			if os.path.exists ( sFilePath ):
+				oldumask = os.umask(0) 
+				os.chmod( sFilePath, 0755 ) 
+				os.umask( oldumask ) 
+
+			if ( Config.UseFileType ):
+				sFileUrl = Config.UserFilesPath[sType] + sType + '/' + sFileName
+			else:
+				sFileUrl = Config.UserFilesPath[sType] + sFileName
+
+			break
+
+	return SendResults ( sErrorNumber, sFileUrl, sFileName ) ;
+
+
+
+# Running from command line (CGI), in case of no mod_python nor wsgi server available
+if __name__ == '__main__':
+	try:
+		import cgi2wsgi
+		cgi2wsgi.run(WSGIApp)     # (call cgi to wsgi wrapper to execute WSGIApp)
+	except:
+		print "Content-Type: text/plain"
+		print
+		cgi.print_exception()
Index: editor/filemanager/upload/py/config.py
===================================================================
--- editor/filemanager/upload/py/config.py	(revisin: 0)
+++ editor/filemanager/upload/py/config.py	(revisin: 0)
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+"""
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Configuration file for the Python File Uploader.
+"""
+   
+# SECURITY: You must explicitelly enable this "uploader".
+Enabled = False 
+
+# Set if the file type must be considere in the target path.
+# Ex: /userfiles/image/ or /userfiles/file/
+UseFileType = False # deprecated, use UserFilesPath { file_type : file_path }
+
+# Path to uploaded files relative to the document root: { Type: Path }
+UserFilesPath = {   'File':'/files/',
+                    'Images':'/images/',
+                    'Flash':'/flash/',
+                }
+
+# Fill the following value it you prefer to specify the absolute path for the
+# user files directory. Usefull if you are using a virtual directory, symbolic
+# link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
+# Attention: The above 'UserFilesPath' must point to the same directory.
+# WARNING: GetRootPath may not work in virtual or mod_python configurations, and
+# may not be thread safe. Use this configuration parameter instead.
+UserFilesAbsolutePath = {   'File':'/var/www/files/',
+        		            'Images':'/var/www/images/',
+		                    'Flash':'/var/www/flash/',
+                } 
+
+# Due to security issues with Apache modules, it is reccomended to leave the
+# following setting enabled.
+ForceSingleExtension = True 
+
+AllowedExtensions={ 'File': [],
+                    'Image':['jpg','gif','jpeg','png'],
+                    'Flash':['swf','fla'] 
+                  }
+    
+DeniedExtensions={  'File': ['html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis'],
+                    'Image': [],
+                    'Flash': [],
+                 }
Index: editor/filemanager/upload/py/.htaccess
===================================================================
--- editor/filemanager/upload/py/.htaccess	(revisin: 0)
+++ editor/filemanager/upload/py/.htaccess	(revisin: 0)
@@ -0,0 +1,30 @@
+# you must use either wsgi, php-like o cgi functionality
+
+# php-like functionality (default):
+#  - calling .../py/upload.py
+#  - can serve files from the same directory
+#  - can do automatic reloading of source files
+#  - no need to specify PythonPath (if wsighandler.py and modpython_gateway.py are already inside PythonPath, in site-pacakges, if not, see PythonPath directive below)
+
+AddHandler mod_python .py
+PythonHandler wsgihandler::handler
+PythonOption reload-modules no
+
+
+# wsgi functionality:
+#  - calling .../py/ executes the script
+#  - cannot serve files from the same directory
+#  - no automatic reloading posible
+#  - you must specify PythonPath to include the script directory
+
+#SetHandler python-program
+#PythonHandler modpython_gateway::handler
+#PythonOption application upload::WSGIApp
+#PythonPath "['C:/Archivos de programa/Apache Software Foundation/Apache2.2/htdocs/'] + sys.path"
+
+
+# cgi functionality (not recomended, very slow)
+#Options +ExecCGI 
+#AddHandler cgi-script py
+ 
+Allow from all
Index: editor/filemanager/upload/py/cgi2wsgi.py
===================================================================
--- editor/filemanager/upload/py/cgi2wsgi.py	(revisin: 0)
+++ editor/filemanager/upload/py/cgi2wsgi.py	(revisin: 0)
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+# taken from http://www.python.org/dev/peps/pep-0333/
+
+import os, sys
+
+def run(wsgi_app):
+    #if sys.argv.:
+    #    instancedir=sys.argv[1]
+    #else
+    instancedir=''
+        
+    stream=sys.stdout
+
+    environ = dict(os.environ.items())
+    environ['wsgi.input']        = sys.stdin
+    environ['wsgi.errors']       = sys.stderr
+    environ['wsgi.version']      = (1, 0)
+    environ['wsgi.multithread']  = False
+    environ['wsgi.multiprocess'] = True
+    environ['wsgi.run_once']    = True
+
+    if environ.get('HTTPS','off') in ('on','1'):
+        environ['wsgi.url_scheme'] = 'https'
+    else:
+        environ['wsgi.url_scheme'] = 'http'
+
+    headers_set = []
+    headers_sent = []
+
+    def write(data):
+        if not headers_set:
+            raise AssertionError("write() before start_response()")
+
+        elif not headers_sent:
+            # Before the first output, send the stored headers
+            status, response_headers = headers_sent[:] = headers_set
+            stream.write('Status: %s\r\n' % status)
+            for header in response_headers:
+                stream.write('%s: %s\r\n' % header)
+            stream.write('\r\n')
+
+        stream.write(data)
+        stream.flush()
+
+    def start_response(status, response_headers, exc_info=None):
+        if exc_info:
+            try:
+                if headers_sent:
+                    # Re-raise original exception if headers sent
+                    raise exc_info[0], exc_info[1], exc_info[2]
+            finally:
+                exc_info = None     # avoid dangling circular ref
+        elif headers_set:
+            raise AssertionError("Headers already set!")
+
+        headers_set[:] = [status, response_headers]
+        return write
+
+    result = wsgi_app(environ, start_response)
+    try:
+        for data in result:
+            if data:    # don't send headers until body appears
+                write(data)
+        if not headers_sent:
+            write('')   # send headers now if body was empty
+    finally:
+        if hasattr(result,'close'):
+            result.close()
+
Index: editor/filemanager/upload/py/modpython_gateway.py
===================================================================
--- editor/filemanager/upload/py/modpython_gateway.py	(revisin: 0)
+++ editor/filemanager/upload/py/modpython_gateway.py	(revisin: 0)
@@ -0,0 +1,212 @@
+"""
+WSGI wrapper for mod_python. Requires Python 2.2 or greater.
+
+
+Example httpd.conf section for a CherryPy app called "mcontrol":
+
+<Location /mcontrol>
+    SetHandler python-program
+    PythonFixupHandler mcontrol.cherry::startup
+    PythonHandler modpython_gateway::handler
+    PythonOption wsgi.application cherrypy._cpwsgi::wsgiApp
+</Location>
+
+Some WSGI implementations assume that the SCRIPT_NAME environ variable will
+always be equal to "the root URL of the app"; Apache probably won't act as
+you expect in that case. You can add another PythonOption directive to tell
+modpython_gateway to force that behavior:
+
+    PythonOption SCRIPT_NAME /mcontrol
+
+Some WSGI applications need to be cleaned up when Apache exits. You can
+register a cleanup handler with yet another PythonOption directive:
+
+    PythonOption wsgi.cleanup module::function
+
+The module.function will be called with no arguments on server shutdown,
+once for each child process or thread.
+"""
+
+import traceback
+
+from mod_python import apache
+
+
+class InputWrapper(object):
+    
+    def __init__(self, req):
+        self.req = req
+    
+    def close(self):
+        pass
+    
+    def read(self, size=-1):
+        return self.req.read(size)
+    
+    def readline(self, size=-1):
+        return self.req.readline(size)
+    
+    def readlines(self, hint=-1):
+        return self.req.readlines(hint)
+    
+    def __iter__(self):
+        line = self.readline()
+        while line:
+            yield line
+            # Notice this won't prefetch the next line; it only
+            # gets called if the generator is resumed.
+            line = self.readline()
+
+
+class ErrorWrapper(object):
+    
+    def __init__(self, req):
+        self.req = req
+    
+    def flush(self):
+        pass
+    
+    def write(self, msg):
+        self.req.log_error(msg)
+    
+    def writelines(self, seq):
+        self.write(''.join(seq))
+
+
+bad_value = ("You must provide a PythonOption '%s', either 'on' or 'off', "
+             "when running a version of mod_python < 3.1")
+
+
+class Handler:
+    
+    def __init__(self, req):
+        self.started = False
+        
+        options = req.get_options()
+        
+        # Threading and forking
+        try:
+            q = apache.mpm_query
+            threaded = q(apache.AP_MPMQ_IS_THREADED)
+            forked = q(apache.AP_MPMQ_IS_FORKED)
+        except AttributeError:
+            threaded = options.get('multithread', '').lower()
+            if threaded == 'on':
+                threaded = True
+            elif threaded == 'off':
+                threaded = False
+            else:
+                raise ValueError(bad_value % "multithread")
+            
+            forked = options.get('multiprocess', '').lower()
+            if forked == 'on':
+                forked = True
+            elif forked == 'off':
+                forked = False
+            else:
+                raise ValueError(bad_value % "multiprocess")
+        
+        env = self.environ = dict(apache.build_cgi_env(req))
+        
+        if 'SCRIPT_NAME' in options:
+            # Override SCRIPT_NAME and PATH_INFO if requested.
+            env['SCRIPT_NAME'] = options['SCRIPT_NAME']
+            env['PATH_INFO'] = req.uri[len(options['SCRIPT_NAME']):]
+        
+        env['wsgi.input'] = InputWrapper(req)
+        env['wsgi.errors'] = ErrorWrapper(req)
+        env['wsgi.version'] = (1,0)
+        env['wsgi.run_once'] = False
+        if env.get("HTTPS") in ('yes', 'on', '1'):
+            env['wsgi.url_scheme'] = 'https'
+        else:
+            env['wsgi.url_scheme'] = 'http'
+        env['wsgi.multithread']  = threaded
+        env['wsgi.multiprocess'] = forked
+        
+        self.request = req
+    
+    def run(self, application):
+        # 20070226: DISABLE Exception Handling to be directy handled by wsgihandler
+        #try:
+            result = application(self.environ, self.start_response)
+            for data in result:
+                self.write(data)
+            if not self.started:
+                self.request.set_content_length(0)
+            if hasattr(result, 'close'):
+                result.close()
+        #except:
+        #    traceback.print_exc(None, self.environ['wsgi.errors'])
+        #    if not self.started:
+        #        self.request.status = 500
+        #        self.request.content_type = 'text/plain'
+        #        data = "A server error occurred. Please contact the administrator."
+        #        self.request.set_content_length(len(data))
+        #        self.request.write(data)
+    
+    def start_response(self, status, headers, exc_info=None):
+        if exc_info:
+            try:
+                if self.started:
+                    raise exc_info[0], exc_info[1], exc_info[2]
+            finally:
+                exc_info = None
+        
+        self.request.status = int(status[:3])
+        
+        for key, val in headers:
+            if key.lower() == 'content-length':
+                self.request.set_content_length(int(val))
+            elif key.lower() == 'content-type':
+                self.request.content_type = val
+            else:
+                self.request.headers_out.add(key, val)
+        
+        return self.write
+    
+    def write(self, data):
+        if not self.started:
+            self.started = True
+        self.request.write(data)
+
+
+startup = None
+cleanup = None
+
+def handler(req):
+    # Run a startup function if requested.
+    global startup
+    if not startup:
+        func = req.get_options().get('wsgi.startup')
+        if func:
+            module_name, object_str = func.split('::', 1)
+            module = __import__(module_name, globals(), locals(), [''])
+            startup = apache.resolve_object(module, object_str)
+            startup(req)
+    
+    # Register a cleanup function if requested.
+    global cleanup
+    if not cleanup:
+        func = req.get_options().get('wsgi.cleanup')
+        if func:
+            module_name, object_str = func.split('::', 1)
+            module = __import__(module_name, globals(), locals(), [''])
+            cleanup = apache.resolve_object(module, object_str)
+            def cleaner(data):
+                cleanup()
+            try:
+                # apache.register_cleanup wasn't available until 3.1.4.
+                apache.register_cleanup(cleaner)
+            except AttributeError:
+                req.server.register_cleanup(req, cleaner)
+    
+    # Import the wsgi 'application' callable and pass it to Handler.run
+    modname, objname = req.get_options()['wsgi.application'].split('::', 1)
+    module = __import__(modname, globals(), locals(), [''])
+    app = getattr(module, objname)
+    Handler(req).run(app)
+    
+    # status was set in Handler; always return apache.OK
+    return apache.OK
+
Index: editor/filemanager/upload/py/wsgihandler.py
===================================================================
--- editor/filemanager/upload/py/wsgihandler.py	(revisin: 0)
+++ editor/filemanager/upload/py/wsgihandler.py	(revisin: 0)
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+"""
+    WSGI Handler form Mod Python:
+    
+    This module implement cgihandler-like functionality but for WSGI.
+    It allows to call standalone WSGI script without too much configuration,
+    and keep serving static files in the same directory (ala PHP)
+
+    Each script (.py) must contain a WSGI compilant callable named WSGIApp
+
+    Use .htaccess:
+        AddHandler mod_python .py
+        PythonHandler wsgihandler
+
+    This need either modpywsgi.py or modpython_gateway.py (WSGI gateways) be
+    present inside python path.
+    
+    If this script is stored inside python path (normally site-packages),
+    no PythonPath directive is needed (script directory is appended to
+    sys.path), so you could import modules in script directory normally. 
+    
+    If you cannot install both scripts in site-packages, just modify .htaccess:
+        AddHandler mod_python .py
+        PythonHandler wsgihandler
+        PythonPath "['/your/script/path'] + sys.path"
+    And copy modpywsgi.py or modpython_gateway.py and wsgihandler.py with your
+    script.
+    
+    license: GNU GPL
+"""
+
+# Copyright (C) 2007 Mariano Reingart <mr@nsis.com.ar>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+import os
+import sys
+from mod_python import apache
+
+try:
+    # first, try to import "official" modpython wsgi gateway
+    import modpython_gateway
+    srv=modpython_gateway.Handler
+except ImportError:
+    try:
+        import modpywsgi
+        srv=modpywsgi.WSGIServer
+    except ImportError:
+        # sorry, no gateway found, raise apache error
+        raise apache.SERVER_RETURN, apache.HTTP_BAD_GATEWAY
+
+__author__ = 'Mariano Reingart <mr@nsis.com.ar>'
+
+# keep original modules, in order to refresh user ones
+# (only in development, to prevent restarting apache to apply changes)
+original = sys.modules.keys()
+# find out the standard library location
+stdlib, x = os.path.split(os.__file__)
+
+def handler(req):
+    options=req.get_options()
+
+    # this allows make changes to source files and get them imported without
+    # restarting apache
+    if options.get('reload-modules', '').lower()=='yes':    
+        for m in sys.modules.keys():
+            if m not in original:
+                # unless they are part of standard library
+                mod = sys.modules[m]
+                if hasattr(mod, "__file__"):
+                    path, x = os.path.split(mod.__file__)
+                    if path != stdlib:
+                        del sys.modules[m]
+                    
+    # get the filename of the script (copied from cgihandler)
+    if req.subprocess_env.has_key("script_filename"):
+        dir, file = os.path.split(req.subprocess_env["script_filename"])
+    else:
+        dir, file = os.path.split(req.filename)
+
+    module_name, ext = os.path.splitext(file)
+
+    # automagically append script directory to sys.path
+    if dir not in sys.path:
+        sys.path.append(dir)
+    
+    try:
+        module = __import__(module_name)
+    except ImportError:
+        raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
+    
+    app = getattr(module, "WSGIApp")
+
+    try:        
+        # create server and run WSGIApp
+        if srv.__name__ == 'WSGIServer':
+            # this is to prevent that modpywsgi alter SCRIPT_NAME
+            options['untouched_scriptname']='yes'  
+            srv(app).run(req)
+        elif srv.__name__ == 'Handler':
+            srv(req).run(app)
+    except:
+        # print fancy exception output
+        import cgitb
+        req.status = int(200)        
+        req.content_type = "text/html"
+        req.write(cgitb.html(sys.exc_info()))
+    
+    # allways return apache.OK (status was set in Handler)     
+    return apache.OK
