##// END OF EJS Templates
hgweb: log error before attempting I/O...
Gregory Szorc -
r41500:5492dc20 default draft
parent child Browse files
Show More
@@ -0,0 +1,29 b''
1 #!/usr/bin/env python
2
3 # Filters traceback lines from stdin.
4
5 from __future__ import absolute_import, print_function
6
7 import sys
8
9 state = 'none'
10
11 for line in sys.stdin:
12 if state == 'none':
13 if line.startswith('Traceback '):
14 state = 'tb'
15
16 elif state == 'tb':
17 if line.startswith(' File '):
18 state = 'file'
19 continue
20
21 elif not line.startswith(' '):
22 state = 'none'
23
24 elif state == 'file':
25 # Ignore lines after " File "
26 state = 'tb'
27 continue
28
29 print(line, end='')
@@ -1,380 +1,383 b''
1 1 # hgweb/server.py - The standalone hg web server.
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from __future__ import absolute_import
10 10
11 11 import errno
12 12 import os
13 13 import socket
14 14 import sys
15 15 import traceback
16 16 import wsgiref.validate
17 17
18 18 from ..i18n import _
19 19
20 20 from .. import (
21 21 encoding,
22 22 error,
23 23 pycompat,
24 24 util,
25 25 )
26 26
27 27 httpservermod = util.httpserver
28 28 socketserver = util.socketserver
29 29 urlerr = util.urlerr
30 30 urlreq = util.urlreq
31 31
32 32 from . import (
33 33 common,
34 34 )
35 35
36 36 def _splitURI(uri):
37 37 """Return path and query that has been split from uri
38 38
39 39 Just like CGI environment, the path is unquoted, the query is
40 40 not.
41 41 """
42 42 if r'?' in uri:
43 43 path, query = uri.split(r'?', 1)
44 44 else:
45 45 path, query = uri, r''
46 46 return urlreq.unquote(path), query
47 47
48 48 class _error_logger(object):
49 49 def __init__(self, handler):
50 50 self.handler = handler
51 51 def flush(self):
52 52 pass
53 53 def write(self, str):
54 54 self.writelines(str.split('\n'))
55 55 def writelines(self, seq):
56 56 for msg in seq:
57 57 self.handler.log_error(r"HG error: %s", encoding.strfromlocal(msg))
58 58
59 59 class _httprequesthandler(httpservermod.basehttprequesthandler):
60 60
61 61 url_scheme = 'http'
62 62
63 63 @staticmethod
64 64 def preparehttpserver(httpserver, ui):
65 65 """Prepare .socket of new HTTPServer instance"""
66 66
67 67 def __init__(self, *args, **kargs):
68 68 self.protocol_version = r'HTTP/1.1'
69 69 httpservermod.basehttprequesthandler.__init__(self, *args, **kargs)
70 70
71 71 def _log_any(self, fp, format, *args):
72 72 fp.write(pycompat.sysbytes(
73 73 r"%s - - [%s] %s" % (self.client_address[0],
74 74 self.log_date_time_string(),
75 75 format % args)) + '\n')
76 76 fp.flush()
77 77
78 78 def log_error(self, format, *args):
79 79 self._log_any(self.server.errorlog, format, *args)
80 80
81 81 def log_message(self, format, *args):
82 82 self._log_any(self.server.accesslog, format, *args)
83 83
84 84 def log_request(self, code=r'-', size=r'-'):
85 85 xheaders = []
86 86 if util.safehasattr(self, 'headers'):
87 87 xheaders = [h for h in self.headers.items()
88 88 if h[0].startswith(r'x-')]
89 89 self.log_message(r'"%s" %s %s%s',
90 90 self.requestline, str(code), str(size),
91 91 r''.join([r' %s:%s' % h for h in sorted(xheaders)]))
92 92
93 93 def do_write(self):
94 94 try:
95 95 self.do_hgweb()
96 96 except socket.error as inst:
97 97 if inst.errno != errno.EPIPE:
98 98 raise
99 99
100 100 def do_POST(self):
101 101 try:
102 102 self.do_write()
103 103 except Exception:
104 self._start_response(r"500 Internal Server Error", [])
105 self._write(b"Internal Server Error")
106 self._done()
104 # I/O below could raise another exception. So log the original
105 # exception first to ensure it is recorded.
107 106 tb = r"".join(traceback.format_exception(*sys.exc_info()))
108 107 # We need a native-string newline to poke in the log
109 108 # message, because we won't get a newline when using an
110 109 # r-string. This is the easy way out.
111 110 newline = chr(10)
112 111 self.log_error(r"Exception happened during processing "
113 112 r"request '%s':%s%s", self.path, newline, tb)
114 113
114 self._start_response(r"500 Internal Server Error", [])
115 self._write(b"Internal Server Error")
116 self._done()
117
115 118 def do_PUT(self):
116 119 self.do_POST()
117 120
118 121 def do_GET(self):
119 122 self.do_POST()
120 123
121 124 def do_hgweb(self):
122 125 self.sent_headers = False
123 126 path, query = _splitURI(self.path)
124 127
125 128 # Ensure the slicing of path below is valid
126 129 if (path != self.server.prefix
127 130 and not path.startswith(self.server.prefix + b'/')):
128 131 self._start_response(pycompat.strurl(common.statusmessage(404)),
129 132 [])
130 133 if self.command == 'POST':
131 134 # Paranoia: tell the client we're going to close the
132 135 # socket so they don't try and reuse a socket that
133 136 # might have a POST body waiting to confuse us. We do
134 137 # this by directly munging self.saved_headers because
135 138 # self._start_response ignores Connection headers.
136 139 self.saved_headers = [(r'Connection', r'Close')]
137 140 self._write(b"Not Found")
138 141 self._done()
139 142 return
140 143
141 144 env = {}
142 145 env[r'GATEWAY_INTERFACE'] = r'CGI/1.1'
143 146 env[r'REQUEST_METHOD'] = self.command
144 147 env[r'SERVER_NAME'] = self.server.server_name
145 148 env[r'SERVER_PORT'] = str(self.server.server_port)
146 149 env[r'REQUEST_URI'] = self.path
147 150 env[r'SCRIPT_NAME'] = pycompat.sysstr(self.server.prefix)
148 151 env[r'PATH_INFO'] = pycompat.sysstr(path[len(self.server.prefix):])
149 152 env[r'REMOTE_HOST'] = self.client_address[0]
150 153 env[r'REMOTE_ADDR'] = self.client_address[0]
151 154 env[r'QUERY_STRING'] = query or r''
152 155
153 156 if pycompat.ispy3:
154 157 if self.headers.get_content_type() is None:
155 158 env[r'CONTENT_TYPE'] = self.headers.get_default_type()
156 159 else:
157 160 env[r'CONTENT_TYPE'] = self.headers.get_content_type()
158 161 length = self.headers.get(r'content-length')
159 162 else:
160 163 if self.headers.typeheader is None:
161 164 env[r'CONTENT_TYPE'] = self.headers.type
162 165 else:
163 166 env[r'CONTENT_TYPE'] = self.headers.typeheader
164 167 length = self.headers.getheader(r'content-length')
165 168 if length:
166 169 env[r'CONTENT_LENGTH'] = length
167 170 for header in [h for h in self.headers.keys()
168 171 if h.lower() not in (r'content-type', r'content-length')]:
169 172 hkey = r'HTTP_' + header.replace(r'-', r'_').upper()
170 173 hval = self.headers.get(header)
171 174 hval = hval.replace(r'\n', r'').strip()
172 175 if hval:
173 176 env[hkey] = hval
174 177 env[r'SERVER_PROTOCOL'] = self.request_version
175 178 env[r'wsgi.version'] = (1, 0)
176 179 env[r'wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme)
177 180 if env.get(r'HTTP_EXPECT', '').lower() == '100-continue':
178 181 self.rfile = common.continuereader(self.rfile, self.wfile.write)
179 182
180 183 env[r'wsgi.input'] = self.rfile
181 184 env[r'wsgi.errors'] = _error_logger(self)
182 185 env[r'wsgi.multithread'] = isinstance(self.server,
183 186 socketserver.ThreadingMixIn)
184 187 if util.safehasattr(socketserver, 'ForkingMixIn'):
185 188 env[r'wsgi.multiprocess'] = isinstance(self.server,
186 189 socketserver.ForkingMixIn)
187 190 else:
188 191 env[r'wsgi.multiprocess'] = False
189 192
190 193 env[r'wsgi.run_once'] = 0
191 194
192 195 wsgiref.validate.check_environ(env)
193 196
194 197 self.saved_status = None
195 198 self.saved_headers = []
196 199 self.length = None
197 200 self._chunked = None
198 201 for chunk in self.server.application(env, self._start_response):
199 202 self._write(chunk)
200 203 if not self.sent_headers:
201 204 self.send_headers()
202 205 self._done()
203 206
204 207 def send_headers(self):
205 208 if not self.saved_status:
206 209 raise AssertionError("Sending headers before "
207 210 "start_response() called")
208 211 saved_status = self.saved_status.split(None, 1)
209 212 saved_status[0] = int(saved_status[0])
210 213 self.send_response(*saved_status)
211 214 self.length = None
212 215 self._chunked = False
213 216 for h in self.saved_headers:
214 217 self.send_header(*h)
215 218 if h[0].lower() == r'content-length':
216 219 self.length = int(h[1])
217 220 if (self.length is None and
218 221 saved_status[0] != common.HTTP_NOT_MODIFIED):
219 222 self._chunked = (not self.close_connection and
220 223 self.request_version == r'HTTP/1.1')
221 224 if self._chunked:
222 225 self.send_header(r'Transfer-Encoding', r'chunked')
223 226 else:
224 227 self.send_header(r'Connection', r'close')
225 228 self.end_headers()
226 229 self.sent_headers = True
227 230
228 231 def _start_response(self, http_status, headers, exc_info=None):
229 232 assert isinstance(http_status, str)
230 233 code, msg = http_status.split(None, 1)
231 234 code = int(code)
232 235 self.saved_status = http_status
233 236 bad_headers = (r'connection', r'transfer-encoding')
234 237 self.saved_headers = [h for h in headers
235 238 if h[0].lower() not in bad_headers]
236 239 return self._write
237 240
238 241 def _write(self, data):
239 242 if not self.saved_status:
240 243 raise AssertionError("data written before start_response() called")
241 244 elif not self.sent_headers:
242 245 self.send_headers()
243 246 if self.length is not None:
244 247 if len(data) > self.length:
245 248 raise AssertionError("Content-length header sent, but more "
246 249 "bytes than specified are being written.")
247 250 self.length = self.length - len(data)
248 251 elif self._chunked and data:
249 252 data = '%x\r\n%s\r\n' % (len(data), data)
250 253 self.wfile.write(data)
251 254 self.wfile.flush()
252 255
253 256 def _done(self):
254 257 if self._chunked:
255 258 self.wfile.write('0\r\n\r\n')
256 259 self.wfile.flush()
257 260
258 261 def version_string(self):
259 262 if self.server.serverheader:
260 263 return encoding.strfromlocal(self.server.serverheader)
261 264 return httpservermod.basehttprequesthandler.version_string(self)
262 265
263 266 class _httprequesthandlerssl(_httprequesthandler):
264 267 """HTTPS handler based on Python's ssl module"""
265 268
266 269 url_scheme = 'https'
267 270
268 271 @staticmethod
269 272 def preparehttpserver(httpserver, ui):
270 273 try:
271 274 from .. import sslutil
272 275 sslutil.modernssl
273 276 except ImportError:
274 277 raise error.Abort(_("SSL support is unavailable"))
275 278
276 279 certfile = ui.config('web', 'certificate')
277 280
278 281 # These config options are currently only meant for testing. Use
279 282 # at your own risk.
280 283 cafile = ui.config('devel', 'servercafile')
281 284 reqcert = ui.configbool('devel', 'serverrequirecert')
282 285
283 286 httpserver.socket = sslutil.wrapserversocket(httpserver.socket,
284 287 ui,
285 288 certfile=certfile,
286 289 cafile=cafile,
287 290 requireclientcert=reqcert)
288 291
289 292 def setup(self):
290 293 self.connection = self.request
291 294 self.rfile = self.request.makefile(r"rb", self.rbufsize)
292 295 self.wfile = self.request.makefile(r"wb", self.wbufsize)
293 296
294 297 try:
295 298 import threading
296 299 threading.activeCount() # silence pyflakes and bypass demandimport
297 300 _mixin = socketserver.ThreadingMixIn
298 301 except ImportError:
299 302 if util.safehasattr(os, "fork"):
300 303 _mixin = socketserver.ForkingMixIn
301 304 else:
302 305 class _mixin(object):
303 306 pass
304 307
305 308 def openlog(opt, default):
306 309 if opt and opt != '-':
307 310 return open(opt, 'ab')
308 311 return default
309 312
310 313 class MercurialHTTPServer(_mixin, httpservermod.httpserver, object):
311 314
312 315 # SO_REUSEADDR has broken semantics on windows
313 316 if pycompat.iswindows:
314 317 allow_reuse_address = 0
315 318
316 319 def __init__(self, ui, app, addr, handler, **kwargs):
317 320 httpservermod.httpserver.__init__(self, addr, handler, **kwargs)
318 321 self.daemon_threads = True
319 322 self.application = app
320 323
321 324 handler.preparehttpserver(self, ui)
322 325
323 326 prefix = ui.config('web', 'prefix')
324 327 if prefix:
325 328 prefix = '/' + prefix.strip('/')
326 329 self.prefix = prefix
327 330
328 331 alog = openlog(ui.config('web', 'accesslog'), ui.fout)
329 332 elog = openlog(ui.config('web', 'errorlog'), ui.ferr)
330 333 self.accesslog = alog
331 334 self.errorlog = elog
332 335
333 336 self.addr, self.port = self.socket.getsockname()[0:2]
334 337 self.fqaddr = socket.getfqdn(addr[0])
335 338
336 339 self.serverheader = ui.config('web', 'server-header')
337 340
338 341 class IPv6HTTPServer(MercurialHTTPServer):
339 342 address_family = getattr(socket, 'AF_INET6', None)
340 343 def __init__(self, *args, **kwargs):
341 344 if self.address_family is None:
342 345 raise error.RepoError(_('IPv6 is not available on this system'))
343 346 super(IPv6HTTPServer, self).__init__(*args, **kwargs)
344 347
345 348 def create_server(ui, app):
346 349
347 350 if ui.config('web', 'certificate'):
348 351 handler = _httprequesthandlerssl
349 352 else:
350 353 handler = _httprequesthandler
351 354
352 355 if ui.configbool('web', 'ipv6'):
353 356 cls = IPv6HTTPServer
354 357 else:
355 358 cls = MercurialHTTPServer
356 359
357 360 # ugly hack due to python issue5853 (for threaded use)
358 361 try:
359 362 import mimetypes
360 363 mimetypes.init()
361 364 except UnicodeDecodeError:
362 365 # Python 2.x's mimetypes module attempts to decode strings
363 366 # from Windows' ANSI APIs as ascii (fail), then re-encode them
364 367 # as ascii (clown fail), because the default Python Unicode
365 368 # codec is hardcoded as ascii.
366 369
367 370 sys.argv # unwrap demand-loader so that reload() works
368 371 reload(sys) # resurrect sys.setdefaultencoding()
369 372 oldenc = sys.getdefaultencoding()
370 373 sys.setdefaultencoding("latin1") # or any full 8-bit encoding
371 374 mimetypes.init()
372 375 sys.setdefaultencoding(oldenc)
373 376
374 377 address = ui.config('web', 'address')
375 378 port = util.getport(ui.config('web', 'port'))
376 379 try:
377 380 return cls(ui, app, (address, port), handler)
378 381 except socket.error as inst:
379 382 raise error.Abort(_("cannot start server at '%s:%d': %s")
380 383 % (address, port, encoding.strtolocal(inst.args[1])))
@@ -1,963 +1,979 b''
1 1 #require serve
2 2
3 3 Some tests for hgweb. Tests static files, plain files and different 404's.
4 4
5 5 $ hg init test
6 6 $ cd test
7 7 $ mkdir da
8 8 $ echo foo > da/foo
9 9 $ echo foo > foo
10 10 $ hg ci -Ambase
11 11 adding da/foo
12 12 adding foo
13 13 $ hg bookmark -r0 '@'
14 14 $ hg bookmark -r0 'a b c'
15 15 $ hg bookmark -r0 'd/e/f'
16 16 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
17 17 $ cat hg.pid >> $DAEMON_PIDS
18 18
19 19 manifest
20 20
21 21 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=raw')
22 22 200 Script output follows
23 23
24 24
25 25 drwxr-xr-x da
26 26 -rw-r--r-- 4 foo
27 27
28 28
29 29 $ (get-with-headers.py localhost:$HGPORT 'file/tip/da?style=raw')
30 30 200 Script output follows
31 31
32 32
33 33 -rw-r--r-- 4 foo
34 34
35 35
36 36
37 37 plain file
38 38
39 39 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?style=raw'
40 40 200 Script output follows
41 41
42 42 foo
43 43
44 44 should give a 404 - static file that does not exist
45 45
46 46 $ get-with-headers.py localhost:$HGPORT 'static/bogus'
47 47 404 Not Found
48 48
49 49 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
50 50 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
51 51 <head>
52 52 <link rel="icon" href="/static/hgicon.png" type="image/png" />
53 53 <meta name="robots" content="index, nofollow" />
54 54 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
55 55 <script type="text/javascript" src="/static/mercurial.js"></script>
56 56
57 57 <title>test: error</title>
58 58 </head>
59 59 <body>
60 60
61 61 <div class="container">
62 62 <div class="menu">
63 63 <div class="logo">
64 64 <a href="https://mercurial-scm.org/">
65 65 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
66 66 </div>
67 67 <ul>
68 68 <li><a href="/shortlog">log</a></li>
69 69 <li><a href="/graph">graph</a></li>
70 70 <li><a href="/tags">tags</a></li>
71 71 <li><a href="/bookmarks">bookmarks</a></li>
72 72 <li><a href="/branches">branches</a></li>
73 73 </ul>
74 74 <ul>
75 75 <li><a href="/help">help</a></li>
76 76 </ul>
77 77 </div>
78 78
79 79 <div class="main">
80 80
81 81 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
82 82 <h3>error</h3>
83 83
84 84
85 85 <form class="search" action="/log">
86 86
87 87 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
88 88 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
89 89 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
90 90 </form>
91 91
92 92 <div class="description">
93 93 <p>
94 94 An error occurred while processing your request:
95 95 </p>
96 96 <p>
97 97 Not Found
98 98 </p>
99 99 </div>
100 100 </div>
101 101 </div>
102 102
103 103
104 104
105 105 </body>
106 106 </html>
107 107
108 108 [1]
109 109
110 110 should give a 404 - bad revision
111 111
112 112 $ get-with-headers.py localhost:$HGPORT 'file/spam/foo?style=raw'
113 113 404 Not Found
114 114
115 115
116 116 error: revision not found: spam
117 117 [1]
118 118
119 119 should give a 400 - bad command
120 120
121 121 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?cmd=spam&style=raw'
122 122 400* (glob)
123 123
124 124
125 125 error: no such method: spam
126 126 [1]
127 127
128 128 $ get-with-headers.py --headeronly localhost:$HGPORT '?cmd=spam'
129 129 400 no such method: spam
130 130 [1]
131 131
132 132 should give a 400 - bad command as a part of url path (issue4071)
133 133
134 134 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam'
135 135 400 no such method: spam
136 136 [1]
137 137
138 138 $ get-with-headers.py --headeronly localhost:$HGPORT 'raw-spam'
139 139 400 no such method: spam
140 140 [1]
141 141
142 142 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam/tip/foo'
143 143 400 no such method: spam
144 144 [1]
145 145
146 146 should give a 404 - file does not exist
147 147
148 148 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork?style=raw'
149 149 404 Not Found
150 150
151 151
152 152 error: bork@2ef0ac749a14: not found in manifest
153 153 [1]
154 154 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork'
155 155 404 Not Found
156 156
157 157 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
158 158 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
159 159 <head>
160 160 <link rel="icon" href="/static/hgicon.png" type="image/png" />
161 161 <meta name="robots" content="index, nofollow" />
162 162 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
163 163 <script type="text/javascript" src="/static/mercurial.js"></script>
164 164
165 165 <title>test: error</title>
166 166 </head>
167 167 <body>
168 168
169 169 <div class="container">
170 170 <div class="menu">
171 171 <div class="logo">
172 172 <a href="https://mercurial-scm.org/">
173 173 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
174 174 </div>
175 175 <ul>
176 176 <li><a href="/shortlog">log</a></li>
177 177 <li><a href="/graph">graph</a></li>
178 178 <li><a href="/tags">tags</a></li>
179 179 <li><a href="/bookmarks">bookmarks</a></li>
180 180 <li><a href="/branches">branches</a></li>
181 181 </ul>
182 182 <ul>
183 183 <li><a href="/help">help</a></li>
184 184 </ul>
185 185 </div>
186 186
187 187 <div class="main">
188 188
189 189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
190 190 <h3>error</h3>
191 191
192 192
193 193 <form class="search" action="/log">
194 194
195 195 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
196 196 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
197 197 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
198 198 </form>
199 199
200 200 <div class="description">
201 201 <p>
202 202 An error occurred while processing your request:
203 203 </p>
204 204 <p>
205 205 bork@2ef0ac749a14: not found in manifest
206 206 </p>
207 207 </div>
208 208 </div>
209 209 </div>
210 210
211 211
212 212
213 213 </body>
214 214 </html>
215 215
216 216 [1]
217 217 $ get-with-headers.py localhost:$HGPORT 'diff/tip/bork?style=raw'
218 218 404 Not Found
219 219
220 220
221 221 error: bork@2ef0ac749a14: not found in manifest
222 222 [1]
223 223
224 224 try bad style
225 225
226 226 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=foobar')
227 227 200 Script output follows
228 228
229 229 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
230 230 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
231 231 <head>
232 232 <link rel="icon" href="/static/hgicon.png" type="image/png" />
233 233 <meta name="robots" content="index, nofollow" />
234 234 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
235 235 <script type="text/javascript" src="/static/mercurial.js"></script>
236 236
237 237 <title>test: 2ef0ac749a14 /</title>
238 238 </head>
239 239 <body>
240 240
241 241 <div class="container">
242 242 <div class="menu">
243 243 <div class="logo">
244 244 <a href="https://mercurial-scm.org/">
245 245 <img src="/static/hglogo.png" alt="mercurial" /></a>
246 246 </div>
247 247 <ul>
248 248 <li><a href="/shortlog/tip">log</a></li>
249 249 <li><a href="/graph/tip">graph</a></li>
250 250 <li><a href="/tags">tags</a></li>
251 251 <li><a href="/bookmarks">bookmarks</a></li>
252 252 <li><a href="/branches">branches</a></li>
253 253 </ul>
254 254 <ul>
255 255 <li><a href="/rev/tip">changeset</a></li>
256 256 <li class="active">browse</li>
257 257 </ul>
258 258 <ul>
259 259
260 260 </ul>
261 261 <ul>
262 262 <li><a href="/help">help</a></li>
263 263 </ul>
264 264 </div>
265 265
266 266 <div class="main">
267 267 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
268 268 <h3>
269 269 directory / @ 0:<a href="/rev/2ef0ac749a14">2ef0ac749a14</a>
270 270 <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> <span class="tag">@</span> <span class="tag">a b c</span> <span class="tag">d/e/f</span>
271 271 </h3>
272 272
273 273
274 274 <form class="search" action="/log">
275 275
276 276 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
277 277 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
278 278 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
279 279 </form>
280 280
281 281 <table class="bigtable">
282 282 <thead>
283 283 <tr>
284 284 <th class="name">name</th>
285 285 <th class="size">size</th>
286 286 <th class="permissions">permissions</th>
287 287 </tr>
288 288 </thead>
289 289 <tbody class="stripes2">
290 290
291 291
292 292 <tr class="fileline">
293 293 <td class="name">
294 294 <a href="/file/tip/da">
295 295 <img src="/static/coal-folder.png" alt="dir."/> da/
296 296 </a>
297 297 <a href="/file/tip/da/">
298 298
299 299 </a>
300 300 </td>
301 301 <td class="size"></td>
302 302 <td class="permissions">drwxr-xr-x</td>
303 303 </tr>
304 304
305 305 <tr class="fileline">
306 306 <td class="filename">
307 307 <a href="/file/tip/foo">
308 308 <img src="/static/coal-file.png" alt="file"/> foo
309 309 </a>
310 310 </td>
311 311 <td class="size">4</td>
312 312 <td class="permissions">-rw-r--r--</td>
313 313 </tr>
314 314 </tbody>
315 315 </table>
316 316 </div>
317 317 </div>
318 318
319 319
320 320 </body>
321 321 </html>
322 322
323 323
324 324 stop and restart
325 325
326 326 $ killdaemons.py
327 327 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log
328 328 $ cat hg.pid >> $DAEMON_PIDS
329 329
330 330 Test the access/error files are opened in append mode
331 331
332 332 $ "$PYTHON" -c "from __future__ import print_function; print(len(open('access.log', 'rb').readlines()), 'log lines written')"
333 333 14 log lines written
334 334
335 335 static file
336 336
337 337 $ get-with-headers.py --twice localhost:$HGPORT 'static/style-gitweb.css' - date etag server
338 338 200 Script output follows
339 339 content-length: 9074
340 340 content-type: text/css
341 341
342 342 body { font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px; margin:10px; background: white; color: black; }
343 343 a { color:#0000cc; }
344 344 a:hover, a:visited, a:active { color:#880000; }
345 345 div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
346 346 div.page_header a:visited { color:#0000cc; }
347 347 div.page_header a:hover { color:#880000; }
348 348 div.page_nav {
349 349 padding:8px;
350 350 display: flex;
351 351 justify-content: space-between;
352 352 align-items: center;
353 353 }
354 354 div.page_nav a:visited { color:#0000cc; }
355 355 div.extra_nav {
356 356 padding: 8px;
357 357 }
358 358 div.extra_nav a:visited {
359 359 color: #0000cc;
360 360 }
361 361 div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
362 362 div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
363 363 div.page_footer_text { float:left; color:#555555; font-style:italic; }
364 364 div.page_body { padding:8px; }
365 365 div.title, a.title {
366 366 display:block; padding:6px 8px;
367 367 font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
368 368 }
369 369 a.title:hover { background-color: #d9d8d1; }
370 370 div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
371 371 div.log_body { padding:8px 8px 8px 150px; }
372 372 .age { white-space:nowrap; }
373 373 a.title span.age { position:relative; float:left; width:142px; font-style:italic; }
374 374 div.log_link {
375 375 padding:0px 8px;
376 376 font-size:10px; font-family:sans-serif; font-style:normal;
377 377 position:relative; float:left; width:136px;
378 378 }
379 379 div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
380 380 a.list { text-decoration:none; color:#000000; }
381 381 a.list:hover { text-decoration:underline; color:#880000; }
382 382 table { padding:8px 4px; }
383 383 th { padding:2px 5px; font-size:12px; text-align:left; }
384 384 .parity0 { background-color:#ffffff; }
385 385 tr.dark, .parity1, pre.sourcelines.stripes > :nth-child(4n+4) { background-color:#f6f6f0; }
386 386 tr.light:hover, .parity0:hover, tr.dark:hover, .parity1:hover,
387 387 pre.sourcelines.stripes > :nth-child(4n+2):hover,
388 388 pre.sourcelines.stripes > :nth-child(4n+4):hover,
389 389 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
390 390 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color:#edece6; }
391 391 td { padding:2px 5px; font-size:12px; vertical-align:top; }
392 392 td.closed { background-color: #99f; }
393 393 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
394 394 td.indexlinks { white-space: nowrap; }
395 395 td.indexlinks a {
396 396 padding: 2px 5px; line-height: 10px;
397 397 border: 1px solid;
398 398 color: #ffffff; background-color: #7777bb;
399 399 border-color: #aaaadd #333366 #333366 #aaaadd;
400 400 font-weight: bold; text-align: center; text-decoration: none;
401 401 font-size: 10px;
402 402 }
403 403 td.indexlinks a:hover { background-color: #6666aa; }
404 404 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
405 405
406 406 .search {
407 407 margin-right: 8px;
408 408 }
409 409
410 410 div#hint {
411 411 position: absolute;
412 412 display: none;
413 413 width: 250px;
414 414 padding: 5px;
415 415 background: #ffc;
416 416 border: 1px solid yellow;
417 417 border-radius: 5px;
418 418 z-index: 15;
419 419 }
420 420
421 421 #searchform:hover div#hint { display: block; }
422 422
423 423 tr.thisrev a { color:#999999; text-decoration: none; }
424 424 tr.thisrev pre { color:#009900; }
425 425 td.annotate {
426 426 white-space: nowrap;
427 427 }
428 428 div.annotate-info {
429 429 z-index: 5;
430 430 display: none;
431 431 position: absolute;
432 432 background-color: #FFFFFF;
433 433 border: 1px solid #d9d8d1;
434 434 text-align: left;
435 435 color: #000000;
436 436 padding: 5px;
437 437 }
438 438 div.annotate-info a { color: #0000FF; text-decoration: underline; }
439 439 td.annotate:hover div.annotate-info { display: inline; }
440 440
441 441 #diffopts-form {
442 442 padding-left: 8px;
443 443 display: none;
444 444 }
445 445
446 446 .linenr { color:#999999; text-decoration:none }
447 447 div.rss_logo { float: right; white-space: nowrap; }
448 448 div.rss_logo a {
449 449 padding:3px 6px; line-height:10px;
450 450 border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
451 451 color:#ffffff; background-color:#ff6600;
452 452 font-weight:bold; font-family:sans-serif; font-size:10px;
453 453 text-align:center; text-decoration:none;
454 454 }
455 455 div.rss_logo a:hover { background-color:#ee5500; }
456 456 pre { margin: 0; }
457 457 span.logtags span {
458 458 padding: 0px 4px;
459 459 font-size: 10px;
460 460 font-weight: normal;
461 461 border: 1px solid;
462 462 background-color: #ffaaff;
463 463 border-color: #ffccff #ff00ee #ff00ee #ffccff;
464 464 }
465 465 span.logtags span.phasetag {
466 466 background-color: #dfafff;
467 467 border-color: #e2b8ff #ce48ff #ce48ff #e2b8ff;
468 468 }
469 469 span.logtags span.obsoletetag {
470 470 background-color: #dddddd;
471 471 border-color: #e4e4e4 #a3a3a3 #a3a3a3 #e4e4e4;
472 472 }
473 473 span.logtags span.instabilitytag {
474 474 background-color: #ffb1c0;
475 475 border-color: #ffbbc8 #ff4476 #ff4476 #ffbbc8;
476 476 }
477 477 span.logtags span.tagtag {
478 478 background-color: #ffffaa;
479 479 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
480 480 }
481 481 span.logtags span.branchtag {
482 482 background-color: #aaffaa;
483 483 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
484 484 }
485 485 span.logtags span.inbranchtag {
486 486 background-color: #d5dde6;
487 487 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
488 488 }
489 489 span.logtags span.bookmarktag {
490 490 background-color: #afdffa;
491 491 border-color: #ccecff #46ace6 #46ace6 #ccecff;
492 492 }
493 493 span.difflineplus { color:#008800; }
494 494 span.difflineminus { color:#cc0000; }
495 495 span.difflineat { color:#990099; }
496 496 div.diffblocks { counter-reset: lineno; }
497 497 div.diffblock { counter-increment: lineno; }
498 498 pre.sourcelines { position: relative; counter-reset: lineno; }
499 499 pre.sourcelines > span {
500 500 display: inline-block;
501 501 box-sizing: border-box;
502 502 width: 100%;
503 503 padding: 0 0 0 5em;
504 504 counter-increment: lineno;
505 505 vertical-align: top;
506 506 }
507 507 pre.sourcelines > span:before {
508 508 -moz-user-select: -moz-none;
509 509 -khtml-user-select: none;
510 510 -webkit-user-select: none;
511 511 -ms-user-select: none;
512 512 user-select: none;
513 513 display: inline-block;
514 514 margin-left: -6em;
515 515 width: 4em;
516 516 color: #999;
517 517 text-align: right;
518 518 content: counters(lineno,".");
519 519 float: left;
520 520 }
521 521 pre.sourcelines > a {
522 522 display: inline-block;
523 523 position: absolute;
524 524 left: 0px;
525 525 width: 4em;
526 526 height: 1em;
527 527 }
528 528 tr:target td,
529 529 pre.sourcelines > span:target,
530 530 pre.sourcelines.stripes > span:target {
531 531 background-color: #bfdfff;
532 532 }
533 533
534 534 .description {
535 535 font-family: monospace;
536 536 white-space: pre;
537 537 }
538 538
539 539 /* Followlines */
540 540 tbody.sourcelines > tr.followlines-selected,
541 541 pre.sourcelines > span.followlines-selected {
542 542 background-color: #99C7E9 !important;
543 543 }
544 544
545 545 div#followlines {
546 546 background-color: #FFF;
547 547 border: 1px solid #d9d8d1;
548 548 padding: 5px;
549 549 position: fixed;
550 550 }
551 551
552 552 div.followlines-cancel {
553 553 text-align: right;
554 554 }
555 555
556 556 div.followlines-cancel > button {
557 557 line-height: 80%;
558 558 padding: 0;
559 559 border: 0;
560 560 border-radius: 2px;
561 561 background-color: inherit;
562 562 font-weight: bold;
563 563 }
564 564
565 565 div.followlines-cancel > button:hover {
566 566 color: #FFFFFF;
567 567 background-color: #CF1F1F;
568 568 }
569 569
570 570 div.followlines-link {
571 571 margin: 2px;
572 572 margin-top: 4px;
573 573 font-family: sans-serif;
574 574 }
575 575
576 576 .btn-followlines {
577 577 position: absolute;
578 578 display: none;
579 579 cursor: pointer;
580 580 box-sizing: content-box;
581 581 font-size: 11px;
582 582 width: 13px;
583 583 height: 13px;
584 584 border-radius: 3px;
585 585 margin: 0px;
586 586 margin-top: -2px;
587 587 padding: 0px;
588 588 background-color: #E5FDE5;
589 589 border: 1px solid #9BC19B;
590 590 font-family: monospace;
591 591 text-align: center;
592 592 line-height: 5px;
593 593 }
594 594
595 595 span.followlines-select .btn-followlines {
596 596 margin-left: -1.6em;
597 597 }
598 598
599 599 .btn-followlines:hover {
600 600 transform: scale(1.1, 1.1);
601 601 }
602 602
603 603 .btn-followlines .followlines-plus {
604 604 color: green;
605 605 }
606 606
607 607 .btn-followlines .followlines-minus {
608 608 color: red;
609 609 }
610 610
611 611 .btn-followlines-end {
612 612 background-color: #ffdcdc;
613 613 }
614 614
615 615 .sourcelines tr:hover .btn-followlines,
616 616 .sourcelines span.followlines-select:hover > .btn-followlines {
617 617 display: inline;
618 618 }
619 619
620 620 .btn-followlines-hidden,
621 621 .sourcelines tr:hover .btn-followlines-hidden {
622 622 display: none;
623 623 }
624 624
625 625 /* Graph */
626 626 div#wrapper {
627 627 position: relative;
628 628 margin: 0;
629 629 padding: 0;
630 630 margin-top: 3px;
631 631 }
632 632
633 633 canvas {
634 634 position: absolute;
635 635 z-index: 5;
636 636 top: -0.9em;
637 637 margin: 0;
638 638 }
639 639
640 640 ul#graphnodes {
641 641 list-style: none inside none;
642 642 padding: 0;
643 643 margin: 0;
644 644 }
645 645
646 646 ul#graphnodes li {
647 647 position: relative;
648 648 height: 37px;
649 649 overflow: visible;
650 650 padding-top: 2px;
651 651 }
652 652
653 653 ul#graphnodes li .fg {
654 654 position: absolute;
655 655 z-index: 10;
656 656 }
657 657
658 658 ul#graphnodes li .info {
659 659 font-size: 100%;
660 660 font-style: italic;
661 661 }
662 662
663 663 /* Comparison */
664 664 .legend {
665 665 padding: 1.5% 0 1.5% 0;
666 666 }
667 667
668 668 .legendinfo {
669 669 border: 1px solid #d9d8d1;
670 670 font-size: 80%;
671 671 text-align: center;
672 672 padding: 0.5%;
673 673 }
674 674
675 675 .equal {
676 676 background-color: #ffffff;
677 677 }
678 678
679 679 .delete {
680 680 background-color: #faa;
681 681 color: #333;
682 682 }
683 683
684 684 .insert {
685 685 background-color: #ffa;
686 686 }
687 687
688 688 .replace {
689 689 background-color: #e8e8e8;
690 690 }
691 691
692 692 .comparison {
693 693 overflow-x: auto;
694 694 }
695 695
696 696 .header th {
697 697 text-align: center;
698 698 }
699 699
700 700 .block {
701 701 border-top: 1px solid #d9d8d1;
702 702 }
703 703
704 704 .scroll-loading {
705 705 -webkit-animation: change_color 1s linear 0s infinite alternate;
706 706 -moz-animation: change_color 1s linear 0s infinite alternate;
707 707 -o-animation: change_color 1s linear 0s infinite alternate;
708 708 animation: change_color 1s linear 0s infinite alternate;
709 709 }
710 710
711 711 @-webkit-keyframes change_color {
712 712 from { background-color: #A0CEFF; } to { }
713 713 }
714 714 @-moz-keyframes change_color {
715 715 from { background-color: #A0CEFF; } to { }
716 716 }
717 717 @-o-keyframes change_color {
718 718 from { background-color: #A0CEFF; } to { }
719 719 }
720 720 @keyframes change_color {
721 721 from { background-color: #A0CEFF; } to { }
722 722 }
723 723
724 724 .scroll-loading-error {
725 725 background-color: #FFCCCC !important;
726 726 }
727 727
728 728 #doc {
729 729 margin: 0 8px;
730 730 }
731 731 304 Not Modified
732 732
733 733
734 734 phase changes are refreshed (issue4061)
735 735
736 736 $ echo bar >> foo
737 737 $ hg ci -msecret --secret
738 738 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
739 739 200 Script output follows
740 740
741 741
742 742 # HG changelog
743 743 # Node ID 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
744 744
745 745 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
746 746 revision: 0
747 747 user: test
748 748 date: Thu, 01 Jan 1970 00:00:00 +0000
749 749 summary: base
750 750 branch: default
751 751 tag: tip
752 752 bookmark: @
753 753 bookmark: a b c
754 754 bookmark: d/e/f
755 755
756 756
757 757 $ hg phase --draft tip
758 758 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
759 759 200 Script output follows
760 760
761 761
762 762 # HG changelog
763 763 # Node ID a084749e708a9c4c0a5b652a2a446322ce290e04
764 764
765 765 changeset: a084749e708a9c4c0a5b652a2a446322ce290e04
766 766 revision: 1
767 767 user: test
768 768 date: Thu, 01 Jan 1970 00:00:00 +0000
769 769 summary: secret
770 770 branch: default
771 771 tag: tip
772 772
773 773 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
774 774 revision: 0
775 775 user: test
776 776 date: Thu, 01 Jan 1970 00:00:00 +0000
777 777 summary: base
778 778 bookmark: @
779 779 bookmark: a b c
780 780 bookmark: d/e/f
781 781
782 782
783 783
784 784 access bookmarks
785 785
786 786 $ get-with-headers.py localhost:$HGPORT 'rev/@?style=paper' | egrep '^200|changeset 0:'
787 787 200 Script output follows
788 788 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
789 789
790 790 $ get-with-headers.py localhost:$HGPORT 'rev/%40?style=paper' | egrep '^200|changeset 0:'
791 791 200 Script output follows
792 792 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
793 793
794 794 $ get-with-headers.py localhost:$HGPORT 'rev/a%20b%20c?style=paper' | egrep '^200|changeset 0:'
795 795 200 Script output follows
796 796 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
797 797
798 798 $ get-with-headers.py localhost:$HGPORT 'rev/d%252Fe%252Ff?style=paper' | egrep '^200|changeset 0:'
799 799 200 Script output follows
800 800 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
801 801
802 802 no '[up]' entry in file view when in root directory
803 803
804 804 $ get-with-headers.py localhost:$HGPORT 'file/tip?style=paper' | grep -F '[up]'
805 805 [1]
806 806 $ get-with-headers.py localhost:$HGPORT 'file/tip/da?style=paper' | grep -F '[up]'
807 807 <a href="/file/tip/?style=paper">[up]</a>
808 808 $ get-with-headers.py localhost:$HGPORT 'file/tip?style=coal' | grep -F '[up]'
809 809 [1]
810 810 $ get-with-headers.py localhost:$HGPORT 'file/tip/da?style=coal' | grep -F '[up]'
811 811 <a href="/file/tip/?style=coal">[up]</a>
812 812 $ get-with-headers.py localhost:$HGPORT 'file/tip?style=gitweb' | grep -F '[up]'
813 813 [1]
814 814 $ get-with-headers.py localhost:$HGPORT 'file/tip/da?style=gitweb' | grep -F '[up]'
815 815 <a href="/file/tip/?style=gitweb">[up]</a>
816 816 $ get-with-headers.py localhost:$HGPORT 'file/tip?style=monoblue' | grep -F '[up]'
817 817 [1]
818 818 $ get-with-headers.py localhost:$HGPORT 'file/tip/da?style=monoblue' | grep -F '[up]'
819 819 <a href="/file/tip/?style=monoblue">[up]</a>
820 820 $ get-with-headers.py localhost:$HGPORT 'file/tip?style=spartan' | grep -F '[up]'
821 821 [1]
822 822 $ get-with-headers.py localhost:$HGPORT 'file/tip/da?style=spartan' | grep -F '[up]'
823 823 <a href="/file/tip/?style=spartan">[up]</a>
824 824
825 825 no style can be loaded from directories other than the specified paths
826 826
827 827 $ mkdir -p x/templates/fallback
828 828 $ cat <<EOF > x/templates/fallback/map
829 829 > default = 'shortlog'
830 830 > shortlog = 'fall back to default\n'
831 831 > mimetype = 'text/plain'
832 832 > EOF
833 833 $ cat <<EOF > x/map
834 834 > default = 'shortlog'
835 835 > shortlog = 'access to outside of templates directory\n'
836 836 > mimetype = 'text/plain'
837 837 > EOF
838 838
839 839 $ killdaemons.py
840 840 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log \
841 841 > --config web.style=fallback --config web.templates=x/templates
842 842 $ cat hg.pid >> $DAEMON_PIDS
843 843
844 844 $ get-with-headers.py localhost:$HGPORT "?style=`pwd`/x"
845 845 200 Script output follows
846 846
847 847 fall back to default
848 848
849 849 $ get-with-headers.py localhost:$HGPORT '?style=..'
850 850 200 Script output follows
851 851
852 852 fall back to default
853 853
854 854 $ get-with-headers.py localhost:$HGPORT '?style=./..'
855 855 200 Script output follows
856 856
857 857 fall back to default
858 858
859 859 $ get-with-headers.py localhost:$HGPORT '?style=.../.../'
860 860 200 Script output follows
861 861
862 862 fall back to default
863 863
864 864 $ killdaemons.py
865 865
866 866 Test signal-safe-lock in web and non-web processes
867 867
868 868 $ cat <<'EOF' > disablesig.py
869 869 > import signal
870 870 > from mercurial import error, extensions
871 871 > def disabledsig(orig, signalnum, handler):
872 872 > if signalnum == signal.SIGTERM:
873 873 > raise error.Abort(b'SIGTERM cannot be replaced')
874 874 > try:
875 875 > return orig(signalnum, handler)
876 876 > except ValueError:
877 877 > raise error.Abort(b'signal.signal() called in thread?')
878 878 > def uisetup(ui):
879 879 > extensions.wrapfunction(signal, b'signal', disabledsig)
880 880 > EOF
881 881
882 882 by default, signal interrupt should be disabled while making a lock file
883 883
884 884 $ hg debuglock -s --config extensions.disablesig=disablesig.py
885 885 abort: SIGTERM cannot be replaced
886 886 [255]
887 887
888 888 but in hgweb, it isn't disabled since some WSGI servers complains about
889 889 unsupported signal.signal() calls (see issue5889)
890 890
891 891 $ hg serve --config extensions.disablesig=disablesig.py \
892 892 > --config web.allow-push='*' --config web.push_ssl=False \
893 893 > -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
894 894 $ cat hg.pid >> $DAEMON_PIDS
895 895
896 896 $ hg clone -q http://localhost:$HGPORT/ repo
897 897 $ hg bookmark -R repo foo
898 898
899 899 push would fail if signal.signal() were called
900 900
901 901 $ hg push -R repo -B foo
902 902 pushing to http://localhost:$HGPORT/
903 903 searching for changes
904 904 no changes found
905 905 exporting bookmark foo
906 906 [1]
907 907
908 908 $ rm -R repo
909 909 $ killdaemons.py
910 910
911 911 errors
912 912
913 $ cat errors.log
913 $ cat errors.log | "$PYTHON" $TESTDIR/filtertraceback.py
914 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=spam': (glob)
915 Traceback (most recent call last):
916 error: [Errno 104] $ECONNRESET$
917
918 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/spam': (glob)
919 Traceback (most recent call last):
920 error: [Errno 104] $ECONNRESET$
921
922 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/spam/tip/foo': (glob)
923 Traceback (most recent call last):
924 error: [Errno 104] $ECONNRESET$
925
926 $ rm -f errors.log
914 927
915 928 Uncaught exceptions result in a logged error and canned HTTP response
916 929
917 930 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
918 931 $ cat hg.pid >> $DAEMON_PIDS
919 932
920 933 $ get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type
921 934 500 Internal Server Error
922 935 transfer-encoding: chunked
923 936
924 937 Internal Server Error (no-eol)
925 938 [1]
926 939
927 940 $ killdaemons.py
928 $ head -1 errors.log
941 $ cat errors.log | "$PYTHON" $TESTDIR/filtertraceback.py
929 942 .* Exception happened during processing request '/raiseerror': (re)
943 Traceback (most recent call last):
944 AttributeError: I am an uncaught error!
945
930 946
931 947 Uncaught exception after partial content sent
932 948
933 949 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
934 950 $ cat hg.pid >> $DAEMON_PIDS
935 951 $ get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type
936 952 200 Script output follows
937 953 transfer-encoding: chunked
938 954 content-type: text/plain
939 955
940 956 partial content
941 957 Internal Server Error (no-eol)
942 958
943 959 $ killdaemons.py
944 960
945 961 HTTP 304 works with hgwebdir (issue5844)
946 962
947 963 $ cat > hgweb.conf << EOF
948 964 > [paths]
949 965 > /repo = $TESTTMP/test
950 966 > EOF
951 967
952 968 $ hg serve --web-conf hgweb.conf -p $HGPORT -d --pid-file hg.pid -E error.log
953 969 $ cat hg.pid >> $DAEMON_PIDS
954 970
955 971 $ get-with-headers.py --twice --headeronly localhost:$HGPORT 'repo/static/style.css' - date etag server
956 972 200 Script output follows
957 973 content-length: 2677
958 974 content-type: text/css
959 975 304 Not Modified
960 976
961 977 $ killdaemons.py
962 978
963 979 $ cd ..
@@ -1,936 +1,1008 b''
1 1 #require serve zstd
2 2
3 3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
4 4 version so behavior is deterministic.
5 5
6 6 $ cat > fakeversion.py << EOF
7 7 > from mercurial import util
8 8 > util.version = lambda: b'4.2'
9 9 > EOF
10 10
11 11 $ cat >> $HGRCPATH << EOF
12 12 > [extensions]
13 13 > fakeversion = `pwd`/fakeversion.py
14 14 > [format]
15 15 > sparse-revlog = no
16 16 > [devel]
17 17 > legacy.exchange = phases
18 18 > EOF
19 19
20 20 $ hg init server0
21 21 $ cd server0
22 22 $ touch foo
23 23 $ hg -q commit -A -m initial
24 24
25 25 Also disable compression because zstd is optional and causes output to vary
26 26 and because debugging partial responses is hard when compression is involved
27 27
28 28 $ cat > .hg/hgrc << EOF
29 29 > [extensions]
30 30 > badserver = $TESTDIR/badserverext.py
31 31 > [server]
32 32 > compressionengines = none
33 33 > EOF
34 34
35 35 Failure to accept() socket should result in connection related error message
36 36
37 37 $ hg serve --config badserver.closebeforeaccept=true -p $HGPORT -d --pid-file=hg.pid
38 38 $ cat hg.pid > $DAEMON_PIDS
39 39
40 40 $ hg clone http://localhost:$HGPORT/ clone
41 41 abort: error: (\$ECONNRESET\$|\$EADDRNOTAVAIL\$) (re)
42 42 [255]
43 43
44 44 (The server exits on its own, but there is a race between that and starting a new server.
45 45 So ensure the process is dead.)
46 46
47 47 $ killdaemons.py $DAEMON_PIDS
48 48
49 49 Failure immediately after accept() should yield connection related error message
50 50
51 51 $ hg serve --config badserver.closeafteraccept=true -p $HGPORT -d --pid-file=hg.pid
52 52 $ cat hg.pid > $DAEMON_PIDS
53 53
54 54 TODO: this usually outputs good results, but sometimes emits abort:
55 55 error: '' on FreeBSD and OS X.
56 56 What we ideally want are:
57 57
58 58 abort: error: $ECONNRESET$
59 59
60 60 The flakiness in this output was observable easily with
61 61 --runs-per-test=20 on macOS 10.12 during the freeze for 4.2.
62 62 $ hg clone http://localhost:$HGPORT/ clone
63 63 abort: error: * (glob)
64 64 [255]
65 65
66 66 $ killdaemons.py $DAEMON_PIDS
67 67
68 68 Failure to read all bytes in initial HTTP request should yield connection related error message
69 69
70 70 $ hg serve --config badserver.closeafterrecvbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
71 71 $ cat hg.pid > $DAEMON_PIDS
72 72
73 73 $ hg clone http://localhost:$HGPORT/ clone
74 74 abort: error: bad HTTP status line: * (glob)
75 75 [255]
76 76
77 77 $ killdaemons.py $DAEMON_PIDS
78 78
79 79 $ cat error.log
80 80 readline(1 from 65537) -> (1) G
81 81 read limit reached; closing socket
82 82
83 83 $ rm -f error.log
84 84
85 85 Same failure, but server reads full HTTP request line
86 86
87 87 $ hg serve --config badserver.closeafterrecvbytes=40 -p $HGPORT -d --pid-file=hg.pid -E error.log
88 88 $ cat hg.pid > $DAEMON_PIDS
89 89 $ hg clone http://localhost:$HGPORT/ clone
90 90 abort: error: bad HTTP status line: * (glob)
91 91 [255]
92 92
93 93 $ killdaemons.py $DAEMON_PIDS
94 94
95 95 $ cat error.log
96 96 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
97 97 readline(7 from -1) -> (7) Accept-
98 98 read limit reached; closing socket
99 99
100 100 $ rm -f error.log
101 101
102 102 Failure on subsequent HTTP request on the same socket (cmd?batch)
103 103
104 104 $ hg serve --config badserver.closeafterrecvbytes=210,223 -p $HGPORT -d --pid-file=hg.pid -E error.log
105 105 $ cat hg.pid > $DAEMON_PIDS
106 106 $ hg clone http://localhost:$HGPORT/ clone
107 107 abort: error: bad HTTP status line: * (glob)
108 108 [255]
109 109
110 110 $ killdaemons.py $DAEMON_PIDS
111 111
112 112 $ cat error.log
113 113 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
114 114 readline(177 from -1) -> (27) Accept-Encoding: identity\r\n
115 115 readline(150 from -1) -> (35) accept: application/mercurial-0.1\r\n
116 116 readline(115 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
117 117 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
118 118 readline(* from -1) -> (2) \r\n (glob)
119 119 write(36) -> HTTP/1.1 200 Script output follows\r\n
120 120 write(23) -> Server: badhttpserver\r\n
121 121 write(37) -> Date: $HTTP_DATE$\r\n
122 122 write(41) -> Content-Type: application/mercurial-0.1\r\n
123 123 write(21) -> Content-Length: 450\r\n
124 124 write(2) -> \r\n
125 125 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
126 126 readline(4? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
127 127 readline(1? from -1) -> (1?) Accept-Encoding* (glob)
128 128 read limit reached; closing socket
129 129 readline(223 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
130 130 readline(197 from -1) -> (27) Accept-Encoding: identity\r\n
131 131 readline(170 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
132 132 readline(141 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
133 133 readline(100 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
134 134 readline(39 from -1) -> (35) accept: application/mercurial-0.1\r\n
135 135 readline(4 from -1) -> (4) host
136 136 read limit reached; closing socket
137 137
138 138 $ rm -f error.log
139 139
140 140 Failure to read getbundle HTTP request
141 141
142 142 $ hg serve --config badserver.closeafterrecvbytes=308,317,304 -p $HGPORT -d --pid-file=hg.pid -E error.log
143 143 $ cat hg.pid > $DAEMON_PIDS
144 144 $ hg clone http://localhost:$HGPORT/ clone
145 145 requesting all changes
146 146 abort: error: bad HTTP status line: * (glob)
147 147 [255]
148 148
149 149 $ killdaemons.py $DAEMON_PIDS
150 150
151 151 $ cat error.log
152 152 readline(1 from -1) -> (1) x (?)
153 153 readline(1 from -1) -> (1) x (?)
154 154 readline(308 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
155 155 readline(275 from -1) -> (27) Accept-Encoding: identity\r\n
156 156 readline(248 from -1) -> (35) accept: application/mercurial-0.1\r\n
157 157 readline(213 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
158 158 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
159 159 readline(* from -1) -> (2) \r\n (glob)
160 160 write(36) -> HTTP/1.1 200 Script output follows\r\n
161 161 write(23) -> Server: badhttpserver\r\n
162 162 write(37) -> Date: $HTTP_DATE$\r\n
163 163 write(41) -> Content-Type: application/mercurial-0.1\r\n
164 164 write(21) -> Content-Length: 450\r\n
165 165 write(2) -> \r\n
166 166 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
167 167 readline(13? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
168 168 readline(1?? from -1) -> (27) Accept-Encoding: identity\r\n (glob)
169 169 readline(8? from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
170 170 readline(5? from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
171 171 readline(1? from -1) -> (1?) x-hgproto-1:* (glob)
172 172 read limit reached; closing socket
173 173 readline(317 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
174 174 readline(291 from -1) -> (27) Accept-Encoding: identity\r\n
175 175 readline(264 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
176 176 readline(235 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
177 177 readline(194 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
178 178 readline(133 from -1) -> (35) accept: application/mercurial-0.1\r\n
179 179 readline(98 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
180 180 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
181 181 readline(* from -1) -> (2) \r\n (glob)
182 182 write(36) -> HTTP/1.1 200 Script output follows\r\n
183 183 write(23) -> Server: badhttpserver\r\n
184 184 write(37) -> Date: $HTTP_DATE$\r\n
185 185 write(41) -> Content-Type: application/mercurial-0.1\r\n
186 186 write(20) -> Content-Length: 42\r\n
187 187 write(2) -> \r\n
188 188 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
189 189 readline(* from 65537) -> (*) GET /?cmd=getbundle HTTP* (glob)
190 190 read limit reached; closing socket
191 191 readline(304 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
192 192 readline(274 from -1) -> (27) Accept-Encoding: identity\r\n
193 193 readline(247 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
194 194 readline(218 from -1) -> (218) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtag
195 195 read limit reached; closing socket
196 196
197 197 $ rm -f error.log
198 198
199 199 Now do a variation using POST to send arguments
200 200
201 201 $ hg serve --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=329,344 -p $HGPORT -d --pid-file=hg.pid -E error.log
202 202 $ cat hg.pid > $DAEMON_PIDS
203 203
204 204 $ hg clone http://localhost:$HGPORT/ clone
205 205 abort: error: bad HTTP status line: * (glob)
206 206 [255]
207 207
208 208 $ killdaemons.py $DAEMON_PIDS
209 209
210 $ cat error.log
210 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
211 211 readline(329 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
212 212 readline(296 from -1) -> (27) Accept-Encoding: identity\r\n
213 213 readline(269 from -1) -> (35) accept: application/mercurial-0.1\r\n
214 214 readline(234 from -1) -> (2?) host: localhost:$HGPORT\r\n (glob)
215 215 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
216 216 readline(* from -1) -> (2) \r\n (glob)
217 217 write(36) -> HTTP/1.1 200 Script output follows\r\n
218 218 write(23) -> Server: badhttpserver\r\n
219 219 write(37) -> Date: $HTTP_DATE$\r\n
220 220 write(41) -> Content-Type: application/mercurial-0.1\r\n
221 221 write(21) -> Content-Length: 463\r\n
222 222 write(2) -> \r\n
223 223 write(463) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
224 224 readline(1?? from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n (glob)
225 225 readline(1?? from -1) -> (27) Accept-Encoding: identity\r\n (glob)
226 226 readline(1?? from -1) -> (41) content-type: application/mercurial-0.1\r\n (glob)
227 227 readline(6? from -1) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
228 228 readline(3? from -1) -> (19) x-hgargs-post: 28\r\n (glob)
229 229 readline(1? from -1) -> (1?) x-hgproto-1: * (glob)
230 230 read limit reached; closing socket
231 231 readline(344 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
232 232 readline(317 from -1) -> (27) Accept-Encoding: identity\r\n
233 233 readline(290 from -1) -> (41) content-type: application/mercurial-0.1\r\n
234 234 readline(249 from -1) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n
235 235 readline(216 from -1) -> (19) x-hgargs-post: 28\r\n
236 236 readline(197 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
237 237 readline(136 from -1) -> (35) accept: application/mercurial-0.1\r\n
238 238 readline(101 from -1) -> (20) content-length: 28\r\n
239 239 readline(81 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
240 240 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
241 241 readline(* from -1) -> (2) \r\n (glob)
242 242 read(* from 28) -> (*) cmds=* (glob)
243 243 read limit reached, closing socket
244 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
245 Traceback (most recent call last):
246 Exception: connection closed after receiving N bytes
247
244 248 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
245 249
246 250 $ rm -f error.log
247 251
248 252 Now move on to partial server responses
249 253
250 254 Server sends a single character from the HTTP response line
251 255
252 256 $ hg serve --config badserver.closeaftersendbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
253 257 $ cat hg.pid > $DAEMON_PIDS
254 258
255 259 $ hg clone http://localhost:$HGPORT/ clone
256 260 abort: error: bad HTTP status line: H
257 261 [255]
258 262
259 263 $ killdaemons.py $DAEMON_PIDS
260 264
261 $ cat error.log
265 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
262 266 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
263 267 readline(-1) -> (27) Accept-Encoding: identity\r\n
264 268 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
265 269 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
266 270 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
267 271 readline(-1) -> (2) \r\n
268 272 write(1 from 36) -> (0) H
269 273 write limit reached; closing socket
274 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
275 Traceback (most recent call last):
276 Exception: connection closed after sending N bytes
277
270 278 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
271 279
272 280 $ rm -f error.log
273 281
274 282 Server sends an incomplete capabilities response body
275 283
276 284 $ hg serve --config badserver.closeaftersendbytes=180 -p $HGPORT -d --pid-file=hg.pid -E error.log
277 285 $ cat hg.pid > $DAEMON_PIDS
278 286
279 287 $ hg clone http://localhost:$HGPORT/ clone
280 288 abort: HTTP request error (incomplete response; expected 450 bytes got 20)
281 289 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
282 290 [255]
283 291
284 292 $ killdaemons.py $DAEMON_PIDS
285 293
286 $ cat error.log
294 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
287 295 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
288 296 readline(-1) -> (27) Accept-Encoding: identity\r\n
289 297 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
290 298 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
291 299 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
292 300 readline(-1) -> (2) \r\n
293 301 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n
294 302 write(23 from 23) -> (121) Server: badhttpserver\r\n
295 303 write(37 from 37) -> (84) Date: $HTTP_DATE$\r\n
296 304 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n
297 305 write(21 from 21) -> (22) Content-Length: 450\r\n
298 306 write(2 from 2) -> (20) \r\n
299 307 write(20 from 450) -> (0) batch branchmap bund
300 308 write limit reached; closing socket
309 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
310 Traceback (most recent call last):
311 Exception: connection closed after sending N bytes
312
301 313
302 314 $ rm -f error.log
303 315
304 316 Server sends incomplete headers for batch request
305 317
306 318 $ hg serve --config badserver.closeaftersendbytes=728 -p $HGPORT -d --pid-file=hg.pid -E error.log
307 319 $ cat hg.pid > $DAEMON_PIDS
308 320
309 321 TODO this output is horrible
310 322
311 323 $ hg clone http://localhost:$HGPORT/ clone
312 324 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
313 325 ---%<--- (applicat)
314 326
315 327 ---%<---
316 328 !
317 329 [255]
318 330
319 331 $ killdaemons.py $DAEMON_PIDS
320 332
321 $ cat error.log
333 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
322 334 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
323 335 readline(-1) -> (27) Accept-Encoding: identity\r\n
324 336 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
325 337 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
326 338 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
327 339 readline(-1) -> (2) \r\n
328 340 write(36 from 36) -> (692) HTTP/1.1 200 Script output follows\r\n
329 341 write(23 from 23) -> (669) Server: badhttpserver\r\n
330 342 write(37 from 37) -> (632) Date: $HTTP_DATE$\r\n
331 343 write(41 from 41) -> (591) Content-Type: application/mercurial-0.1\r\n
332 344 write(21 from 21) -> (570) Content-Length: 450\r\n
333 345 write(2 from 2) -> (568) \r\n
334 346 write(450 from 450) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
335 347 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
336 348 readline(-1) -> (27) Accept-Encoding: identity\r\n
337 349 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
338 350 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
339 351 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
340 352 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
341 353 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
342 354 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
343 355 readline(-1) -> (2) \r\n
344 356 write(36 from 36) -> (82) HTTP/1.1 200 Script output follows\r\n
345 357 write(23 from 23) -> (59) Server: badhttpserver\r\n
346 358 write(37 from 37) -> (22) Date: $HTTP_DATE$\r\n
347 359 write(22 from 41) -> (0) Content-Type: applicat
348 360 write limit reached; closing socket
361 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
362 Traceback (most recent call last):
363 Exception: connection closed after sending N bytes
364
349 365 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
350 366
351 367 $ rm -f error.log
352 368
353 369 Server sends an incomplete HTTP response body to batch request
354 370
355 371 $ hg serve --config badserver.closeaftersendbytes=793 -p $HGPORT -d --pid-file=hg.pid -E error.log
356 372 $ cat hg.pid > $DAEMON_PIDS
357 373
358 374 TODO client spews a stack due to uncaught ValueError in batch.results()
359 375 #if no-chg
360 376 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
361 377 [1]
362 378 #else
363 379 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
364 380 [255]
365 381 #endif
366 382
367 383 $ killdaemons.py $DAEMON_PIDS
368 384
369 $ cat error.log
385 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
370 386 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
371 387 readline(-1) -> (27) Accept-Encoding: identity\r\n
372 388 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
373 389 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
374 390 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
375 391 readline(-1) -> (2) \r\n
376 392 write(36 from 36) -> (757) HTTP/1.1 200 Script output follows\r\n
377 393 write(23 from 23) -> (734) Server: badhttpserver\r\n
378 394 write(37 from 37) -> (697) Date: $HTTP_DATE$\r\n
379 395 write(41 from 41) -> (656) Content-Type: application/mercurial-0.1\r\n
380 396 write(21 from 21) -> (635) Content-Length: 450\r\n
381 397 write(2 from 2) -> (633) \r\n
382 398 write(450 from 450) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
383 399 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
384 400 readline(-1) -> (27) Accept-Encoding: identity\r\n
385 401 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
386 402 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
387 403 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
388 404 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
389 405 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
390 406 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
391 407 readline(-1) -> (2) \r\n
392 408 write(36 from 36) -> (147) HTTP/1.1 200 Script output follows\r\n
393 409 write(23 from 23) -> (124) Server: badhttpserver\r\n
394 410 write(37 from 37) -> (87) Date: $HTTP_DATE$\r\n
395 411 write(41 from 41) -> (46) Content-Type: application/mercurial-0.1\r\n
396 412 write(20 from 20) -> (26) Content-Length: 42\r\n
397 413 write(2 from 2) -> (24) \r\n
398 414 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672
399 415 write limit reached; closing socket
416 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
417 Traceback (most recent call last):
418 Exception: connection closed after sending N bytes
419
400 420
401 421 $ rm -f error.log
402 422
403 423 Server sends incomplete headers for getbundle response
404 424
405 425 $ hg serve --config badserver.closeaftersendbytes=940 -p $HGPORT -d --pid-file=hg.pid -E error.log
406 426 $ cat hg.pid > $DAEMON_PIDS
407 427
408 428 TODO this output is terrible
409 429
410 430 $ hg clone http://localhost:$HGPORT/ clone
411 431 requesting all changes
412 432 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
413 433 ---%<--- (application/mercuri)
414 434
415 435 ---%<---
416 436 !
417 437 [255]
418 438
419 439 $ killdaemons.py $DAEMON_PIDS
420 440
421 $ cat error.log
441 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
422 442 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
423 443 readline(-1) -> (27) Accept-Encoding: identity\r\n
424 444 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
425 445 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
426 446 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
427 447 readline(-1) -> (2) \r\n
428 448 write(36 from 36) -> (904) HTTP/1.1 200 Script output follows\r\n
429 449 write(23 from 23) -> (881) Server: badhttpserver\r\n
430 450 write(37 from 37) -> (844) Date: $HTTP_DATE$\r\n
431 451 write(41 from 41) -> (803) Content-Type: application/mercurial-0.1\r\n
432 452 write(21 from 21) -> (782) Content-Length: 450\r\n
433 453 write(2 from 2) -> (780) \r\n
434 454 write(450 from 450) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
435 455 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
436 456 readline(-1) -> (27) Accept-Encoding: identity\r\n
437 457 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
438 458 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
439 459 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
440 460 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
441 461 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
442 462 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
443 463 readline(-1) -> (2) \r\n
444 464 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n
445 465 write(23 from 23) -> (271) Server: badhttpserver\r\n
446 466 write(37 from 37) -> (234) Date: $HTTP_DATE$\r\n
447 467 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n
448 468 write(20 from 20) -> (173) Content-Length: 42\r\n
449 469 write(2 from 2) -> (171) \r\n
450 470 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
451 471 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
452 472 readline(-1) -> (27) Accept-Encoding: identity\r\n
453 473 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
454 474 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
455 475 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
456 476 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
457 477 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
458 478 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
459 479 readline(-1) -> (2) \r\n
460 480 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n
461 481 write(23 from 23) -> (70) Server: badhttpserver\r\n
462 482 write(37 from 37) -> (33) Date: $HTTP_DATE$\r\n
463 483 write(33 from 41) -> (0) Content-Type: application/mercuri
464 484 write limit reached; closing socket
485 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
486 Traceback (most recent call last):
487 Exception: connection closed after sending N bytes
488
465 489 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
466 490
467 491 $ rm -f error.log
468 492
469 493 Server stops before it sends transfer encoding
470 494
471 495 $ hg serve --config badserver.closeaftersendbytes=973 -p $HGPORT -d --pid-file=hg.pid -E error.log
472 496 $ cat hg.pid > $DAEMON_PIDS
473 497
474 498 $ hg clone http://localhost:$HGPORT/ clone
475 499 requesting all changes
476 500 abort: stream ended unexpectedly (got 0 bytes, expected 1)
477 501 [255]
478 502
479 503 $ killdaemons.py $DAEMON_PIDS
480 504
481 $ tail -4 error.log
482 write(41 from 41) -> (25) Content-Type: application/mercurial-0.2\r\n
483 write(25 from 28) -> (0) Transfer-Encoding: chunke
484 write limit reached; closing socket
505 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -4
506 Traceback (most recent call last):
507 Exception: connection closed after sending N bytes
508
485 509 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
486 510
487 511 $ rm -f error.log
488 512
489 513 Server sends empty HTTP body for getbundle
490 514
491 515 $ hg serve --config badserver.closeaftersendbytes=978 -p $HGPORT -d --pid-file=hg.pid -E error.log
492 516 $ cat hg.pid > $DAEMON_PIDS
493 517
494 518 $ hg clone http://localhost:$HGPORT/ clone
495 519 requesting all changes
496 520 abort: HTTP request error (incomplete response)
497 521 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
498 522 [255]
499 523
500 524 $ killdaemons.py $DAEMON_PIDS
501 525
502 $ cat error.log
526 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
503 527 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
504 528 readline(-1) -> (27) Accept-Encoding: identity\r\n
505 529 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
506 530 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
507 531 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
508 532 readline(-1) -> (2) \r\n
509 533 write(36 from 36) -> (942) HTTP/1.1 200 Script output follows\r\n
510 534 write(23 from 23) -> (919) Server: badhttpserver\r\n
511 535 write(37 from 37) -> (882) Date: $HTTP_DATE$\r\n
512 536 write(41 from 41) -> (841) Content-Type: application/mercurial-0.1\r\n
513 537 write(21 from 21) -> (820) Content-Length: 450\r\n
514 538 write(2 from 2) -> (818) \r\n
515 539 write(450 from 450) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
516 540 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
517 541 readline(-1) -> (27) Accept-Encoding: identity\r\n
518 542 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
519 543 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
520 544 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
521 545 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
522 546 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
523 547 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
524 548 readline(-1) -> (2) \r\n
525 549 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n
526 550 write(23 from 23) -> (309) Server: badhttpserver\r\n
527 551 write(37 from 37) -> (272) Date: $HTTP_DATE$\r\n
528 552 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n
529 553 write(20 from 20) -> (211) Content-Length: 42\r\n
530 554 write(2 from 2) -> (209) \r\n
531 555 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
532 556 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
533 557 readline(-1) -> (27) Accept-Encoding: identity\r\n
534 558 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
535 559 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
536 560 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
537 561 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
538 562 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
539 563 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
540 564 readline(-1) -> (2) \r\n
541 565 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n
542 566 write(23 from 23) -> (108) Server: badhttpserver\r\n
543 567 write(37 from 37) -> (71) Date: $HTTP_DATE$\r\n
544 568 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n
545 569 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n
546 570 write(2 from 2) -> (0) \r\n
547 571 write limit reached; closing socket
572 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
573 Traceback (most recent call last):
574 Exception: connection closed after sending N bytes
575
548 576 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
549 577
550 578 $ rm -f error.log
551 579
552 580 Server sends partial compression string
553 581
554 582 $ hg serve --config badserver.closeaftersendbytes=1002 -p $HGPORT -d --pid-file=hg.pid -E error.log
555 583 $ cat hg.pid > $DAEMON_PIDS
556 584
557 585 $ hg clone http://localhost:$HGPORT/ clone
558 586 requesting all changes
559 587 abort: HTTP request error (incomplete response)
560 588 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
561 589 [255]
562 590
563 591 $ killdaemons.py $DAEMON_PIDS
564 592
565 $ cat error.log
593 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
566 594 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
567 595 readline(-1) -> (27) Accept-Encoding: identity\r\n
568 596 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
569 597 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
570 598 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
571 599 readline(-1) -> (2) \r\n
572 600 write(36 from 36) -> (966) HTTP/1.1 200 Script output follows\r\n
573 601 write(23 from 23) -> (943) Server: badhttpserver\r\n
574 602 write(37 from 37) -> (906) Date: $HTTP_DATE$\r\n
575 603 write(41 from 41) -> (865) Content-Type: application/mercurial-0.1\r\n
576 604 write(21 from 21) -> (844) Content-Length: 450\r\n
577 605 write(2 from 2) -> (842) \r\n
578 606 write(450 from 450) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
579 607 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
580 608 readline(-1) -> (27) Accept-Encoding: identity\r\n
581 609 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
582 610 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
583 611 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
584 612 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
585 613 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
586 614 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
587 615 readline(-1) -> (2) \r\n
588 616 write(36 from 36) -> (356) HTTP/1.1 200 Script output follows\r\n
589 617 write(23 from 23) -> (333) Server: badhttpserver\r\n
590 618 write(37 from 37) -> (296) Date: $HTTP_DATE$\r\n
591 619 write(41 from 41) -> (255) Content-Type: application/mercurial-0.1\r\n
592 620 write(20 from 20) -> (235) Content-Length: 42\r\n
593 621 write(2 from 2) -> (233) \r\n
594 622 write(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
595 623 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
596 624 readline(-1) -> (27) Accept-Encoding: identity\r\n
597 625 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
598 626 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
599 627 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
600 628 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
601 629 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
602 630 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
603 631 readline(-1) -> (2) \r\n
604 632 write(36 from 36) -> (155) HTTP/1.1 200 Script output follows\r\n
605 633 write(23 from 23) -> (132) Server: badhttpserver\r\n
606 634 write(37 from 37) -> (95) Date: $HTTP_DATE$\r\n
607 635 write(41 from 41) -> (54) Content-Type: application/mercurial-0.2\r\n
608 636 write(28 from 28) -> (26) Transfer-Encoding: chunked\r\n
609 637 write(2 from 2) -> (24) \r\n
610 638 write(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc)
611 639 write(9 from 9) -> (9) 4\r\nnone\r\n
612 640 write(9 from 9) -> (0) 4\r\nHG20\r\n
613 641 write limit reached; closing socket
642 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
643 Traceback (most recent call last):
644 Exception: connection closed after sending N bytes
645
614 646 write(27) -> 15\r\nInternal Server Error\r\n
615 647
616 648 $ rm -f error.log
617 649
618 650 Server sends partial bundle2 header magic
619 651
620 652 $ hg serve --config badserver.closeaftersendbytes=999 -p $HGPORT -d --pid-file=hg.pid -E error.log
621 653 $ cat hg.pid > $DAEMON_PIDS
622 654
623 655 $ hg clone http://localhost:$HGPORT/ clone
624 656 requesting all changes
625 657 abort: HTTP request error (incomplete response; expected 4 bytes got 3)
626 658 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
627 659 [255]
628 660
629 661 $ killdaemons.py $DAEMON_PIDS
630 662
631 $ tail -7 error.log
663 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
632 664 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n
633 665 write(2 from 2) -> (21) \r\n
634 666 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
635 667 write(9 from 9) -> (6) 4\r\nnone\r\n
636 668 write(6 from 9) -> (0) 4\r\nHG2
637 669 write limit reached; closing socket
670 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
671 Traceback (most recent call last):
672 Exception: connection closed after sending N bytes
673
638 674 write(27) -> 15\r\nInternal Server Error\r\n
639 675
640 676 $ rm -f error.log
641 677
642 678 Server sends incomplete bundle2 stream params length
643 679
644 680 $ hg serve --config badserver.closeaftersendbytes=1008 -p $HGPORT -d --pid-file=hg.pid -E error.log
645 681 $ cat hg.pid > $DAEMON_PIDS
646 682
647 683 $ hg clone http://localhost:$HGPORT/ clone
648 684 requesting all changes
649 685 abort: HTTP request error (incomplete response; expected 4 bytes got 3)
650 686 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
651 687 [255]
652 688
653 689 $ killdaemons.py $DAEMON_PIDS
654 690
655 $ tail -8 error.log
691 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
656 692 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n
657 693 write(2 from 2) -> (30) \r\n
658 694 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
659 695 write(9 from 9) -> (15) 4\r\nnone\r\n
660 696 write(9 from 9) -> (6) 4\r\nHG20\r\n
661 697 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
662 698 write limit reached; closing socket
699 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
700 Traceback (most recent call last):
701 Exception: connection closed after sending N bytes
702
663 703 write(27) -> 15\r\nInternal Server Error\r\n
664 704
665 705 $ rm -f error.log
666 706
667 707 Servers stops after bundle2 stream params header
668 708
669 709 $ hg serve --config badserver.closeaftersendbytes=1011 -p $HGPORT -d --pid-file=hg.pid -E error.log
670 710 $ cat hg.pid > $DAEMON_PIDS
671 711
672 712 $ hg clone http://localhost:$HGPORT/ clone
673 713 requesting all changes
674 714 abort: HTTP request error (incomplete response)
675 715 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
676 716 [255]
677 717
678 718 $ killdaemons.py $DAEMON_PIDS
679 719
680 $ tail -8 error.log
720 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
681 721 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n
682 722 write(2 from 2) -> (33) \r\n
683 723 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
684 724 write(9 from 9) -> (18) 4\r\nnone\r\n
685 725 write(9 from 9) -> (9) 4\r\nHG20\r\n
686 726 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
687 727 write limit reached; closing socket
728 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
729 Traceback (most recent call last):
730 Exception: connection closed after sending N bytes
731
688 732 write(27) -> 15\r\nInternal Server Error\r\n
689 733
690 734 $ rm -f error.log
691 735
692 736 Server stops sending after bundle2 part header length
693 737
694 738 $ hg serve --config badserver.closeaftersendbytes=1020 -p $HGPORT -d --pid-file=hg.pid -E error.log
695 739 $ cat hg.pid > $DAEMON_PIDS
696 740
697 741 $ hg clone http://localhost:$HGPORT/ clone
698 742 requesting all changes
699 743 abort: HTTP request error (incomplete response)
700 744 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
701 745 [255]
702 746
703 747 $ killdaemons.py $DAEMON_PIDS
704 748
705 $ tail -9 error.log
749 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -13
706 750 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n
707 751 write(2 from 2) -> (42) \r\n
708 752 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
709 753 write(9 from 9) -> (27) 4\r\nnone\r\n
710 754 write(9 from 9) -> (18) 4\r\nHG20\r\n
711 755 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
712 756 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
713 757 write limit reached; closing socket
758 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
759 Traceback (most recent call last):
760 Exception: connection closed after sending N bytes
761
714 762 write(27) -> 15\r\nInternal Server Error\r\n
715 763
716 764 $ rm -f error.log
717 765
718 766 Server stops sending after bundle2 part header
719 767
720 768 $ hg serve --config badserver.closeaftersendbytes=1067 -p $HGPORT -d --pid-file=hg.pid -E error.log
721 769 $ cat hg.pid > $DAEMON_PIDS
722 770
723 771 $ hg clone http://localhost:$HGPORT/ clone
724 772 requesting all changes
725 773 adding changesets
726 774 transaction abort!
727 775 rollback completed
728 776 abort: HTTP request error (incomplete response)
729 777 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
730 778 [255]
731 779
732 780 $ killdaemons.py $DAEMON_PIDS
733 781
734 $ tail -10 error.log
782 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
735 783 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n
736 784 write(2 from 2) -> (89) \r\n
737 785 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
738 786 write(9 from 9) -> (74) 4\r\nnone\r\n
739 787 write(9 from 9) -> (65) 4\r\nHG20\r\n
740 788 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
741 789 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
742 790 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
743 791 write limit reached; closing socket
792 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
793 Traceback (most recent call last):
794 Exception: connection closed after sending N bytes
795
744 796 write(27) -> 15\r\nInternal Server Error\r\n
745 797
746 798 $ rm -f error.log
747 799
748 800 Server stops after bundle2 part payload chunk size
749 801
750 802 $ hg serve --config badserver.closeaftersendbytes=1088 -p $HGPORT -d --pid-file=hg.pid -E error.log
751 803 $ cat hg.pid > $DAEMON_PIDS
752 804
753 805 $ hg clone http://localhost:$HGPORT/ clone
754 806 requesting all changes
755 807 adding changesets
756 808 transaction abort!
757 809 rollback completed
758 810 abort: HTTP request error (incomplete response; expected 466 bytes got 7)
759 811 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
760 812 [255]
761 813
762 814 $ killdaemons.py $DAEMON_PIDS
763 815
764 $ tail -11 error.log
816 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -15
765 817 write(2 from 2) -> (110) \r\n
766 818 write(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
767 819 write(9 from 9) -> (95) 4\r\nnone\r\n
768 820 write(9 from 9) -> (86) 4\r\nHG20\r\n
769 821 write(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
770 822 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
771 823 write(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
772 824 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
773 825 write(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
774 826 write limit reached; closing socket
827 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
828 Traceback (most recent call last):
829 Exception: connection closed after sending N bytes
830
775 831 write(27) -> 15\r\nInternal Server Error\r\n
776 832
777 833 $ rm -f error.log
778 834
779 835 Server stops sending in middle of bundle2 payload chunk
780 836
781 837 $ hg serve --config badserver.closeaftersendbytes=1549 -p $HGPORT -d --pid-file=hg.pid -E error.log
782 838 $ cat hg.pid > $DAEMON_PIDS
783 839
784 840 $ hg clone http://localhost:$HGPORT/ clone
785 841 requesting all changes
786 842 adding changesets
787 843 transaction abort!
788 844 rollback completed
789 845 abort: HTTP request error (incomplete response)
790 846 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
791 847 [255]
792 848
793 849 $ killdaemons.py $DAEMON_PIDS
794 850
795 $ tail -12 error.log
851 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -16
796 852 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n
797 853 write(2 from 2) -> (571) \r\n
798 854 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
799 855 write(9 from 9) -> (556) 4\r\nnone\r\n
800 856 write(9 from 9) -> (547) 4\r\nHG20\r\n
801 857 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
802 858 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
803 859 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
804 860 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
805 861 write(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
806 862 write limit reached; closing socket
863 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
864 Traceback (most recent call last):
865 Exception: connection closed after sending N bytes
866
807 867 write(27) -> 15\r\nInternal Server Error\r\n
808 868
809 869 $ rm -f error.log
810 870
811 871 Server stops sending after 0 length payload chunk size
812 872
813 873 $ hg serve --config badserver.closeaftersendbytes=1580 -p $HGPORT -d --pid-file=hg.pid -E error.log
814 874 $ cat hg.pid > $DAEMON_PIDS
815 875
816 876 $ hg clone http://localhost:$HGPORT/ clone
817 877 requesting all changes
818 878 adding changesets
819 879 adding manifests
820 880 adding file changes
821 881 added 1 changesets with 1 changes to 1 files
822 882 transaction abort!
823 883 rollback completed
824 884 abort: HTTP request error (incomplete response; expected 32 bytes got 9)
825 885 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
826 886 [255]
827 887
828 888 $ killdaemons.py $DAEMON_PIDS
829 889
830 $ tail -13 error.log
890 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -17
831 891 write(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
832 892 write(9 from 9) -> (587) 4\r\nnone\r\n
833 893 write(9 from 9) -> (578) 4\r\nHG20\r\n
834 894 write(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
835 895 write(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
836 896 write(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
837 897 write(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
838 898 write(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
839 899 write(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
840 900 write(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
841 901 write(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
842 902 write limit reached; closing socket
903 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
904 Traceback (most recent call last):
905 Exception: connection closed after sending N bytes
906
843 907 write(27) -> 15\r\nInternal Server Error\r\n
844 908
845 909 $ rm -f error.log
846 910
847 911 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
848 912 This is before the 0 size chunked transfer part that signals end of HTTP response.
849 913
850 914 # $ hg serve --config badserver.closeaftersendbytes=1755 -p $HGPORT -d --pid-file=hg.pid -E error.log
851 915 $ hg serve --config badserver.closeaftersendbytes=1862 -p $HGPORT -d --pid-file=hg.pid -E error.log
852 916 $ cat hg.pid > $DAEMON_PIDS
853 917
854 918 $ hg clone http://localhost:$HGPORT/ clone
855 919 requesting all changes
856 920 adding changesets
857 921 adding manifests
858 922 adding file changes
859 923 added 1 changesets with 1 changes to 1 files
860 924 new changesets 96ee1d7354c4
861 925 updating to branch default
862 926 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 927
864 928 $ killdaemons.py $DAEMON_PIDS
865 929
866 $ tail -22 error.log
930 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -26
867 931 write(9 from 9) -> (851) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
868 932 write(9 from 9) -> (842) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
869 933 write(47 from 47) -> (795) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
870 934 write(9 from 9) -> (786) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
871 935 write(473 from 473) -> (313) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
872 936 write(9 from 9) -> (304) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
873 937 write(9 from 9) -> (295) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
874 938 write(38 from 38) -> (257) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
875 939 write(9 from 9) -> (248) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
876 940 write(64 from 64) -> (184) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
877 941 write(9 from 9) -> (175) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
878 942 write(9 from 9) -> (166) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
879 943 write(41 from 41) -> (125) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
880 944 write(9 from 9) -> (116) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
881 945 write(9 from 9) -> (107) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
882 946 write(35 from 35) -> (72) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
883 947 write(9 from 9) -> (63) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
884 948 write(45 from 45) -> (18) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
885 949 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
886 950 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
887 951 write limit reached; closing socket
952 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
953 Traceback (most recent call last):
954 Exception: connection closed after sending N bytes
955
888 956 write(27) -> 15\r\nInternal Server Error\r\n
889 957
890 958 $ rm -f error.log
891 959 $ rm -rf clone
892 960
893 961 Server sends a size 0 chunked-transfer size without terminating \r\n
894 962
895 963 $ hg serve --config badserver.closeaftersendbytes=1865 -p $HGPORT -d --pid-file=hg.pid -E error.log
896 964 $ cat hg.pid > $DAEMON_PIDS
897 965
898 966 $ hg clone http://localhost:$HGPORT/ clone
899 967 requesting all changes
900 968 adding changesets
901 969 adding manifests
902 970 adding file changes
903 971 added 1 changesets with 1 changes to 1 files
904 972 new changesets 96ee1d7354c4
905 973 updating to branch default
906 974 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
907 975
908 976 $ killdaemons.py $DAEMON_PIDS
909 977
910 $ tail -23 error.log
978 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -27
911 979 write(9 from 9) -> (854) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
912 980 write(9 from 9) -> (845) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
913 981 write(47 from 47) -> (798) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
914 982 write(9 from 9) -> (789) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
915 983 write(473 from 473) -> (316) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
916 984 write(9 from 9) -> (307) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
917 985 write(9 from 9) -> (298) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
918 986 write(38 from 38) -> (260) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
919 987 write(9 from 9) -> (251) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
920 988 write(64 from 64) -> (187) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
921 989 write(9 from 9) -> (178) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
922 990 write(9 from 9) -> (169) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
923 991 write(41 from 41) -> (128) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
924 992 write(9 from 9) -> (119) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
925 993 write(9 from 9) -> (110) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
926 994 write(35 from 35) -> (75) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
927 995 write(9 from 9) -> (66) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
928 996 write(45 from 45) -> (21) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
929 997 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
930 998 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
931 999 write(3 from 5) -> (0) 0\r\n
932 1000 write limit reached; closing socket
1001 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1002 Traceback (most recent call last):
1003 Exception: connection closed after sending N bytes
1004
933 1005 write(27) -> 15\r\nInternal Server Error\r\n
934 1006
935 1007 $ rm -f error.log
936 1008 $ rm -rf clone
General Comments 0
You need to be logged in to leave comments. Login now