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)