1
2
3
4
5
6 import re
7 import sys
8 import StringIO
9 import traceback
10 from urllib import unquote
11
12 from restkit.util import url_encode
13
14 from .. import __version__
15 from ..external import External
16
18 return "-".join([w.lower().capitalize() for w in name.split("-")])
19
21
22 SERVER_VERSION = "couchdbkit/%s" % __version__
23
25 self.line = line
26 self.response_status = 200
27 self.response_headers = {}
28 self.start_response_called = False
29
31 headers = self.parse_headers()
32
33 length = headers.get("CONTENT_LENGTH")
34 if self.line["body"] and self.line["body"] != "undefined":
35 length = len(self.line["body"])
36 body = StringIO.StringIO(self.line["body"])
37
38 else:
39 body = StringIO.StringIO()
40
41
42 script_name, path_info = self.line['path'][:2], self.line['path'][2:]
43 if path_info:
44 path_info = "/%s" % "/".join(path_info)
45 else:
46 path_info = ""
47 script_name = "/%s" % "/".join(script_name)
48
49
50 args = []
51 query_string = None
52 for k, v in self.line["query"].items():
53 if v is None:
54 continue
55 else:
56 args.append((k,v))
57 if args: query_string = url_encode(dict(args))
58
59
60 path = "%s%s" % (path_info, query_string)
61
62
63 if ":" in self.line["headers"]["Host"]:
64 server_address = self.line["headers"]["Host"].split(":")
65 else:
66 server_address = (self.line["headers"]["Host"], 80)
67
68 environ = {
69 "wsgi.url_scheme": 'http',
70 "wsgi.input": body,
71 "wsgi.errors": StringIO.StringIO(),
72 "wsgi.version": (1, 0),
73 "wsgi.multithread": False,
74 "wsgi.multiprocess": True,
75 "wsgi.run_once": False,
76 "SCRIPT_NAME": script_name,
77 "SERVER_SOFTWARE": self.SERVER_VERSION,
78 "COUCHDB_INFO": self.line["info"],
79 "COUCHDB_REQUEST": self.line,
80 "REQUEST_METHOD": self.line["verb"].upper(),
81 "PATH_INFO": unquote(path_info),
82 "QUERY_STRING": query_string,
83 "RAW_URI": path,
84 "CONTENT_TYPE": headers.get('CONTENT-TYPE', ''),
85 "CONTENT_LENGTH": length,
86 "REMOTE_ADDR": self.line['peer'],
87 "REMOTE_PORT": 0,
88 "SERVER_NAME": server_address[0],
89 "SERVER_PORT": int(server_address[1]),
90 "SERVER_PROTOCOL": "HTTP/1.1"
91 }
92
93 for key, value in headers.items():
94 key = 'HTTP_' + key.replace('-', '_')
95 if key not in ('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH'):
96 environ[key] = value
97
98 return environ
99
101 self.response_status = int(status.split(" ")[0])
102 for name, value in response_headers:
103 name = _normalize_name(name)
104 self.response_headers[name] = value.strip()
105 self.start_response_called = True
106
108 headers = {}
109 for name, value in self.line.get("headers", {}).items():
110 name = name.strip().upper().encode("utf-8")
111 headers[name] = value.strip().encode("utf-8")
112 return headers
113
115
116 - def __init__(self, application, stdin=sys.stdin,
117 stdout=sys.stdout):
118 External.__init__(self, stdin=stdin, stdout=stdout)
119 self.app = application
120
122 try:
123 req = WSGIRequest(line)
124 response = self.app(req.read(), req.start_response)
125 except:
126 self.send_response(500, "".join(traceback.format_exc()),
127 {"Content-Type": "text/plain"})
128 return
129
130 content = "".join(response).encode("utf-8")
131 self.send_response(req.response_status, content, req.response_headers)
132