comparison MoinMoin/request/request_modpython.py @ 2338:b902f2397c68

rename server and request Implementations by adding a prefix server_, request_
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Thu, 05 Jul 2007 21:23:29 +0200
parents
children ea78a739b5ad
comparison
equal deleted inserted replaced
2290:49188b1e803c 2338:b902f2397c68
1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - mod_python Request Implementation for Apache and mod_python.
4
5 @copyright: 2001-2003 Juergen Hermann <jh@web.de>,
6 2003-2006 MoinMoin:ThomasWaldmann
7 @license: GNU GPL, see COPYING for details.
8 """
9 from MoinMoin import wikiutil
10 from MoinMoin.request import RequestBase
11
12 class Request(RequestBase):
13 """ specialized on mod_python requests """
14
15 def __init__(self, req):
16 """ Saves mod_pythons request and sets basic variables using
17 the req.subprocess_env, cause this provides a standard
18 way to access the values we need here.
19
20 @param req: the mod_python request instance
21 """
22 try:
23 # flags if headers sent out contained content-type or status
24 self._have_ct = 0
25 self._have_status = 0
26
27 req.add_common_vars()
28 self.mpyreq = req
29 # some mod_python 2.7.X has no get method for table objects,
30 # so we make a real dict out of it first.
31 if not hasattr(req.subprocess_env, 'get'):
32 env = dict(req.subprocess_env)
33 else:
34 env = req.subprocess_env
35 self._setup_vars_from_std_env(env)
36 RequestBase.__init__(self)
37
38 except Exception, err:
39 self.fail(err)
40
41 def fixURI(self, env):
42 """ Fix problems with script_name and path_info using
43 PythonOption directive to rewrite URI.
44
45 This is needed when using Apache 1 or other server which does
46 not support adding custom headers per request. With mod_python we
47 can use the PythonOption directive:
48
49 <Location /url/to/mywiki/>
50 PythonOption X-Moin-Location /url/to/mywiki/
51 </location>
52
53 Note that *neither* script_name *nor* path_info can be trusted
54 when Moin is invoked as a mod_python handler with apache1, so we
55 must build both using request_uri and the provided PythonOption.
56 """
57 # Be compatible with release 1.3.5 "Location" option
58 # TODO: Remove in later release, we should have one option only.
59 old_location = 'Location'
60 options_table = self.mpyreq.get_options()
61 if not hasattr(options_table, 'get'):
62 options = dict(options_table)
63 else:
64 options = options_table
65 location = options.get(self.moin_location) or options.get(old_location)
66 if location:
67 env[self.moin_location] = location
68 # Try to recreate script_name and path_info from request_uri.
69 import urlparse
70 scriptAndPath = urlparse.urlparse(self.request_uri)[2]
71 self.script_name = location.rstrip('/')
72 path = scriptAndPath.replace(self.script_name, '', 1)
73 self.path_info = wikiutil.url_unquote(path, want_unicode=False)
74
75 RequestBase.fixURI(self, env)
76
77 def _setup_args_from_cgi_form(self):
78 """ Override to use mod_python.util.FieldStorage
79
80 It's little different from cgi.FieldStorage, so we need to
81 duplicate the conversion code.
82 """
83 from mod_python import util
84 form = util.FieldStorage(self.mpyreq)
85
86 args = {}
87 for key in form:
88 if key is None:
89 continue
90 values = form[key]
91 if not isinstance(values, list):
92 values = [values]
93 fixedResult = []
94
95 for item in values:
96 # Remember filenames with a name hack
97 if hasattr(item, 'filename') and item.filename:
98 args[key + '__filename__'] = item.filename
99 # mod_python 2.7 might return strings instead of Field
100 # objects.
101 if hasattr(item, 'value'):
102 item = item.value
103 fixedResult.append(item)
104 args[key] = fixedResult
105
106 return self.decodeArgs(args)
107
108 def run(self, req):
109 """ mod_python calls this with its request object. We don't
110 need it cause its already passed to __init__. So ignore
111 it and just return RequestBase.run.
112
113 @param req: the mod_python request instance
114 """
115 return RequestBase.run(self)
116
117 def read(self, n=None):
118 """ Read from input stream. """
119 if n is None:
120 return self.mpyreq.read()
121 else:
122 return self.mpyreq.read(n)
123
124 def write(self, *data):
125 """ Write to output stream. """
126 self.mpyreq.write(self.encode(data))
127
128 def flush(self):
129 """ We can't flush it, so do nothing. """
130 pass
131
132 def finish(self):
133 """ Just return apache.OK. Status is set in req.status. """
134 RequestBase.finish(self)
135 # is it possible that we need to return something else here?
136 from mod_python import apache
137 return apache.OK
138
139 def _emit_http_headers(self, headers):
140 """ private method to send out preprocessed list of HTTP headers """
141 st_header, ct_header, other_headers = headers[0], headers[1], headers[2:]
142 status = st_header.split(':', 1)[1].lstrip()
143 self.mpyreq.status = int(status.split(' ', 1)[0])
144 self.mpyreq.content_type = ct_header.split(':', 1)[1].lstrip()
145 for header in other_headers:
146 key, value = header.split(':', 1)
147 value = value.lstrip()
148 self.mpyreq.headers_out[key] = value
149 # this is for mod_python 2.7.X, for 3.X it's a NOP
150 self.mpyreq.send_http_header()
151