Mercurial > bzapi
annotate bzapi_server.py @ 37:c6b41464c021 default tip
factored async web server into separate file
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 24 Dec 2009 18:34:51 -0800 |
parents | 352f4cc55d12 |
children |
rev | line source |
---|---|
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
1 import os |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
2 import sys |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
3 import re |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
4 import cgi |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
5 import logging |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
6 |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
7 try: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
8 import json |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
9 except ImportError: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
10 import simplejson as json |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
11 |
37
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
12 import channels |
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
13 import cosocket |
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
14 from async_web_server import until_http_response_sent |
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
15 from async_web_server import until_http_file_sent |
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
16 from async_web_server import AsyncWebServer |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
17 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
18 class BugzillaApiApp(object): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
19 QUERYSTRING_TEMPLATE = re.compile('([^\?]*)\?(.*)') |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
20 REDIRECT_TEMPLATE = re.compile('\/([A-Za-z0-9_]+)$') |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
21 URL_TEMPLATE = re.compile('\/([A-Za-z0-9_]+)/(.*)') |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
22 MAX_MESSAGE_SIZE = 8192 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
23 ROBOTS_TXT = "User-agent: *\r\nDisallow: /" |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
24 |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
25 def __init__(self, media_dir, index_filename): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
26 self._media_dir = media_dir |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
27 self._index_filename = index_filename |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
28 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
29 def until_request_processed(self, method, path, headers, addr): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
30 match = self.URL_TEMPLATE.match(path) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
31 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
32 if path == '/': |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
33 yield until_http_file_sent(self._index_filename) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
34 elif not match: |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
35 match = self.REDIRECT_TEMPLATE.match(path) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
36 if match: |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
37 newpath = path + '/' |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
38 yield until_http_response_sent( |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
39 newpath, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
40 code = 301, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
41 additional_headers = {'Location': newpath} |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
42 ) |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
43 elif path == '/robots.txt': |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
44 yield until_http_response_sent(self.ROBOTS_TXT) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
45 else: |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
46 yield until_http_response_sent('not found', |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
47 code = 404) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
48 else: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
49 conv_name = match.group(1) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
50 page = match.group(2) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
51 if conv_name == 'status': |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
52 # TODO: Return 404 if page is non-empty. |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
53 lines = ('open connections : %d' % self._num_connections, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
54 'open timers : %d' % len(time_map)) |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
55 yield until_http_response_sent('\r\n'.join(lines)) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
56 elif conv_name == 'media': |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
57 path = os.path.join(self._media_dir, *page.split('/')) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
58 path = os.path.normpath(path) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
59 if (path.startswith(self._media_dir) and |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
60 os.path.exists(path) and |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
61 os.path.isfile(path)): |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
62 yield until_http_file_sent(path) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
63 else: |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
64 yield until_http_response_sent('not found', |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
65 code = 404) |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
66 else: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
67 yield self._until_conv_request_processed(addr, headers, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
68 method, conv_name, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
69 page) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
70 |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
71 def _parse_qs(self, querystring): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
72 querydict = {} |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
73 cgi_querydict = cgi.parse_qs(querystring) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
74 for key, value in cgi_querydict.items(): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
75 querydict[key] = cgi_querydict[key][0] |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
76 return querydict |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
77 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
78 def _until_conv_request_processed(self, addr, headers, method, |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
79 conv_name, page): |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
80 match = self.QUERYSTRING_TEMPLATE.match(page) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
81 querydict = {} |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
82 if match: |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
83 querydict.update(self._parse_qs(match.group(2))) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
84 page = match.group(1) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
85 if page == 'listen': |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
86 logging.info("Waiting for message on channel '%s' for %s" % |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
87 (conv_name, addr)) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
88 msg = yield channels.until_message_received(conv_name) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
89 yield until_http_response_sent( |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
90 json.dumps(msg), |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
91 mimetype = 'application/json' |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
92 ) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
93 elif page == 'send': |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
94 length = int(headers.getheader('Content-Length', 0)) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
95 if length == 0 or length > self.MAX_MESSAGE_SIZE: |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
96 yield until_http_response_sent('message too large', |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
97 code = 413) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
98 else: |
37
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
99 msg = yield cosocket.until_received(bytes = length) |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
100 json_msg = json.loads(msg) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
101 yield channels.until_message_sent(conv_name, json_msg) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
102 yield until_http_response_sent('sent.') |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
103 else: |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
104 yield until_http_response_sent('not found', code = 404) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
105 |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
106 if __name__ == '__main__': |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
107 args = dict(ip = '127.0.0.1', |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
108 port = 8071, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
109 logfile = '', |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
110 loglevel = 'info', |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
111 media_dir = os.path.abspath('media')) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
112 |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
113 args['index_filename'] = os.path.join(args['media_dir'], 'html', |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
114 'index.html') |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
115 args['loglevel'] = getattr(logging, args['loglevel'].upper()) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
116 if args['logfile']: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
117 logging.basicConfig(filename = args['logfile'], |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
118 level = args['loglevel']) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
119 else: |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
120 logging.basicConfig(stream = sys.stdout, |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
121 level = args['loglevel']) |
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
122 |
35
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
123 app = BugzillaApiApp(media_dir = args['media_dir'], |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
124 index_filename = args['index_filename']) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
125 |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
126 server = AsyncWebServer(addr = (args['ip'], args['port']), |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
127 app = app) |
45d84e588d14
massive refactorings to bzapi_server.py
Atul Varma <varmaa@toolness.com>
parents:
34
diff
changeset
|
128 |
34
b4fab248d1eb
Added a bunch of files from http://hg.toolness.com/cosocket
Atul Varma <varmaa@toolness.com>
parents:
diff
changeset
|
129 logging.info("Starting server with configuration: %s" % args) |
37
c6b41464c021
factored async web server into separate file
Atul Varma <varmaa@toolness.com>
parents:
36
diff
changeset
|
130 cosocket.loop() |