1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Twisted Request Implementation
@copyright: 2001-2003 Juergen Hermann <jh@web.de>,
2003-2006 MoinMoin:ThomasWaldmann
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin import log
logging = log.getLogger(__name__)
from MoinMoin.request import RequestBase, MoinMoinFinish, RemoteClosedConnection
class Request(RequestBase):
""" specialized on Twisted requests """
def __init__(self, twistedRequest, pagename, reactor, properties={}):
try:
self.twistd = twistedRequest
self.reactor = reactor
# Copy headers
self.http_accept_language = self.twistd.getHeader('Accept-Language')
self.saved_cookie = self.twistd.getHeader('Cookie')
self.http_user_agent = self.twistd.getHeader('User-Agent')
try:
self.content_length = int(self.twistd.getHeader('Content-Length'))
except (TypeError, ValueError):
self.content_length = None
self.if_modified_since = self.twistd.getHeader('If-Modified-Since')
self.if_none_match = self.twistd.getHeader('If-None-Match')
# Copy values from twisted request
self.server_protocol = self.twistd.clientproto
self.server_name = self.twistd.getRequestHostname().split(':')[0]
self.server_port = str(self.twistd.getHost()[2])
self.is_ssl = self.twistd.isSecure()
self.path_info = '/' + '/'.join([pagename] + self.twistd.postpath)
self.request_method = self.twistd.method
self.remote_addr = self.twistd.getClientIP()
self.request_uri = self.twistd.uri
self.script_name = "/" + '/'.join(self.twistd.prepath[:-1])
# Values that need more work
self.query_string = self.splitURI(self.twistd.uri)[1]
self.setHttpReferer(self.twistd.getHeader('Referer'))
self.setHost()
self.setURL(self.twistd.getAllHeaders())
##self.debugEnvironment(twistedRequest.getAllHeaders())
RequestBase.__init__(self, properties)
except MoinMoinFinish: # might be triggered by http_redirect
self.emit_http_headers() # send headers (important for sending MOIN_ID cookie)
self.finish()
except Exception, err:
# Wrap err inside an internal error if needed
from MoinMoin import error
if isinstance(err, error.FatalError):
self.delayedError = err
else:
self.delayedError = error.InternalError(str(err))
def run(self):
""" Handle delayed errors then invoke base class run """
if hasattr(self, 'delayedError'):
self.fail(self.delayedError)
return self.finish()
RequestBase.run(self)
def setup_args(self):
""" Return args dict
Twisted already parsed args, including __filename__ hacking,
but did not decode the values.
"""
# All of the arguments, including URL and POST arguments (using keep_blank_values=1 internally).
return self.decodeArgs(self.twistd.args)
def read(self, n):
""" Read from input stream. """
# XXX why is that wrong?:
#rd = self.reactor.callFromThread(self.twistd.read)
# XXX do we need self.reactor.callFromThread with that?
# XXX if yes, why doesn't it work?
self.twistd.content.seek(0, 0)
if n is None:
logging.warning("calling request.read(None) might block")
rd = self.twistd.content.read()
else:
rd = self.twistd.content.read(n)
#print "request.RequestTwisted.read: data=\n" + str(rd)
return rd
def write(self, *data):
""" Write to output stream. """
#print "request.RequestTwisted.write: data=\n" + wd
data = self.encode(data)
try:
self.reactor.callFromThread(self.twistd.write, data)
except Exception:
raise RemoteClosedConnection()
def flush(self):
pass # XXX is there a flush in twisted?
def finish(self):
RequestBase.finish(self)
self.reactor.callFromThread(self.twistd.finish)
# Headers ----------------------------------------------------------
def _emit_http_headers(self, headers):
""" private method to send out preprocessed list of HTTP headers """
st_header, other_headers = headers[0], headers[1:]
status = st_header.split(':', 1)[1].lstrip()
status_code, status_msg = status.split(' ', 1)
self.twistd.setResponseCode(int(status_code), status_msg)
for header in other_headers:
key, value = header.split(':', 1)
value = value.lstrip()
if key.lower() == 'set-cookie':
key, value = value.split('=', 1)
self.twistd.addCookie(key, value)
else:
self.twistd.setHeader(key, value)
def http_redirect(self, url):
""" Redirect to a fully qualified, or server-rooted URL
@param url: relative or absolute url, ascii using url encoding.
"""
url = self.getQualifiedURL(url)
self.twistd.redirect(url)
# calling finish here will send the rest of the data to the next
# request. leave the finish call to run()
#self.twistd.finish()
raise MoinMoinFinish
|