Re: pyblosxom1.2 + mod_python/2.7.10 on apache 1.3.33

Pasi Savolainen <[email protected]>
Newsgroups gmane.comp.web.pyblosxom.user
Message-ID <[email protected]>
* Steven Armstrong <[email protected]>:
>
> Do you have other mod_python scripts that work in your setup?
> Maybe write a simple handler that sets some headers and writes a Hello
> World or something to check if your installation basically works?

Did that now and noticed that it also lacks header output. Apparently
mod_python for apache 1.3 needs send_http_header() called. I've not
checked but this behaviour applies when using directive
PythonHandler test::handler

- test.py -
# 'really' minimal HTTP handler
from mod_python import apache

def handler(req):
    req.content_type = "text/plain"
    req.send_http_header()
    req.write( "1, 2, 3")
    return apache.OK
- -

> One guess would be that something goes wrong in the method
> 'ModPythonHandler send_headers' in mp_wsgi_handler.py. Maybe for some
> reason it doesn't get called?

I had already poked at it and saw that headers _were_ being generated
(using this kind of 'debug': print >> file('/tmp/pbdeb', 'a'), "--sr: ", self.request  ...)
Some part in newer mod_python calls the header flushing function, but
in older mod_python that needs to be explicit.

Many thanks for nudging me into right direction.
I very much like the added performance over plain perl blosxom. My
pageload has dropped from 3s to 0.5s, and blosxom has most of content
cached.
I think I'll be giving to couple of blosxom plugins some python lovin'
and try to convert my site over to pyblosxom.

Inlined is patch needed to make pyblosxom/mp_wsgi_handler runnable under
mod_python/2.7. I have step-by-step instructions written, but they do
get quite hairy with need to separate server-side-view and clientside
view. I'd say managing apache would get a lot easier with partial
unification of these.

- -
--- mp_wsgi_handler.py.orig	2005-02-28 02:29:32.000000000 +0200
+++ mp_wsgi_handler.py	2005-03-28 13:43:41.041075046 +0300
@@ -27,6 +27,13 @@
 # mod_python imports
 from mod_python import apache
 
+# workaround for earlier mod_python not having smart enough mp_table
+def __getAOpt__(options, x, xdef):
+    if getattr(options, 'get', 'notthere') == 'notthere':
+        if options.has_key(x):
+            return options[x]
+        return xdef
+    return options.get(x, xdef)
 
 class ModPythonInputWrapper(object):
     
@@ -55,7 +62,8 @@
     def __init__(self, request):
         self._request = request
         config = request.get_config()
-        self.debug = int(config.get("PythonDebug", 0))
+        cget = lambda x, xdef: __getAOpt__(config, x, xdef)
+        self.debug = int(cget("PythonDebug", 0))
 
     def write(self, msg):
         self._request.log_error(msg)
@@ -71,13 +79,25 @@
     
     def __init__(self, req):
         options = req.get_options()
+        # The root uri sometimes has to be explicitly specified because apache
+        # sometimes get req.path_info wrong if many <alias> and <location> directives
+        # are used. <http://projects.edgewall.com/trac/changeset/797>
+        if options.has_key('ApplicationPath'):
+            root_uri = options['ApplicationPath'].rstrip('/')
+            if req.uri[:len(root_uri)] != root_uri:
+                raise ValueError('ApplicationPath set to "%s" but req.uri starts with "%s"' %
+                      (root_uri, req.uri[:len(root_uri)]))
+            self.path_info = req.uri[len(root_uri):]
+        else:
+            self.path_info = req.path_info
 
         try:
             q = apache.mpm_query
         except AttributeError:
             # Threading and forking
-            threaded = options.get('multithread', '')
-            forked = options.get('multiprocess', '')
+            oget = lambda x, xdef: __getAOpt__(options, x, xdef)
+            threaded = oget('multithread', '')
+            forked = oget('multiprocess', '')
             if not (threaded and forked):
                 raise ValueError("You must provide 'multithread' and "
                                  "'multiprocess' PythonOptions when "
@@ -98,6 +118,8 @@
         # store the mod_python request instance in the env dict 
         # so it is accessible from the application
         env['mod_python.request'] = req
+        # store fixed-up PATH_INFO.
+        env['PATH_INFO'] = self.path_info
 
         BaseCGIHandler.__init__(self,
                                 stdin=ModPythonInputWrapper(req),
@@ -124,6 +146,9 @@
                 self.request.content_type = str(val)
             else:
                 self.request.headers_out[key] = val
+        # mod_python 2.7 need this, it doesn't send headers out automatically when
+        # using PythonHandler file::handler -directive.
+        self.request.send_http_header()
 
 # TODO: implement this
 #    def sendfile(self, file=None, offset=0, len=-1):
@@ -159,10 +184,9 @@
     handler = ModPythonHandler(req)
     options = req.get_options()
     config = req.get_config()
-    debug = int(config.get("PythonDebug", 0))
     modname, objname = options['application'].split('::')
-    module = apache.import_module(modname, autoreload=False, log=debug)
-    app = apache.resolve_object(module, objname, arg=None, silent=False)
+    module = apache.import_module(modname)
+    app = apache.resolve_object(req, module, objname, silent=False)
     handler.run(app)
 
     return apache.OK
- -



-- 
   Psi -- <http://www.iki.fi/pasi.savolainen>



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.