~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/request/request_twisted.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mfrom: (0.9.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080622211713-fpo2zrq3s5dfecxg
Tags: 1.7.0-3
Simplify /etc/moin/wikilist format: "USER URL" (drop unneeded middle
CONFIG_DIR that was wrongly advertised as DATA_DIR).  Make
moin-mass-migrate handle both formats and warn about deprecation of
the old one.

Show diffs side-by-side

added added

removed removed

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