Show More
@@ -1,90 +1,87 b'' | |||||
1 | # hgweb/request.py - An http request from either CGI or the standalone server. |
|
1 | # hgweb/request.py - An http request from either CGI or the standalone server. | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. | |
8 |
|
8 | |||
9 | from mercurial.demandload import demandload |
|
9 | from mercurial.demandload import demandload | |
10 | demandload(globals(), "socket sys cgi os errno") |
|
10 | demandload(globals(), "socket sys cgi os errno") | |
11 | from mercurial.i18n import gettext as _ |
|
11 | from mercurial.i18n import gettext as _ | |
12 |
|
12 | |||
13 | class wsgiapplication(object): |
|
13 | class wsgiapplication(object): | |
14 | def __init__(self, destmaker): |
|
14 | def __init__(self, destmaker): | |
15 | self.destmaker = destmaker |
|
15 | self.destmaker = destmaker | |
16 |
|
16 | |||
17 | def __call__(self, wsgienv, start_response): |
|
17 | def __call__(self, wsgienv, start_response): | |
18 | return _wsgirequest(self.destmaker(), wsgienv, start_response) |
|
18 | return _wsgirequest(self.destmaker(), wsgienv, start_response) | |
19 |
|
19 | |||
20 | class _wsgioutputfile(object): |
|
|||
21 | def __init__(self, request): |
|
|||
22 | self.request = request |
|
|||
23 |
|
||||
24 | def write(self, data): |
|
|||
25 | self.request.write(data) |
|
|||
26 | def writelines(self, lines): |
|
|||
27 | for line in lines: |
|
|||
28 | self.write(line) |
|
|||
29 | def flush(self): |
|
|||
30 | return None |
|
|||
31 | def close(self): |
|
|||
32 | return None |
|
|||
33 |
|
||||
34 | class _wsgirequest(object): |
|
20 | class _wsgirequest(object): | |
35 | def __init__(self, destination, wsgienv, start_response): |
|
21 | def __init__(self, destination, wsgienv, start_response): | |
36 | version = wsgienv['wsgi.version'] |
|
22 | version = wsgienv['wsgi.version'] | |
37 | if (version < (1, 0)) or (version >= (2, 0)): |
|
23 | if (version < (1, 0)) or (version >= (2, 0)): | |
38 | raise RuntimeError("Unknown and unsupported WSGI version %d.%d" \ |
|
24 | raise RuntimeError("Unknown and unsupported WSGI version %d.%d" \ | |
39 | % version) |
|
25 | % version) | |
40 | self.inp = wsgienv['wsgi.input'] |
|
26 | self.inp = wsgienv['wsgi.input'] | |
41 | self.out = _wsgioutputfile(self) |
|
|||
42 | self.server_write = None |
|
27 | self.server_write = None | |
43 | self.err = wsgienv['wsgi.errors'] |
|
28 | self.err = wsgienv['wsgi.errors'] | |
44 | self.threaded = wsgienv['wsgi.multithread'] |
|
29 | self.threaded = wsgienv['wsgi.multithread'] | |
45 | self.multiprocess = wsgienv['wsgi.multiprocess'] |
|
30 | self.multiprocess = wsgienv['wsgi.multiprocess'] | |
46 | self.run_once = wsgienv['wsgi.run_once'] |
|
31 | self.run_once = wsgienv['wsgi.run_once'] | |
47 | self.env = wsgienv |
|
32 | self.env = wsgienv | |
48 | self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) |
|
33 | self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) | |
49 | self.start_response = start_response |
|
34 | self.start_response = start_response | |
50 | self.headers = [] |
|
35 | self.headers = [] | |
51 | destination.run_wsgi(self) |
|
36 | destination.run_wsgi(self) | |
52 |
|
37 | |||
|
38 | out = property(lambda self: self) | |||
|
39 | ||||
53 | def __iter__(self): |
|
40 | def __iter__(self): | |
54 | return iter([]) |
|
41 | return iter([]) | |
55 |
|
42 | |||
56 | def read(self, count=-1): |
|
43 | def read(self, count=-1): | |
57 | return self.inp.read(count) |
|
44 | return self.inp.read(count) | |
58 |
|
45 | |||
59 | def write(self, *things): |
|
46 | def write(self, *things): | |
60 | for thing in things: |
|
47 | for thing in things: | |
61 | if hasattr(thing, "__iter__"): |
|
48 | if hasattr(thing, "__iter__"): | |
62 | for part in thing: |
|
49 | for part in thing: | |
63 | self.write(part) |
|
50 | self.write(part) | |
64 | else: |
|
51 | else: | |
65 | thing = str(thing) |
|
52 | thing = str(thing) | |
66 | if self.server_write is None: |
|
53 | if self.server_write is None: | |
67 | if not self.headers: |
|
54 | if not self.headers: | |
68 | raise RuntimeError("request.write called before headers sent (%s)." % thing) |
|
55 | raise RuntimeError("request.write called before headers sent (%s)." % thing) | |
69 | self.server_write = self.start_response('200 Script output follows', |
|
56 | self.server_write = self.start_response('200 Script output follows', | |
70 | self.headers) |
|
57 | self.headers) | |
71 | self.start_response = None |
|
58 | self.start_response = None | |
72 | self.headers = None |
|
59 | self.headers = None | |
73 | try: |
|
60 | try: | |
74 | self.server_write(thing) |
|
61 | self.server_write(thing) | |
75 | except socket.error, inst: |
|
62 | except socket.error, inst: | |
76 | if inst[0] != errno.ECONNRESET: |
|
63 | if inst[0] != errno.ECONNRESET: | |
77 | raise |
|
64 | raise | |
78 |
|
65 | |||
|
66 | def writelines(self, lines): | |||
|
67 | for line in lines: | |||
|
68 | self.write(line) | |||
|
69 | ||||
|
70 | def flush(self): | |||
|
71 | return None | |||
|
72 | ||||
|
73 | def close(self): | |||
|
74 | return None | |||
|
75 | ||||
79 | def header(self, headers=[('Content-type','text/html')]): |
|
76 | def header(self, headers=[('Content-type','text/html')]): | |
80 | self.headers.extend(headers) |
|
77 | self.headers.extend(headers) | |
81 |
|
78 | |||
82 | def httphdr(self, type, filename=None, length=0, headers={}): |
|
79 | def httphdr(self, type, filename=None, length=0, headers={}): | |
83 | headers = headers.items() |
|
80 | headers = headers.items() | |
84 | headers.append(('Content-type', type)) |
|
81 | headers.append(('Content-type', type)) | |
85 | if filename: |
|
82 | if filename: | |
86 | headers.append(('Content-disposition', 'attachment; filename=%s' % |
|
83 | headers.append(('Content-disposition', 'attachment; filename=%s' % | |
87 | filename)) |
|
84 | filename)) | |
88 | if length: |
|
85 | if length: | |
89 | headers.append(('Content-length', str(length))) |
|
86 | headers.append(('Content-length', str(length))) | |
90 | self.header(headers) |
|
87 | self.header(headers) |
General Comments 0
You need to be logged in to leave comments.
Login now