aboutsummaryrefslogtreecommitdiffstats
path: root/libpathod/pathod.py
blob: 8a29b9cb311e9c234a13ead17ad7305398508366 (plain)
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
import urllib
from netlib import tcp, protocol, odict, wsgi
import version, app, rparse


class PathodHandler(tcp.BaseHandler):
    def handle(self):
        if self.server.ssloptions:
            self.convert_to_ssl(
                self.server.ssloptions["certfile"],
                self.server.ssloptions["keyfile"],
            )

        line = self.rfile.readline()
        if line == "\r\n" or line == "\n": # Possible leftover from previous message
            line = self.rfile.readline()
        if line == "":
            return None

        method, path, httpversion = protocol.parse_init_http(line)
        if path.startswith(self.server.prefix):
            spec = urllib.unquote(path)[len(self.server.prefix):]
            try:
                presp = rparse.parse({}, spec)
            except rparse.ParseException, v:
                presp = rparse.InternalResponse(
                    800,
                    "Error parsing response spec: %s\n"%v.msg + v.marked()
                )
            presp.serve(self.wfile)
            self.finish()
            return

        headers = odict.ODictCaseless(protocol.read_headers(self.rfile))
        content = protocol.read_http_body_request(
                    self.rfile, self.wfile, headers, httpversion, None
                )
        cc = wsgi.ClientConn(self.client_address)
        req = wsgi.Request(cc, "http", method, path, headers, content)
        sn = self.connection.getsockname()
        app = wsgi.WSGIAdaptor(
            self.server.app,
            sn[0],
            self.server.port,
            version.NAMEVERSION
        )
        app.serve(req, self.wfile)


class Pathod(tcp.TCPServer):
    def __init__(self, addr, ssloptions=None, prefix="/p/"):
        tcp.TCPServer.__init__(self, addr)
        self.ssloptions = ssloptions
        self.prefix = prefix
        self.app = app.app
        self.app.config["pathod"] = self

    def handle_connection(self, request, client_address):
        PathodHandler(request, client_address, self)