Mercurial > hg > gitweb
comparison mercurial/hgweb/request.py @ 2434:a2df85adface
http server: support persistent connections.
only "hg serve" affected yet. http server running cgi script will not
use persistent connections. support for fastcgi will help that.
clients that support keepalive can use one tcp connection for all
commands during clone and pull. this makes latency of binary search
during pull much lower over wan.
if server does not know content-length, it will force connection to
close at end. right fix is to use chunked transfer-encoding but this is
easier and does not hurt performance. only command that is affected is
"changegroup" which is always last command during a pull.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Thu, 15 Jun 2006 12:55:58 -0700 |
parents | a8f1049d1d2d |
children | 09b1c9ef317c |
comparison
equal
deleted
inserted
replaced
2433:d09da6fc1061 | 2434:a2df85adface |
---|---|
14 def __init__(self, inp=None, out=None, env=None): | 14 def __init__(self, inp=None, out=None, env=None): |
15 self.inp = inp or sys.stdin | 15 self.inp = inp or sys.stdin |
16 self.out = out or sys.stdout | 16 self.out = out or sys.stdout |
17 self.env = env or os.environ | 17 self.env = env or os.environ |
18 self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) | 18 self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) |
19 self.will_close = True | |
19 | 20 |
20 def write(self, *things): | 21 def write(self, *things): |
21 for thing in things: | 22 for thing in things: |
22 if hasattr(thing, "__iter__"): | 23 if hasattr(thing, "__iter__"): |
23 for part in thing: | 24 for part in thing: |
27 self.out.write(str(thing)) | 28 self.out.write(str(thing)) |
28 except socket.error, inst: | 29 except socket.error, inst: |
29 if inst[0] != errno.ECONNRESET: | 30 if inst[0] != errno.ECONNRESET: |
30 raise | 31 raise |
31 | 32 |
33 def done(self): | |
34 if self.will_close: | |
35 self.inp.close() | |
36 self.out.close() | |
37 else: | |
38 self.out.flush() | |
39 | |
32 def header(self, headers=[('Content-type','text/html')]): | 40 def header(self, headers=[('Content-type','text/html')]): |
33 for header in headers: | 41 for header in headers: |
34 self.out.write("%s: %s\r\n" % header) | 42 self.out.write("%s: %s\r\n" % header) |
35 self.out.write("\r\n") | 43 self.out.write("\r\n") |
36 | 44 |
37 def httphdr(self, type, file="", size=0): | 45 def httphdr(self, type, filename=None, length=0): |
38 | 46 |
39 headers = [('Content-type', type)] | 47 headers = [('Content-type', type)] |
40 if file: | 48 if filename: |
41 headers.append(('Content-disposition', 'attachment; filename=%s' % file)) | 49 headers.append(('Content-disposition', 'attachment; filename=%s' % |
42 if size > 0: | 50 filename)) |
43 headers.append(('Content-length', str(size))) | 51 # we do not yet support http 1.1 chunked transfer, so we have |
52 # to force connection to close if content-length not known | |
53 if length: | |
54 headers.append(('Content-length', str(length))) | |
55 self.will_close = False | |
56 else: | |
57 headers.append(('Connection', 'close')) | |
58 self.will_close = True | |
44 self.header(headers) | 59 self.header(headers) |