##// END OF EJS Templates
httppeer: wrap HTTPResponse.read() globally...
Gregory Szorc -
r32002:bf855efe default
parent child Browse files
Show More
@@ -1,254 +1,257
1 # error.py - Mercurial exceptions
1 # error.py - Mercurial exceptions
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Mercurial exceptions.
8 """Mercurial exceptions.
9
9
10 This allows us to catch exceptions at higher levels without forcing
10 This allows us to catch exceptions at higher levels without forcing
11 imports.
11 imports.
12 """
12 """
13
13
14 from __future__ import absolute_import
14 from __future__ import absolute_import
15
15
16 # Do not import anything here, please
16 # Do not import anything here, please
17
17
18 class Hint(object):
18 class Hint(object):
19 """Mix-in to provide a hint of an error
19 """Mix-in to provide a hint of an error
20
20
21 This should come first in the inheritance list to consume a hint and
21 This should come first in the inheritance list to consume a hint and
22 pass remaining arguments to the exception class.
22 pass remaining arguments to the exception class.
23 """
23 """
24 def __init__(self, *args, **kw):
24 def __init__(self, *args, **kw):
25 self.hint = kw.pop(r'hint', None)
25 self.hint = kw.pop(r'hint', None)
26 super(Hint, self).__init__(*args, **kw)
26 super(Hint, self).__init__(*args, **kw)
27
27
28 class RevlogError(Hint, Exception):
28 class RevlogError(Hint, Exception):
29 pass
29 pass
30
30
31 class FilteredIndexError(IndexError):
31 class FilteredIndexError(IndexError):
32 pass
32 pass
33
33
34 class LookupError(RevlogError, KeyError):
34 class LookupError(RevlogError, KeyError):
35 def __init__(self, name, index, message):
35 def __init__(self, name, index, message):
36 self.name = name
36 self.name = name
37 self.index = index
37 self.index = index
38 # this can't be called 'message' because at least some installs of
38 # this can't be called 'message' because at least some installs of
39 # Python 2.6+ complain about the 'message' property being deprecated
39 # Python 2.6+ complain about the 'message' property being deprecated
40 self.lookupmessage = message
40 self.lookupmessage = message
41 if isinstance(name, str) and len(name) == 20:
41 if isinstance(name, str) and len(name) == 20:
42 from .node import short
42 from .node import short
43 name = short(name)
43 name = short(name)
44 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
44 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
45
45
46 def __str__(self):
46 def __str__(self):
47 return RevlogError.__str__(self)
47 return RevlogError.__str__(self)
48
48
49 class FilteredLookupError(LookupError):
49 class FilteredLookupError(LookupError):
50 pass
50 pass
51
51
52 class ManifestLookupError(LookupError):
52 class ManifestLookupError(LookupError):
53 pass
53 pass
54
54
55 class CommandError(Exception):
55 class CommandError(Exception):
56 """Exception raised on errors in parsing the command line."""
56 """Exception raised on errors in parsing the command line."""
57
57
58 class InterventionRequired(Hint, Exception):
58 class InterventionRequired(Hint, Exception):
59 """Exception raised when a command requires human intervention."""
59 """Exception raised when a command requires human intervention."""
60
60
61 class Abort(Hint, Exception):
61 class Abort(Hint, Exception):
62 """Raised if a command needs to print an error and exit."""
62 """Raised if a command needs to print an error and exit."""
63
63
64 class HookLoadError(Abort):
64 class HookLoadError(Abort):
65 """raised when loading a hook fails, aborting an operation
65 """raised when loading a hook fails, aborting an operation
66
66
67 Exists to allow more specialized catching."""
67 Exists to allow more specialized catching."""
68
68
69 class HookAbort(Abort):
69 class HookAbort(Abort):
70 """raised when a validation hook fails, aborting an operation
70 """raised when a validation hook fails, aborting an operation
71
71
72 Exists to allow more specialized catching."""
72 Exists to allow more specialized catching."""
73
73
74 class ConfigError(Abort):
74 class ConfigError(Abort):
75 """Exception raised when parsing config files"""
75 """Exception raised when parsing config files"""
76
76
77 class UpdateAbort(Abort):
77 class UpdateAbort(Abort):
78 """Raised when an update is aborted for destination issue"""
78 """Raised when an update is aborted for destination issue"""
79
79
80 class MergeDestAbort(Abort):
80 class MergeDestAbort(Abort):
81 """Raised when an update is aborted for destination issues"""
81 """Raised when an update is aborted for destination issues"""
82
82
83 class NoMergeDestAbort(MergeDestAbort):
83 class NoMergeDestAbort(MergeDestAbort):
84 """Raised when an update is aborted because there is nothing to merge"""
84 """Raised when an update is aborted because there is nothing to merge"""
85
85
86 class ManyMergeDestAbort(MergeDestAbort):
86 class ManyMergeDestAbort(MergeDestAbort):
87 """Raised when an update is aborted because destination is ambiguous"""
87 """Raised when an update is aborted because destination is ambiguous"""
88
88
89 class ResponseExpected(Abort):
89 class ResponseExpected(Abort):
90 """Raised when an EOF is received for a prompt"""
90 """Raised when an EOF is received for a prompt"""
91 def __init__(self):
91 def __init__(self):
92 from .i18n import _
92 from .i18n import _
93 Abort.__init__(self, _('response expected'))
93 Abort.__init__(self, _('response expected'))
94
94
95 class OutOfBandError(Hint, Exception):
95 class OutOfBandError(Hint, Exception):
96 """Exception raised when a remote repo reports failure"""
96 """Exception raised when a remote repo reports failure"""
97
97
98 class ParseError(Hint, Exception):
98 class ParseError(Hint, Exception):
99 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
99 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
100
100
101 class UnknownIdentifier(ParseError):
101 class UnknownIdentifier(ParseError):
102 """Exception raised when a {rev,file}set references an unknown identifier"""
102 """Exception raised when a {rev,file}set references an unknown identifier"""
103
103
104 def __init__(self, function, symbols):
104 def __init__(self, function, symbols):
105 from .i18n import _
105 from .i18n import _
106 ParseError.__init__(self, _("unknown identifier: %s") % function)
106 ParseError.__init__(self, _("unknown identifier: %s") % function)
107 self.function = function
107 self.function = function
108 self.symbols = symbols
108 self.symbols = symbols
109
109
110 class RepoError(Hint, Exception):
110 class RepoError(Hint, Exception):
111 pass
111 pass
112
112
113 class RepoLookupError(RepoError):
113 class RepoLookupError(RepoError):
114 pass
114 pass
115
115
116 class FilteredRepoLookupError(RepoLookupError):
116 class FilteredRepoLookupError(RepoLookupError):
117 pass
117 pass
118
118
119 class CapabilityError(RepoError):
119 class CapabilityError(RepoError):
120 pass
120 pass
121
121
122 class RequirementError(RepoError):
122 class RequirementError(RepoError):
123 """Exception raised if .hg/requires has an unknown entry."""
123 """Exception raised if .hg/requires has an unknown entry."""
124
124
125 class StdioError(IOError):
125 class StdioError(IOError):
126 """Raised if I/O to stdout or stderr fails"""
126 """Raised if I/O to stdout or stderr fails"""
127
127
128 def __init__(self, err):
128 def __init__(self, err):
129 IOError.__init__(self, err.errno, err.strerror)
129 IOError.__init__(self, err.errno, err.strerror)
130
130
131 class UnsupportedMergeRecords(Abort):
131 class UnsupportedMergeRecords(Abort):
132 def __init__(self, recordtypes):
132 def __init__(self, recordtypes):
133 from .i18n import _
133 from .i18n import _
134 self.recordtypes = sorted(recordtypes)
134 self.recordtypes = sorted(recordtypes)
135 s = ' '.join(self.recordtypes)
135 s = ' '.join(self.recordtypes)
136 Abort.__init__(
136 Abort.__init__(
137 self, _('unsupported merge state records: %s') % s,
137 self, _('unsupported merge state records: %s') % s,
138 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
138 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
139 'more information'))
139 'more information'))
140
140
141 class LockError(IOError):
141 class LockError(IOError):
142 def __init__(self, errno, strerror, filename, desc):
142 def __init__(self, errno, strerror, filename, desc):
143 IOError.__init__(self, errno, strerror, filename)
143 IOError.__init__(self, errno, strerror, filename)
144 self.desc = desc
144 self.desc = desc
145
145
146 class LockHeld(LockError):
146 class LockHeld(LockError):
147 def __init__(self, errno, filename, desc, locker):
147 def __init__(self, errno, filename, desc, locker):
148 LockError.__init__(self, errno, 'Lock held', filename, desc)
148 LockError.__init__(self, errno, 'Lock held', filename, desc)
149 self.locker = locker
149 self.locker = locker
150
150
151 class LockUnavailable(LockError):
151 class LockUnavailable(LockError):
152 pass
152 pass
153
153
154 # LockError is for errors while acquiring the lock -- this is unrelated
154 # LockError is for errors while acquiring the lock -- this is unrelated
155 class LockInheritanceContractViolation(RuntimeError):
155 class LockInheritanceContractViolation(RuntimeError):
156 pass
156 pass
157
157
158 class ResponseError(Exception):
158 class ResponseError(Exception):
159 """Raised to print an error with part of output and exit."""
159 """Raised to print an error with part of output and exit."""
160
160
161 class UnknownCommand(Exception):
161 class UnknownCommand(Exception):
162 """Exception raised if command is not in the command table."""
162 """Exception raised if command is not in the command table."""
163
163
164 class AmbiguousCommand(Exception):
164 class AmbiguousCommand(Exception):
165 """Exception raised if command shortcut matches more than one command."""
165 """Exception raised if command shortcut matches more than one command."""
166
166
167 # derived from KeyboardInterrupt to simplify some breakout code
167 # derived from KeyboardInterrupt to simplify some breakout code
168 class SignalInterrupt(KeyboardInterrupt):
168 class SignalInterrupt(KeyboardInterrupt):
169 """Exception raised on SIGTERM and SIGHUP."""
169 """Exception raised on SIGTERM and SIGHUP."""
170
170
171 class SignatureError(Exception):
171 class SignatureError(Exception):
172 pass
172 pass
173
173
174 class PushRaced(RuntimeError):
174 class PushRaced(RuntimeError):
175 """An exception raised during unbundling that indicate a push race"""
175 """An exception raised during unbundling that indicate a push race"""
176
176
177 class ProgrammingError(RuntimeError):
177 class ProgrammingError(RuntimeError):
178 """Raised if a mercurial (core or extension) developer made a mistake"""
178 """Raised if a mercurial (core or extension) developer made a mistake"""
179
179
180 # bundle2 related errors
180 # bundle2 related errors
181 class BundleValueError(ValueError):
181 class BundleValueError(ValueError):
182 """error raised when bundle2 cannot be processed"""
182 """error raised when bundle2 cannot be processed"""
183
183
184 class BundleUnknownFeatureError(BundleValueError):
184 class BundleUnknownFeatureError(BundleValueError):
185 def __init__(self, parttype=None, params=(), values=()):
185 def __init__(self, parttype=None, params=(), values=()):
186 self.parttype = parttype
186 self.parttype = parttype
187 self.params = params
187 self.params = params
188 self.values = values
188 self.values = values
189 if self.parttype is None:
189 if self.parttype is None:
190 msg = 'Stream Parameter'
190 msg = 'Stream Parameter'
191 else:
191 else:
192 msg = parttype
192 msg = parttype
193 entries = self.params
193 entries = self.params
194 if self.params and self.values:
194 if self.params and self.values:
195 assert len(self.params) == len(self.values)
195 assert len(self.params) == len(self.values)
196 entries = []
196 entries = []
197 for idx, par in enumerate(self.params):
197 for idx, par in enumerate(self.params):
198 val = self.values[idx]
198 val = self.values[idx]
199 if val is None:
199 if val is None:
200 entries.append(val)
200 entries.append(val)
201 else:
201 else:
202 entries.append("%s=%r" % (par, val))
202 entries.append("%s=%r" % (par, val))
203 if entries:
203 if entries:
204 msg = '%s - %s' % (msg, ', '.join(entries))
204 msg = '%s - %s' % (msg, ', '.join(entries))
205 ValueError.__init__(self, msg)
205 ValueError.__init__(self, msg)
206
206
207 class ReadOnlyPartError(RuntimeError):
207 class ReadOnlyPartError(RuntimeError):
208 """error raised when code tries to alter a part being generated"""
208 """error raised when code tries to alter a part being generated"""
209
209
210 class PushkeyFailed(Abort):
210 class PushkeyFailed(Abort):
211 """error raised when a pushkey part failed to update a value"""
211 """error raised when a pushkey part failed to update a value"""
212
212
213 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
213 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
214 ret=None):
214 ret=None):
215 self.partid = partid
215 self.partid = partid
216 self.namespace = namespace
216 self.namespace = namespace
217 self.key = key
217 self.key = key
218 self.new = new
218 self.new = new
219 self.old = old
219 self.old = old
220 self.ret = ret
220 self.ret = ret
221 # no i18n expected to be processed into a better message
221 # no i18n expected to be processed into a better message
222 Abort.__init__(self, 'failed to update value for "%s/%s"'
222 Abort.__init__(self, 'failed to update value for "%s/%s"'
223 % (namespace, key))
223 % (namespace, key))
224
224
225 class CensoredNodeError(RevlogError):
225 class CensoredNodeError(RevlogError):
226 """error raised when content verification fails on a censored node
226 """error raised when content verification fails on a censored node
227
227
228 Also contains the tombstone data substituted for the uncensored data.
228 Also contains the tombstone data substituted for the uncensored data.
229 """
229 """
230
230
231 def __init__(self, filename, node, tombstone):
231 def __init__(self, filename, node, tombstone):
232 from .node import short
232 from .node import short
233 RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
233 RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
234 self.tombstone = tombstone
234 self.tombstone = tombstone
235
235
236 class CensoredBaseError(RevlogError):
236 class CensoredBaseError(RevlogError):
237 """error raised when a delta is rejected because its base is censored
237 """error raised when a delta is rejected because its base is censored
238
238
239 A delta based on a censored revision must be formed as single patch
239 A delta based on a censored revision must be formed as single patch
240 operation which replaces the entire base with new content. This ensures
240 operation which replaces the entire base with new content. This ensures
241 the delta may be applied by clones which have not censored the base.
241 the delta may be applied by clones which have not censored the base.
242 """
242 """
243
243
244 class InvalidBundleSpecification(Exception):
244 class InvalidBundleSpecification(Exception):
245 """error raised when a bundle specification is invalid.
245 """error raised when a bundle specification is invalid.
246
246
247 This is used for syntax errors as opposed to support errors.
247 This is used for syntax errors as opposed to support errors.
248 """
248 """
249
249
250 class UnsupportedBundleSpecification(Exception):
250 class UnsupportedBundleSpecification(Exception):
251 """error raised when a bundle specification is not supported."""
251 """error raised when a bundle specification is not supported."""
252
252
253 class CorruptedState(Exception):
253 class CorruptedState(Exception):
254 """error raised when a command is not able to read its state from file"""
254 """error raised when a command is not able to read its state from file"""
255
256 class RichIOError(Abort):
257 """An IOError that can also have a hint attached."""
@@ -1,383 +1,422
1 # httppeer.py - HTTP repository proxy classes for mercurial
1 # httppeer.py - HTTP repository proxy classes for mercurial
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import errno
11 import errno
12 import os
12 import os
13 import socket
13 import socket
14 import struct
14 import struct
15 import tempfile
15 import tempfile
16
16
17 from .i18n import _
17 from .i18n import _
18 from .node import nullid
18 from .node import nullid
19 from . import (
19 from . import (
20 bundle2,
20 bundle2,
21 error,
21 error,
22 httpconnection,
22 httpconnection,
23 pycompat,
23 pycompat,
24 statichttprepo,
24 statichttprepo,
25 url,
25 url,
26 util,
26 util,
27 wireproto,
27 wireproto,
28 )
28 )
29
29
30 httplib = util.httplib
30 httplib = util.httplib
31 urlerr = util.urlerr
31 urlerr = util.urlerr
32 urlreq = util.urlreq
32 urlreq = util.urlreq
33
33
34 # FUTURE: consider refactoring this API to use generators. This will
34 # FUTURE: consider refactoring this API to use generators. This will
35 # require a compression engine API to emit generators.
35 # require a compression engine API to emit generators.
36 def decompressresponse(response, engine):
36 def decompressresponse(response, engine):
37 try:
37 try:
38 reader = engine.decompressorreader(response)
38 reader = engine.decompressorreader(response)
39 except httplib.HTTPException:
39 except httplib.HTTPException:
40 raise IOError(None, _('connection ended unexpectedly'))
40 raise IOError(None, _('connection ended unexpectedly'))
41
41
42 # We need to wrap reader.read() so HTTPException on subsequent
42 # We need to wrap reader.read() so HTTPException on subsequent
43 # reads is also converted.
43 # reads is also converted.
44 # Ideally we'd use super() here. However, if ``reader`` isn't a new-style
44 # Ideally we'd use super() here. However, if ``reader`` isn't a new-style
45 # class, this can raise:
45 # class, this can raise:
46 # TypeError: super() argument 1 must be type, not classobj
46 # TypeError: super() argument 1 must be type, not classobj
47 origread = reader.read
47 origread = reader.read
48 class readerproxy(reader.__class__):
48 class readerproxy(reader.__class__):
49 def read(self, *args, **kwargs):
49 def read(self, *args, **kwargs):
50 try:
50 try:
51 return origread(*args, **kwargs)
51 return origread(*args, **kwargs)
52 except httplib.HTTPException:
52 except httplib.HTTPException:
53 raise IOError(None, _('connection ended unexpectedly'))
53 raise IOError(None, _('connection ended unexpectedly'))
54
54
55 reader.__class__ = readerproxy
55 reader.__class__ = readerproxy
56 return reader
56 return reader
57
57
58 def encodevalueinheaders(value, header, limit):
58 def encodevalueinheaders(value, header, limit):
59 """Encode a string value into multiple HTTP headers.
59 """Encode a string value into multiple HTTP headers.
60
60
61 ``value`` will be encoded into 1 or more HTTP headers with the names
61 ``value`` will be encoded into 1 or more HTTP headers with the names
62 ``header-<N>`` where ``<N>`` is an integer starting at 1. Each header
62 ``header-<N>`` where ``<N>`` is an integer starting at 1. Each header
63 name + value will be at most ``limit`` bytes long.
63 name + value will be at most ``limit`` bytes long.
64
64
65 Returns an iterable of 2-tuples consisting of header names and values.
65 Returns an iterable of 2-tuples consisting of header names and values.
66 """
66 """
67 fmt = header + '-%s'
67 fmt = header + '-%s'
68 valuelen = limit - len(fmt % '000') - len(': \r\n')
68 valuelen = limit - len(fmt % '000') - len(': \r\n')
69 result = []
69 result = []
70
70
71 n = 0
71 n = 0
72 for i in xrange(0, len(value), valuelen):
72 for i in xrange(0, len(value), valuelen):
73 n += 1
73 n += 1
74 result.append((fmt % str(n), value[i:i + valuelen]))
74 result.append((fmt % str(n), value[i:i + valuelen]))
75
75
76 return result
76 return result
77
77
78 def _wraphttpresponse(resp):
79 """Wrap an HTTPResponse with common error handlers.
80
81 This ensures that any I/O from any consumer raises the appropriate
82 error and messaging.
83 """
84 origread = resp.read
85
86 class readerproxy(resp.__class__):
87 def read(self, size=None):
88 try:
89 return origread(size)
90 except httplib.IncompleteRead as e:
91 # e.expected is an integer if length known or None otherwise.
92 if e.expected:
93 msg = _('HTTP request error (incomplete response; '
94 'expected %d bytes got %d)') % (e.expected,
95 len(e.partial))
96 else:
97 msg = _('HTTP request error (incomplete response)')
98
99 raise error.RichIOError(
100 msg,
101 hint=_('this may be an intermittent network failure; '
102 'if the error persists, consider contacting the '
103 'network or server operator'))
104 except httplib.HTTPException as e:
105 raise error.RichIOError(
106 _('HTTP request error (%s)') % e,
107 hint=_('this may be an intermittent failure; '
108 'if the error persists, consider contacting the '
109 'network or server operator'))
110
111 resp.__class__ = readerproxy
112
78 class httppeer(wireproto.wirepeer):
113 class httppeer(wireproto.wirepeer):
79 def __init__(self, ui, path):
114 def __init__(self, ui, path):
80 self.path = path
115 self.path = path
81 self.caps = None
116 self.caps = None
82 self.handler = None
117 self.handler = None
83 self.urlopener = None
118 self.urlopener = None
84 self.requestbuilder = None
119 self.requestbuilder = None
85 u = util.url(path)
120 u = util.url(path)
86 if u.query or u.fragment:
121 if u.query or u.fragment:
87 raise error.Abort(_('unsupported URL component: "%s"') %
122 raise error.Abort(_('unsupported URL component: "%s"') %
88 (u.query or u.fragment))
123 (u.query or u.fragment))
89
124
90 # urllib cannot handle URLs with embedded user or passwd
125 # urllib cannot handle URLs with embedded user or passwd
91 self._url, authinfo = u.authinfo()
126 self._url, authinfo = u.authinfo()
92
127
93 self.ui = ui
128 self.ui = ui
94 self.ui.debug('using %s\n' % self._url)
129 self.ui.debug('using %s\n' % self._url)
95
130
96 self.urlopener = url.opener(ui, authinfo)
131 self.urlopener = url.opener(ui, authinfo)
97 self.requestbuilder = urlreq.request
132 self.requestbuilder = urlreq.request
98
133
99 def __del__(self):
134 def __del__(self):
100 urlopener = getattr(self, 'urlopener', None)
135 urlopener = getattr(self, 'urlopener', None)
101 if urlopener:
136 if urlopener:
102 for h in urlopener.handlers:
137 for h in urlopener.handlers:
103 h.close()
138 h.close()
104 getattr(h, "close_all", lambda : None)()
139 getattr(h, "close_all", lambda : None)()
105
140
106 def url(self):
141 def url(self):
107 return self.path
142 return self.path
108
143
109 # look up capabilities only when needed
144 # look up capabilities only when needed
110
145
111 def _fetchcaps(self):
146 def _fetchcaps(self):
112 self.caps = set(self._call('capabilities').split())
147 self.caps = set(self._call('capabilities').split())
113
148
114 def _capabilities(self):
149 def _capabilities(self):
115 if self.caps is None:
150 if self.caps is None:
116 try:
151 try:
117 self._fetchcaps()
152 self._fetchcaps()
118 except error.RepoError:
153 except error.RepoError:
119 self.caps = set()
154 self.caps = set()
120 self.ui.debug('capabilities: %s\n' %
155 self.ui.debug('capabilities: %s\n' %
121 (' '.join(self.caps or ['none'])))
156 (' '.join(self.caps or ['none'])))
122 return self.caps
157 return self.caps
123
158
124 def lock(self):
159 def lock(self):
125 raise error.Abort(_('operation not supported over http'))
160 raise error.Abort(_('operation not supported over http'))
126
161
127 def _callstream(self, cmd, _compressible=False, **args):
162 def _callstream(self, cmd, _compressible=False, **args):
128 if cmd == 'pushkey':
163 if cmd == 'pushkey':
129 args['data'] = ''
164 args['data'] = ''
130 data = args.pop('data', None)
165 data = args.pop('data', None)
131 headers = args.pop('headers', {})
166 headers = args.pop('headers', {})
132
167
133 self.ui.debug("sending %s command\n" % cmd)
168 self.ui.debug("sending %s command\n" % cmd)
134 q = [('cmd', cmd)]
169 q = [('cmd', cmd)]
135 headersize = 0
170 headersize = 0
136 varyheaders = []
171 varyheaders = []
137 # Important: don't use self.capable() here or else you end up
172 # Important: don't use self.capable() here or else you end up
138 # with infinite recursion when trying to look up capabilities
173 # with infinite recursion when trying to look up capabilities
139 # for the first time.
174 # for the first time.
140 postargsok = self.caps is not None and 'httppostargs' in self.caps
175 postargsok = self.caps is not None and 'httppostargs' in self.caps
141 # TODO: support for httppostargs when data is a file-like
176 # TODO: support for httppostargs when data is a file-like
142 # object rather than a basestring
177 # object rather than a basestring
143 canmungedata = not data or isinstance(data, basestring)
178 canmungedata = not data or isinstance(data, basestring)
144 if postargsok and canmungedata:
179 if postargsok and canmungedata:
145 strargs = urlreq.urlencode(sorted(args.items()))
180 strargs = urlreq.urlencode(sorted(args.items()))
146 if strargs:
181 if strargs:
147 if not data:
182 if not data:
148 data = strargs
183 data = strargs
149 elif isinstance(data, basestring):
184 elif isinstance(data, basestring):
150 data = strargs + data
185 data = strargs + data
151 headers['X-HgArgs-Post'] = len(strargs)
186 headers['X-HgArgs-Post'] = len(strargs)
152 else:
187 else:
153 if len(args) > 0:
188 if len(args) > 0:
154 httpheader = self.capable('httpheader')
189 httpheader = self.capable('httpheader')
155 if httpheader:
190 if httpheader:
156 headersize = int(httpheader.split(',', 1)[0])
191 headersize = int(httpheader.split(',', 1)[0])
157 if headersize > 0:
192 if headersize > 0:
158 # The headers can typically carry more data than the URL.
193 # The headers can typically carry more data than the URL.
159 encargs = urlreq.urlencode(sorted(args.items()))
194 encargs = urlreq.urlencode(sorted(args.items()))
160 for header, value in encodevalueinheaders(encargs, 'X-HgArg',
195 for header, value in encodevalueinheaders(encargs, 'X-HgArg',
161 headersize):
196 headersize):
162 headers[header] = value
197 headers[header] = value
163 varyheaders.append(header)
198 varyheaders.append(header)
164 else:
199 else:
165 q += sorted(args.items())
200 q += sorted(args.items())
166 qs = '?%s' % urlreq.urlencode(q)
201 qs = '?%s' % urlreq.urlencode(q)
167 cu = "%s%s" % (self._url, qs)
202 cu = "%s%s" % (self._url, qs)
168 size = 0
203 size = 0
169 if util.safehasattr(data, 'length'):
204 if util.safehasattr(data, 'length'):
170 size = data.length
205 size = data.length
171 elif data is not None:
206 elif data is not None:
172 size = len(data)
207 size = len(data)
173 if size and self.ui.configbool('ui', 'usehttp2', False):
208 if size and self.ui.configbool('ui', 'usehttp2', False):
174 headers['Expect'] = '100-Continue'
209 headers['Expect'] = '100-Continue'
175 headers['X-HgHttp2'] = '1'
210 headers['X-HgHttp2'] = '1'
176 if data is not None and 'Content-Type' not in headers:
211 if data is not None and 'Content-Type' not in headers:
177 headers['Content-Type'] = 'application/mercurial-0.1'
212 headers['Content-Type'] = 'application/mercurial-0.1'
178
213
179 # Tell the server we accept application/mercurial-0.2 and multiple
214 # Tell the server we accept application/mercurial-0.2 and multiple
180 # compression formats if the server is capable of emitting those
215 # compression formats if the server is capable of emitting those
181 # payloads.
216 # payloads.
182 protoparams = []
217 protoparams = []
183
218
184 mediatypes = set()
219 mediatypes = set()
185 if self.caps is not None:
220 if self.caps is not None:
186 mt = self.capable('httpmediatype')
221 mt = self.capable('httpmediatype')
187 if mt:
222 if mt:
188 protoparams.append('0.1')
223 protoparams.append('0.1')
189 mediatypes = set(mt.split(','))
224 mediatypes = set(mt.split(','))
190
225
191 if '0.2tx' in mediatypes:
226 if '0.2tx' in mediatypes:
192 protoparams.append('0.2')
227 protoparams.append('0.2')
193
228
194 if '0.2tx' in mediatypes and self.capable('compression'):
229 if '0.2tx' in mediatypes and self.capable('compression'):
195 # We /could/ compare supported compression formats and prune
230 # We /could/ compare supported compression formats and prune
196 # non-mutually supported or error if nothing is mutually supported.
231 # non-mutually supported or error if nothing is mutually supported.
197 # For now, send the full list to the server and have it error.
232 # For now, send the full list to the server and have it error.
198 comps = [e.wireprotosupport().name for e in
233 comps = [e.wireprotosupport().name for e in
199 util.compengines.supportedwireengines(util.CLIENTROLE)]
234 util.compengines.supportedwireengines(util.CLIENTROLE)]
200 protoparams.append('comp=%s' % ','.join(comps))
235 protoparams.append('comp=%s' % ','.join(comps))
201
236
202 if protoparams:
237 if protoparams:
203 protoheaders = encodevalueinheaders(' '.join(protoparams),
238 protoheaders = encodevalueinheaders(' '.join(protoparams),
204 'X-HgProto',
239 'X-HgProto',
205 headersize or 1024)
240 headersize or 1024)
206 for header, value in protoheaders:
241 for header, value in protoheaders:
207 headers[header] = value
242 headers[header] = value
208 varyheaders.append(header)
243 varyheaders.append(header)
209
244
210 headers['Vary'] = ','.join(varyheaders)
245 headers['Vary'] = ','.join(varyheaders)
211 req = self.requestbuilder(cu, data, headers)
246 req = self.requestbuilder(cu, data, headers)
212
247
213 if data is not None:
248 if data is not None:
214 self.ui.debug("sending %s bytes\n" % size)
249 self.ui.debug("sending %s bytes\n" % size)
215 req.add_unredirected_header('Content-Length', '%d' % size)
250 req.add_unredirected_header('Content-Length', '%d' % size)
216 try:
251 try:
217 resp = self.urlopener.open(req)
252 resp = self.urlopener.open(req)
218 except urlerr.httperror as inst:
253 except urlerr.httperror as inst:
219 if inst.code == 401:
254 if inst.code == 401:
220 raise error.Abort(_('authorization failed'))
255 raise error.Abort(_('authorization failed'))
221 raise
256 raise
222 except httplib.HTTPException as inst:
257 except httplib.HTTPException as inst:
223 self.ui.debug('http error while sending %s command\n' % cmd)
258 self.ui.debug('http error while sending %s command\n' % cmd)
224 self.ui.traceback()
259 self.ui.traceback()
225 raise IOError(None, inst)
260 raise IOError(None, inst)
261
262 # Insert error handlers for common I/O failures.
263 _wraphttpresponse(resp)
264
226 # record the url we got redirected to
265 # record the url we got redirected to
227 resp_url = resp.geturl()
266 resp_url = resp.geturl()
228 if resp_url.endswith(qs):
267 if resp_url.endswith(qs):
229 resp_url = resp_url[:-len(qs)]
268 resp_url = resp_url[:-len(qs)]
230 if self._url.rstrip('/') != resp_url.rstrip('/'):
269 if self._url.rstrip('/') != resp_url.rstrip('/'):
231 if not self.ui.quiet:
270 if not self.ui.quiet:
232 self.ui.warn(_('real URL is %s\n') % resp_url)
271 self.ui.warn(_('real URL is %s\n') % resp_url)
233 self._url = resp_url
272 self._url = resp_url
234 try:
273 try:
235 proto = resp.getheader('content-type')
274 proto = resp.getheader('content-type')
236 except AttributeError:
275 except AttributeError:
237 proto = resp.headers.get('content-type', '')
276 proto = resp.headers.get('content-type', '')
238
277
239 safeurl = util.hidepassword(self._url)
278 safeurl = util.hidepassword(self._url)
240 if proto.startswith('application/hg-error'):
279 if proto.startswith('application/hg-error'):
241 raise error.OutOfBandError(resp.read())
280 raise error.OutOfBandError(resp.read())
242 # accept old "text/plain" and "application/hg-changegroup" for now
281 # accept old "text/plain" and "application/hg-changegroup" for now
243 if not (proto.startswith('application/mercurial-') or
282 if not (proto.startswith('application/mercurial-') or
244 (proto.startswith('text/plain')
283 (proto.startswith('text/plain')
245 and not resp.headers.get('content-length')) or
284 and not resp.headers.get('content-length')) or
246 proto.startswith('application/hg-changegroup')):
285 proto.startswith('application/hg-changegroup')):
247 self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu))
286 self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu))
248 raise error.RepoError(
287 raise error.RepoError(
249 _("'%s' does not appear to be an hg repository:\n"
288 _("'%s' does not appear to be an hg repository:\n"
250 "---%%<--- (%s)\n%s\n---%%<---\n")
289 "---%%<--- (%s)\n%s\n---%%<---\n")
251 % (safeurl, proto or 'no content-type', resp.read(1024)))
290 % (safeurl, proto or 'no content-type', resp.read(1024)))
252
291
253 if proto.startswith('application/mercurial-'):
292 if proto.startswith('application/mercurial-'):
254 try:
293 try:
255 version = proto.split('-', 1)[1]
294 version = proto.split('-', 1)[1]
256 version_info = tuple([int(n) for n in version.split('.')])
295 version_info = tuple([int(n) for n in version.split('.')])
257 except ValueError:
296 except ValueError:
258 raise error.RepoError(_("'%s' sent a broken Content-Type "
297 raise error.RepoError(_("'%s' sent a broken Content-Type "
259 "header (%s)") % (safeurl, proto))
298 "header (%s)") % (safeurl, proto))
260
299
261 if version_info == (0, 1):
300 if version_info == (0, 1):
262 if _compressible:
301 if _compressible:
263 return decompressresponse(resp, util.compengines['zlib'])
302 return decompressresponse(resp, util.compengines['zlib'])
264 return resp
303 return resp
265 elif version_info == (0, 2):
304 elif version_info == (0, 2):
266 # application/mercurial-0.2 always identifies the compression
305 # application/mercurial-0.2 always identifies the compression
267 # engine in the payload header.
306 # engine in the payload header.
268 elen = struct.unpack('B', resp.read(1))[0]
307 elen = struct.unpack('B', resp.read(1))[0]
269 ename = resp.read(elen)
308 ename = resp.read(elen)
270 engine = util.compengines.forwiretype(ename)
309 engine = util.compengines.forwiretype(ename)
271 return decompressresponse(resp, engine)
310 return decompressresponse(resp, engine)
272 else:
311 else:
273 raise error.RepoError(_("'%s' uses newer protocol %s") %
312 raise error.RepoError(_("'%s' uses newer protocol %s") %
274 (safeurl, version))
313 (safeurl, version))
275
314
276 if _compressible:
315 if _compressible:
277 return decompressresponse(resp, util.compengines['zlib'])
316 return decompressresponse(resp, util.compengines['zlib'])
278
317
279 return resp
318 return resp
280
319
281 def _call(self, cmd, **args):
320 def _call(self, cmd, **args):
282 fp = self._callstream(cmd, **args)
321 fp = self._callstream(cmd, **args)
283 try:
322 try:
284 return fp.read()
323 return fp.read()
285 finally:
324 finally:
286 # if using keepalive, allow connection to be reused
325 # if using keepalive, allow connection to be reused
287 fp.close()
326 fp.close()
288
327
289 def _callpush(self, cmd, cg, **args):
328 def _callpush(self, cmd, cg, **args):
290 # have to stream bundle to a temp file because we do not have
329 # have to stream bundle to a temp file because we do not have
291 # http 1.1 chunked transfer.
330 # http 1.1 chunked transfer.
292
331
293 types = self.capable('unbundle')
332 types = self.capable('unbundle')
294 try:
333 try:
295 types = types.split(',')
334 types = types.split(',')
296 except AttributeError:
335 except AttributeError:
297 # servers older than d1b16a746db6 will send 'unbundle' as a
336 # servers older than d1b16a746db6 will send 'unbundle' as a
298 # boolean capability. They only support headerless/uncompressed
337 # boolean capability. They only support headerless/uncompressed
299 # bundles.
338 # bundles.
300 types = [""]
339 types = [""]
301 for x in types:
340 for x in types:
302 if x in bundle2.bundletypes:
341 if x in bundle2.bundletypes:
303 type = x
342 type = x
304 break
343 break
305
344
306 tempname = bundle2.writebundle(self.ui, cg, None, type)
345 tempname = bundle2.writebundle(self.ui, cg, None, type)
307 fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
346 fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
308 headers = {'Content-Type': 'application/mercurial-0.1'}
347 headers = {'Content-Type': 'application/mercurial-0.1'}
309
348
310 try:
349 try:
311 r = self._call(cmd, data=fp, headers=headers, **args)
350 r = self._call(cmd, data=fp, headers=headers, **args)
312 vals = r.split('\n', 1)
351 vals = r.split('\n', 1)
313 if len(vals) < 2:
352 if len(vals) < 2:
314 raise error.ResponseError(_("unexpected response:"), r)
353 raise error.ResponseError(_("unexpected response:"), r)
315 return vals
354 return vals
316 except socket.error as err:
355 except socket.error as err:
317 if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
356 if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
318 raise error.Abort(_('push failed: %s') % err.args[1])
357 raise error.Abort(_('push failed: %s') % err.args[1])
319 raise error.Abort(err.args[1])
358 raise error.Abort(err.args[1])
320 finally:
359 finally:
321 fp.close()
360 fp.close()
322 os.unlink(tempname)
361 os.unlink(tempname)
323
362
324 def _calltwowaystream(self, cmd, fp, **args):
363 def _calltwowaystream(self, cmd, fp, **args):
325 fh = None
364 fh = None
326 fp_ = None
365 fp_ = None
327 filename = None
366 filename = None
328 try:
367 try:
329 # dump bundle to disk
368 # dump bundle to disk
330 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
369 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
331 fh = os.fdopen(fd, pycompat.sysstr("wb"))
370 fh = os.fdopen(fd, pycompat.sysstr("wb"))
332 d = fp.read(4096)
371 d = fp.read(4096)
333 while d:
372 while d:
334 fh.write(d)
373 fh.write(d)
335 d = fp.read(4096)
374 d = fp.read(4096)
336 fh.close()
375 fh.close()
337 # start http push
376 # start http push
338 fp_ = httpconnection.httpsendfile(self.ui, filename, "rb")
377 fp_ = httpconnection.httpsendfile(self.ui, filename, "rb")
339 headers = {'Content-Type': 'application/mercurial-0.1'}
378 headers = {'Content-Type': 'application/mercurial-0.1'}
340 return self._callstream(cmd, data=fp_, headers=headers, **args)
379 return self._callstream(cmd, data=fp_, headers=headers, **args)
341 finally:
380 finally:
342 if fp_ is not None:
381 if fp_ is not None:
343 fp_.close()
382 fp_.close()
344 if fh is not None:
383 if fh is not None:
345 fh.close()
384 fh.close()
346 os.unlink(filename)
385 os.unlink(filename)
347
386
348 def _callcompressable(self, cmd, **args):
387 def _callcompressable(self, cmd, **args):
349 return self._callstream(cmd, _compressible=True, **args)
388 return self._callstream(cmd, _compressible=True, **args)
350
389
351 def _abort(self, exception):
390 def _abort(self, exception):
352 raise exception
391 raise exception
353
392
354 class httpspeer(httppeer):
393 class httpspeer(httppeer):
355 def __init__(self, ui, path):
394 def __init__(self, ui, path):
356 if not url.has_https:
395 if not url.has_https:
357 raise error.Abort(_('Python support for SSL and HTTPS '
396 raise error.Abort(_('Python support for SSL and HTTPS '
358 'is not installed'))
397 'is not installed'))
359 httppeer.__init__(self, ui, path)
398 httppeer.__init__(self, ui, path)
360
399
361 def instance(ui, path, create):
400 def instance(ui, path, create):
362 if create:
401 if create:
363 raise error.Abort(_('cannot create new http repository'))
402 raise error.Abort(_('cannot create new http repository'))
364 try:
403 try:
365 if path.startswith('https:'):
404 if path.startswith('https:'):
366 inst = httpspeer(ui, path)
405 inst = httpspeer(ui, path)
367 else:
406 else:
368 inst = httppeer(ui, path)
407 inst = httppeer(ui, path)
369 try:
408 try:
370 # Try to do useful work when checking compatibility.
409 # Try to do useful work when checking compatibility.
371 # Usually saves a roundtrip since we want the caps anyway.
410 # Usually saves a roundtrip since we want the caps anyway.
372 inst._fetchcaps()
411 inst._fetchcaps()
373 except error.RepoError:
412 except error.RepoError:
374 # No luck, try older compatibility check.
413 # No luck, try older compatibility check.
375 inst.between([(nullid, nullid)])
414 inst.between([(nullid, nullid)])
376 return inst
415 return inst
377 except error.RepoError as httpexception:
416 except error.RepoError as httpexception:
378 try:
417 try:
379 r = statichttprepo.instance(ui, "static-" + path, create)
418 r = statichttprepo.instance(ui, "static-" + path, create)
380 ui.note(_('(falling back to static-http)\n'))
419 ui.note(_('(falling back to static-http)\n'))
381 return r
420 return r
382 except error.RepoError:
421 except error.RepoError:
383 raise httpexception # use the original http RepoError instead
422 raise httpexception # use the original http RepoError instead
@@ -1,896 +1,901
1 #require killdaemons serve zstd
1 #require killdaemons serve zstd
2
2
3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
4 version so behavior is deterministic.
4 version so behavior is deterministic.
5
5
6 $ cat > fakeversion.py << EOF
6 $ cat > fakeversion.py << EOF
7 > from mercurial import util
7 > from mercurial import util
8 > util.version = lambda: '4.2'
8 > util.version = lambda: '4.2'
9 > EOF
9 > EOF
10
10
11 $ cat >> $HGRCPATH << EOF
11 $ cat >> $HGRCPATH << EOF
12 > [extensions]
12 > [extensions]
13 > fakeversion = `pwd`/fakeversion.py
13 > fakeversion = `pwd`/fakeversion.py
14 > EOF
14 > EOF
15
15
16 $ hg init server0
16 $ hg init server0
17 $ cd server0
17 $ cd server0
18 $ touch foo
18 $ touch foo
19 $ hg -q commit -A -m initial
19 $ hg -q commit -A -m initial
20
20
21 Also disable compression because zstd is optional and causes output to vary
21 Also disable compression because zstd is optional and causes output to vary
22 and because debugging partial responses is hard when compression is involved
22 and because debugging partial responses is hard when compression is involved
23
23
24 $ cat > .hg/hgrc << EOF
24 $ cat > .hg/hgrc << EOF
25 > [extensions]
25 > [extensions]
26 > badserver = $TESTDIR/badserverext.py
26 > badserver = $TESTDIR/badserverext.py
27 > [server]
27 > [server]
28 > compressionengines = none
28 > compressionengines = none
29 > EOF
29 > EOF
30
30
31 Failure to accept() socket should result in connection related error message
31 Failure to accept() socket should result in connection related error message
32
32
33 $ hg --config badserver.closebeforeaccept=true serve -p $HGPORT -d --pid-file=hg.pid
33 $ hg --config badserver.closebeforeaccept=true serve -p $HGPORT -d --pid-file=hg.pid
34 $ cat hg.pid > $DAEMON_PIDS
34 $ cat hg.pid > $DAEMON_PIDS
35
35
36 $ hg clone http://localhost:$HGPORT/ clone
36 $ hg clone http://localhost:$HGPORT/ clone
37 abort: error: Connection reset by peer
37 abort: error: Connection reset by peer
38 [255]
38 [255]
39
39
40 (The server exits on its own, but there is a race between that and starting a new server.
40 (The server exits on its own, but there is a race between that and starting a new server.
41 So ensure the process is dead.)
41 So ensure the process is dead.)
42
42
43 $ killdaemons.py $DAEMON_PIDS
43 $ killdaemons.py $DAEMON_PIDS
44
44
45 Failure immediately after accept() should yield connection related error message
45 Failure immediately after accept() should yield connection related error message
46
46
47 $ hg --config badserver.closeafteraccept=true serve -p $HGPORT -d --pid-file=hg.pid
47 $ hg --config badserver.closeafteraccept=true serve -p $HGPORT -d --pid-file=hg.pid
48 $ cat hg.pid > $DAEMON_PIDS
48 $ cat hg.pid > $DAEMON_PIDS
49
49
50 $ hg clone http://localhost:$HGPORT/ clone
50 $ hg clone http://localhost:$HGPORT/ clone
51 abort: error: Connection reset by peer
51 abort: error: Connection reset by peer
52 [255]
52 [255]
53
53
54 $ killdaemons.py $DAEMON_PIDS
54 $ killdaemons.py $DAEMON_PIDS
55
55
56 Failure to read all bytes in initial HTTP request should yield connection related error message
56 Failure to read all bytes in initial HTTP request should yield connection related error message
57
57
58 $ hg --config badserver.closeafterrecvbytes=1 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
58 $ hg --config badserver.closeafterrecvbytes=1 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
59 $ cat hg.pid > $DAEMON_PIDS
59 $ cat hg.pid > $DAEMON_PIDS
60
60
61 TODO this error message is not very good
61 TODO this error message is not very good
62
62
63 $ hg clone http://localhost:$HGPORT/ clone
63 $ hg clone http://localhost:$HGPORT/ clone
64 abort: error: ''
64 abort: error: ''
65 [255]
65 [255]
66
66
67 $ killdaemons.py $DAEMON_PIDS
67 $ killdaemons.py $DAEMON_PIDS
68
68
69 $ cat error.log
69 $ cat error.log
70 readline(1 from 65537) -> (1) G
70 readline(1 from 65537) -> (1) G
71 read limit reached; closing socket
71 read limit reached; closing socket
72
72
73 $ rm -f error.log
73 $ rm -f error.log
74
74
75 Same failure, but server reads full HTTP request line
75 Same failure, but server reads full HTTP request line
76
76
77 $ hg --config badserver.closeafterrecvbytes=40 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
77 $ hg --config badserver.closeafterrecvbytes=40 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
78 $ cat hg.pid > $DAEMON_PIDS
78 $ cat hg.pid > $DAEMON_PIDS
79 $ hg clone http://localhost:$HGPORT/ clone
79 $ hg clone http://localhost:$HGPORT/ clone
80 abort: error: ''
80 abort: error: ''
81 [255]
81 [255]
82
82
83 $ killdaemons.py $DAEMON_PIDS
83 $ killdaemons.py $DAEMON_PIDS
84
84
85 $ cat error.log
85 $ cat error.log
86 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
86 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
87 readline(7 from -1) -> (7) Accept-
87 readline(7 from -1) -> (7) Accept-
88 read limit reached; closing socket
88 read limit reached; closing socket
89
89
90 $ rm -f error.log
90 $ rm -f error.log
91
91
92 Failure on subsequent HTTP request on the same socket (cmd?batch)
92 Failure on subsequent HTTP request on the same socket (cmd?batch)
93
93
94 $ hg --config badserver.closeafterrecvbytes=210 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
94 $ hg --config badserver.closeafterrecvbytes=210 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
95 $ cat hg.pid > $DAEMON_PIDS
95 $ cat hg.pid > $DAEMON_PIDS
96 $ hg clone http://localhost:$HGPORT/ clone
96 $ hg clone http://localhost:$HGPORT/ clone
97 abort: error: ''
97 abort: error: ''
98 [255]
98 [255]
99
99
100 $ killdaemons.py $DAEMON_PIDS
100 $ killdaemons.py $DAEMON_PIDS
101
101
102 $ cat error.log
102 $ cat error.log
103 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
103 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
104 readline(177 from -1) -> (27) Accept-Encoding: identity\r\n
104 readline(177 from -1) -> (27) Accept-Encoding: identity\r\n
105 readline(150 from -1) -> (8) vary: \r\n
105 readline(150 from -1) -> (8) vary: \r\n
106 readline(142 from -1) -> (35) accept: application/mercurial-0.1\r\n
106 readline(142 from -1) -> (35) accept: application/mercurial-0.1\r\n
107 readline(107 from -1) -> (23) host: localhost:$HGPORT\r\n
107 readline(107 from -1) -> (23) host: localhost:$HGPORT\r\n
108 readline(84 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
108 readline(84 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
109 readline(35 from -1) -> (2) \r\n
109 readline(35 from -1) -> (2) \r\n
110 write(36) -> HTTP/1.1 200 Script output follows\r\n
110 write(36) -> HTTP/1.1 200 Script output follows\r\n
111 write(23) -> Server: badhttpserver\r\n
111 write(23) -> Server: badhttpserver\r\n
112 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
112 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
113 write(41) -> Content-Type: application/mercurial-0.1\r\n
113 write(41) -> Content-Type: application/mercurial-0.1\r\n
114 write(21) -> Content-Length: 405\r\n
114 write(21) -> Content-Length: 405\r\n
115 write(2) -> \r\n
115 write(2) -> \r\n
116 write(405) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
116 write(405) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
117 readline(33 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
117 readline(33 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
118 readline(7 from -1) -> (7) Accept-
118 readline(7 from -1) -> (7) Accept-
119 read limit reached; closing socket
119 read limit reached; closing socket
120 readline(210 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
120 readline(210 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
121 readline(184 from -1) -> (27) Accept-Encoding: identity\r\n
121 readline(184 from -1) -> (27) Accept-Encoding: identity\r\n
122 readline(157 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
122 readline(157 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
123 readline(128 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
123 readline(128 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
124 readline(87 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
124 readline(87 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
125 readline(39 from -1) -> (35) accept: application/mercurial-0.1\r\n
125 readline(39 from -1) -> (35) accept: application/mercurial-0.1\r\n
126 readline(4 from -1) -> (4) host
126 readline(4 from -1) -> (4) host
127 read limit reached; closing socket
127 read limit reached; closing socket
128
128
129 $ rm -f error.log
129 $ rm -f error.log
130
130
131 Failure to read getbundle HTTP request
131 Failure to read getbundle HTTP request
132
132
133 $ hg --config badserver.closeafterrecvbytes=300 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
133 $ hg --config badserver.closeafterrecvbytes=300 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
134 $ cat hg.pid > $DAEMON_PIDS
134 $ cat hg.pid > $DAEMON_PIDS
135 $ hg clone http://localhost:$HGPORT/ clone
135 $ hg clone http://localhost:$HGPORT/ clone
136 requesting all changes
136 requesting all changes
137 abort: error: ''
137 abort: error: ''
138 [255]
138 [255]
139
139
140 $ killdaemons.py $DAEMON_PIDS
140 $ killdaemons.py $DAEMON_PIDS
141
141
142 $ cat error.log
142 $ cat error.log
143 readline(300 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
143 readline(300 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
144 readline(267 from -1) -> (27) Accept-Encoding: identity\r\n
144 readline(267 from -1) -> (27) Accept-Encoding: identity\r\n
145 readline(240 from -1) -> (8) vary: \r\n
145 readline(240 from -1) -> (8) vary: \r\n
146 readline(232 from -1) -> (35) accept: application/mercurial-0.1\r\n
146 readline(232 from -1) -> (35) accept: application/mercurial-0.1\r\n
147 readline(197 from -1) -> (23) host: localhost:$HGPORT\r\n
147 readline(197 from -1) -> (23) host: localhost:$HGPORT\r\n
148 readline(174 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
148 readline(174 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
149 readline(125 from -1) -> (2) \r\n
149 readline(125 from -1) -> (2) \r\n
150 write(36) -> HTTP/1.1 200 Script output follows\r\n
150 write(36) -> HTTP/1.1 200 Script output follows\r\n
151 write(23) -> Server: badhttpserver\r\n
151 write(23) -> Server: badhttpserver\r\n
152 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
152 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
153 write(41) -> Content-Type: application/mercurial-0.1\r\n
153 write(41) -> Content-Type: application/mercurial-0.1\r\n
154 write(21) -> Content-Length: 405\r\n
154 write(21) -> Content-Length: 405\r\n
155 write(2) -> \r\n
155 write(2) -> \r\n
156 write(405) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
156 write(405) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
157 readline(123 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
157 readline(123 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
158 readline(97 from -1) -> (27) Accept-Encoding: identity\r\n
158 readline(97 from -1) -> (27) Accept-Encoding: identity\r\n
159 readline(70 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
159 readline(70 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
160 readline(41 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
160 readline(41 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
161 read limit reached; closing socket
161 read limit reached; closing socket
162 readline(300 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
162 readline(300 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
163 readline(274 from -1) -> (27) Accept-Encoding: identity\r\n
163 readline(274 from -1) -> (27) Accept-Encoding: identity\r\n
164 readline(247 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
164 readline(247 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
165 readline(218 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
165 readline(218 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
166 readline(177 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
166 readline(177 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
167 readline(129 from -1) -> (35) accept: application/mercurial-0.1\r\n
167 readline(129 from -1) -> (35) accept: application/mercurial-0.1\r\n
168 readline(94 from -1) -> (23) host: localhost:$HGPORT\r\n
168 readline(94 from -1) -> (23) host: localhost:$HGPORT\r\n
169 readline(71 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
169 readline(71 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
170 readline(22 from -1) -> (2) \r\n
170 readline(22 from -1) -> (2) \r\n
171 write(36) -> HTTP/1.1 200 Script output follows\r\n
171 write(36) -> HTTP/1.1 200 Script output follows\r\n
172 write(23) -> Server: badhttpserver\r\n
172 write(23) -> Server: badhttpserver\r\n
173 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
173 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
174 write(41) -> Content-Type: application/mercurial-0.1\r\n
174 write(41) -> Content-Type: application/mercurial-0.1\r\n
175 write(20) -> Content-Length: 42\r\n
175 write(20) -> Content-Length: 42\r\n
176 write(2) -> \r\n
176 write(2) -> \r\n
177 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
177 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
178 readline(20 from 65537) -> (20) GET /?cmd=getbundle
178 readline(20 from 65537) -> (20) GET /?cmd=getbundle
179 read limit reached; closing socket
179 read limit reached; closing socket
180 readline(300 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
180 readline(300 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
181 readline(270 from -1) -> (27) Accept-Encoding: identity\r\n
181 readline(270 from -1) -> (27) Accept-Encoding: identity\r\n
182 readline(243 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
182 readline(243 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
183 readline(214 from -1) -> (214) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%2
183 readline(214 from -1) -> (214) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%2
184 read limit reached; closing socket
184 read limit reached; closing socket
185
185
186 $ rm -f error.log
186 $ rm -f error.log
187
187
188 Now do a variation using POST to send arguments
188 Now do a variation using POST to send arguments
189
189
190 $ hg --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=315 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
190 $ hg --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=315 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
191 $ cat hg.pid > $DAEMON_PIDS
191 $ cat hg.pid > $DAEMON_PIDS
192
192
193 $ hg clone http://localhost:$HGPORT/ clone
193 $ hg clone http://localhost:$HGPORT/ clone
194 abort: error: ''
194 abort: error: ''
195 [255]
195 [255]
196
196
197 $ killdaemons.py $DAEMON_PIDS
197 $ killdaemons.py $DAEMON_PIDS
198
198
199 $ cat error.log
199 $ cat error.log
200 readline(315 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
200 readline(315 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
201 readline(282 from -1) -> (27) Accept-Encoding: identity\r\n
201 readline(282 from -1) -> (27) Accept-Encoding: identity\r\n
202 readline(255 from -1) -> (8) vary: \r\n
202 readline(255 from -1) -> (8) vary: \r\n
203 readline(247 from -1) -> (35) accept: application/mercurial-0.1\r\n
203 readline(247 from -1) -> (35) accept: application/mercurial-0.1\r\n
204 readline(212 from -1) -> (23) host: localhost:$HGPORT\r\n
204 readline(212 from -1) -> (23) host: localhost:$HGPORT\r\n
205 readline(189 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
205 readline(189 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
206 readline(140 from -1) -> (2) \r\n
206 readline(140 from -1) -> (2) \r\n
207 write(36) -> HTTP/1.1 200 Script output follows\r\n
207 write(36) -> HTTP/1.1 200 Script output follows\r\n
208 write(23) -> Server: badhttpserver\r\n
208 write(23) -> Server: badhttpserver\r\n
209 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
209 write(37) -> Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
210 write(41) -> Content-Type: application/mercurial-0.1\r\n
210 write(41) -> Content-Type: application/mercurial-0.1\r\n
211 write(21) -> Content-Length: 418\r\n
211 write(21) -> Content-Length: 418\r\n
212 write(2) -> \r\n
212 write(2) -> \r\n
213 write(418) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httppostargs httpmediatype=0.1rx,0.1tx,0.2tx compression=none
213 write(418) -> lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httppostargs httpmediatype=0.1rx,0.1tx,0.2tx compression=none
214 readline(138 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
214 readline(138 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
215 readline(111 from -1) -> (27) Accept-Encoding: identity\r\n
215 readline(111 from -1) -> (27) Accept-Encoding: identity\r\n
216 readline(84 from -1) -> (41) content-type: application/mercurial-0.1\r\n
216 readline(84 from -1) -> (41) content-type: application/mercurial-0.1\r\n
217 readline(43 from -1) -> (19) vary: X-HgProto-1\r\n
217 readline(43 from -1) -> (19) vary: X-HgProto-1\r\n
218 readline(24 from -1) -> (19) x-hgargs-post: 28\r\n
218 readline(24 from -1) -> (19) x-hgargs-post: 28\r\n
219 readline(5 from -1) -> (5) x-hgp
219 readline(5 from -1) -> (5) x-hgp
220 read limit reached; closing socket
220 read limit reached; closing socket
221 readline(315 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
221 readline(315 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
222 readline(288 from -1) -> (27) Accept-Encoding: identity\r\n
222 readline(288 from -1) -> (27) Accept-Encoding: identity\r\n
223 readline(261 from -1) -> (41) content-type: application/mercurial-0.1\r\n
223 readline(261 from -1) -> (41) content-type: application/mercurial-0.1\r\n
224 readline(220 from -1) -> (19) vary: X-HgProto-1\r\n
224 readline(220 from -1) -> (19) vary: X-HgProto-1\r\n
225 readline(201 from -1) -> (19) x-hgargs-post: 28\r\n
225 readline(201 from -1) -> (19) x-hgargs-post: 28\r\n
226 readline(182 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
226 readline(182 from -1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
227 readline(134 from -1) -> (35) accept: application/mercurial-0.1\r\n
227 readline(134 from -1) -> (35) accept: application/mercurial-0.1\r\n
228 readline(99 from -1) -> (20) content-length: 28\r\n
228 readline(99 from -1) -> (20) content-length: 28\r\n
229 readline(79 from -1) -> (23) host: localhost:$HGPORT\r\n
229 readline(79 from -1) -> (23) host: localhost:$HGPORT\r\n
230 readline(56 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
230 readline(56 from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
231 readline(7 from -1) -> (2) \r\n
231 readline(7 from -1) -> (2) \r\n
232 read(5 from 28) -> (5) cmds=
232 read(5 from 28) -> (5) cmds=
233 read limit reached, closing socket
233 read limit reached, closing socket
234 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
234 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
235
235
236 $ rm -f error.log
236 $ rm -f error.log
237
237
238 Now move on to partial server responses
238 Now move on to partial server responses
239
239
240 Server sends a single character from the HTTP response line
240 Server sends a single character from the HTTP response line
241
241
242 $ hg --config badserver.closeaftersendbytes=1 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
242 $ hg --config badserver.closeaftersendbytes=1 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
243 $ cat hg.pid > $DAEMON_PIDS
243 $ cat hg.pid > $DAEMON_PIDS
244
244
245 $ hg clone http://localhost:$HGPORT/ clone
245 $ hg clone http://localhost:$HGPORT/ clone
246 abort: error: H
246 abort: error: H
247 [255]
247 [255]
248
248
249 $ killdaemons.py $DAEMON_PIDS
249 $ killdaemons.py $DAEMON_PIDS
250
250
251 $ cat error.log
251 $ cat error.log
252 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
252 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
253 readline(-1) -> (27) Accept-Encoding: identity\r\n
253 readline(-1) -> (27) Accept-Encoding: identity\r\n
254 readline(-1) -> (8) vary: \r\n
254 readline(-1) -> (8) vary: \r\n
255 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
255 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
256 readline(-1) -> (23) host: localhost:$HGPORT\r\n
256 readline(-1) -> (23) host: localhost:$HGPORT\r\n
257 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
257 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
258 readline(-1) -> (2) \r\n
258 readline(-1) -> (2) \r\n
259 write(1 from 36) -> (0) H
259 write(1 from 36) -> (0) H
260 write limit reached; closing socket
260 write limit reached; closing socket
261 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
261 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
262
262
263 $ rm -f error.log
263 $ rm -f error.log
264
264
265 Server sends an incomplete capabilities response body
265 Server sends an incomplete capabilities response body
266
266
267 $ hg --config badserver.closeaftersendbytes=180 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
267 $ hg --config badserver.closeaftersendbytes=180 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
268 $ cat hg.pid > $DAEMON_PIDS
268 $ cat hg.pid > $DAEMON_PIDS
269
269
270 TODO client spews a stack due to uncaught httplib.IncompleteRead
270 $ hg clone http://localhost:$HGPORT/ clone
271
271 abort: HTTP request error (incomplete response; expected 385 bytes got 20)
272 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
272 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
273 [1]
273 [255]
274
274
275 $ killdaemons.py $DAEMON_PIDS
275 $ killdaemons.py $DAEMON_PIDS
276
276
277 $ cat error.log
277 $ cat error.log
278 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
278 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
279 readline(-1) -> (27) Accept-Encoding: identity\r\n
279 readline(-1) -> (27) Accept-Encoding: identity\r\n
280 readline(-1) -> (8) vary: \r\n
280 readline(-1) -> (8) vary: \r\n
281 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
281 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
282 readline(-1) -> (23) host: localhost:$HGPORT\r\n
282 readline(-1) -> (23) host: localhost:$HGPORT\r\n
283 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
283 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
284 readline(-1) -> (2) \r\n
284 readline(-1) -> (2) \r\n
285 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n
285 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n
286 write(23 from 23) -> (121) Server: badhttpserver\r\n
286 write(23 from 23) -> (121) Server: badhttpserver\r\n
287 write(37 from 37) -> (84) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
287 write(37 from 37) -> (84) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
288 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n
288 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n
289 write(21 from 21) -> (22) Content-Length: 405\r\n
289 write(21 from 21) -> (22) Content-Length: 405\r\n
290 write(2 from 2) -> (20) \r\n
290 write(2 from 2) -> (20) \r\n
291 write(20 from 405) -> (0) lookup changegroupsu
291 write(20 from 405) -> (0) lookup changegroupsu
292 write limit reached; closing socket
292 write limit reached; closing socket
293
293
294 $ rm -f error.log
294 $ rm -f error.log
295
295
296 Server sends incomplete headers for batch request
296 Server sends incomplete headers for batch request
297
297
298 $ hg --config badserver.closeaftersendbytes=695 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
298 $ hg --config badserver.closeaftersendbytes=695 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
299 $ cat hg.pid > $DAEMON_PIDS
299 $ cat hg.pid > $DAEMON_PIDS
300
300
301 TODO this output is horrible
301 TODO this output is horrible
302
302
303 $ hg clone http://localhost:$HGPORT/ clone
303 $ hg clone http://localhost:$HGPORT/ clone
304 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
304 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
305 ---%<--- (application/mercuria)
305 ---%<--- (application/mercuria)
306
306
307 ---%<---
307 ---%<---
308 !
308 !
309 [255]
309 [255]
310
310
311 $ killdaemons.py $DAEMON_PIDS
311 $ killdaemons.py $DAEMON_PIDS
312
312
313 $ cat error.log
313 $ cat error.log
314 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
314 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
315 readline(-1) -> (27) Accept-Encoding: identity\r\n
315 readline(-1) -> (27) Accept-Encoding: identity\r\n
316 readline(-1) -> (8) vary: \r\n
316 readline(-1) -> (8) vary: \r\n
317 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
317 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
318 readline(-1) -> (23) host: localhost:$HGPORT\r\n
318 readline(-1) -> (23) host: localhost:$HGPORT\r\n
319 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
319 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
320 readline(-1) -> (2) \r\n
320 readline(-1) -> (2) \r\n
321 write(36 from 36) -> (659) HTTP/1.1 200 Script output follows\r\n
321 write(36 from 36) -> (659) HTTP/1.1 200 Script output follows\r\n
322 write(23 from 23) -> (636) Server: badhttpserver\r\n
322 write(23 from 23) -> (636) Server: badhttpserver\r\n
323 write(37 from 37) -> (599) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
323 write(37 from 37) -> (599) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
324 write(41 from 41) -> (558) Content-Type: application/mercurial-0.1\r\n
324 write(41 from 41) -> (558) Content-Type: application/mercurial-0.1\r\n
325 write(21 from 21) -> (537) Content-Length: 405\r\n
325 write(21 from 21) -> (537) Content-Length: 405\r\n
326 write(2 from 2) -> (535) \r\n
326 write(2 from 2) -> (535) \r\n
327 write(405 from 405) -> (130) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
327 write(405 from 405) -> (130) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
328 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
328 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
329 readline(-1) -> (27) Accept-Encoding: identity\r\n
329 readline(-1) -> (27) Accept-Encoding: identity\r\n
330 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
330 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
331 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
331 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
332 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
332 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
333 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
333 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
334 readline(-1) -> (23) host: localhost:$HGPORT\r\n
334 readline(-1) -> (23) host: localhost:$HGPORT\r\n
335 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
335 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
336 readline(-1) -> (2) \r\n
336 readline(-1) -> (2) \r\n
337 write(36 from 36) -> (94) HTTP/1.1 200 Script output follows\r\n
337 write(36 from 36) -> (94) HTTP/1.1 200 Script output follows\r\n
338 write(23 from 23) -> (71) Server: badhttpserver\r\n
338 write(23 from 23) -> (71) Server: badhttpserver\r\n
339 write(37 from 37) -> (34) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
339 write(37 from 37) -> (34) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
340 write(34 from 41) -> (0) Content-Type: application/mercuria
340 write(34 from 41) -> (0) Content-Type: application/mercuria
341 write limit reached; closing socket
341 write limit reached; closing socket
342 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
342 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
343
343
344 $ rm -f error.log
344 $ rm -f error.log
345
345
346 Server sends an incomplete HTTP response body to batch request
346 Server sends an incomplete HTTP response body to batch request
347
347
348 $ hg --config badserver.closeaftersendbytes=760 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
348 $ hg --config badserver.closeaftersendbytes=760 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
349 $ cat hg.pid > $DAEMON_PIDS
349 $ cat hg.pid > $DAEMON_PIDS
350
350
351 TODO client spews a stack due to uncaught ValueError in batch.results()
351 TODO client spews a stack due to uncaught ValueError in batch.results()
352 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
352 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
353 [1]
353 [1]
354
354
355 $ killdaemons.py $DAEMON_PIDS
355 $ killdaemons.py $DAEMON_PIDS
356
356
357 $ cat error.log
357 $ cat error.log
358 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
358 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
359 readline(-1) -> (27) Accept-Encoding: identity\r\n
359 readline(-1) -> (27) Accept-Encoding: identity\r\n
360 readline(-1) -> (8) vary: \r\n
360 readline(-1) -> (8) vary: \r\n
361 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
361 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
362 readline(-1) -> (23) host: localhost:$HGPORT\r\n
362 readline(-1) -> (23) host: localhost:$HGPORT\r\n
363 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
363 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
364 readline(-1) -> (2) \r\n
364 readline(-1) -> (2) \r\n
365 write(36 from 36) -> (724) HTTP/1.1 200 Script output follows\r\n
365 write(36 from 36) -> (724) HTTP/1.1 200 Script output follows\r\n
366 write(23 from 23) -> (701) Server: badhttpserver\r\n
366 write(23 from 23) -> (701) Server: badhttpserver\r\n
367 write(37 from 37) -> (664) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
367 write(37 from 37) -> (664) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
368 write(41 from 41) -> (623) Content-Type: application/mercurial-0.1\r\n
368 write(41 from 41) -> (623) Content-Type: application/mercurial-0.1\r\n
369 write(21 from 21) -> (602) Content-Length: 405\r\n
369 write(21 from 21) -> (602) Content-Length: 405\r\n
370 write(2 from 2) -> (600) \r\n
370 write(2 from 2) -> (600) \r\n
371 write(405 from 405) -> (195) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
371 write(405 from 405) -> (195) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
372 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
372 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
373 readline(-1) -> (27) Accept-Encoding: identity\r\n
373 readline(-1) -> (27) Accept-Encoding: identity\r\n
374 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
374 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
375 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
375 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
376 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
376 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
377 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
377 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
378 readline(-1) -> (23) host: localhost:$HGPORT\r\n
378 readline(-1) -> (23) host: localhost:$HGPORT\r\n
379 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
379 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
380 readline(-1) -> (2) \r\n
380 readline(-1) -> (2) \r\n
381 write(36 from 36) -> (159) HTTP/1.1 200 Script output follows\r\n
381 write(36 from 36) -> (159) HTTP/1.1 200 Script output follows\r\n
382 write(23 from 23) -> (136) Server: badhttpserver\r\n
382 write(23 from 23) -> (136) Server: badhttpserver\r\n
383 write(37 from 37) -> (99) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
383 write(37 from 37) -> (99) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
384 write(41 from 41) -> (58) Content-Type: application/mercurial-0.1\r\n
384 write(41 from 41) -> (58) Content-Type: application/mercurial-0.1\r\n
385 write(20 from 20) -> (38) Content-Length: 42\r\n
385 write(20 from 20) -> (38) Content-Length: 42\r\n
386 write(2 from 2) -> (36) \r\n
386 write(2 from 2) -> (36) \r\n
387 write(36 from 42) -> (0) 96ee1d7354c4ad7372047672c36a1f561e3a
387 write(36 from 42) -> (0) 96ee1d7354c4ad7372047672c36a1f561e3a
388 write limit reached; closing socket
388 write limit reached; closing socket
389
389
390 $ rm -f error.log
390 $ rm -f error.log
391
391
392 Server sends incomplete headers for getbundle response
392 Server sends incomplete headers for getbundle response
393
393
394 $ hg --config badserver.closeaftersendbytes=895 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
394 $ hg --config badserver.closeaftersendbytes=895 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
395 $ cat hg.pid > $DAEMON_PIDS
395 $ cat hg.pid > $DAEMON_PIDS
396
396
397 TODO this output is terrible
397 TODO this output is terrible
398
398
399 $ hg clone http://localhost:$HGPORT/ clone
399 $ hg clone http://localhost:$HGPORT/ clone
400 requesting all changes
400 requesting all changes
401 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
401 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
402 ---%<--- (application/mercuri)
402 ---%<--- (application/mercuri)
403
403
404 ---%<---
404 ---%<---
405 !
405 !
406 [255]
406 [255]
407
407
408 $ killdaemons.py $DAEMON_PIDS
408 $ killdaemons.py $DAEMON_PIDS
409
409
410 $ cat error.log
410 $ cat error.log
411 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
411 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
412 readline(-1) -> (27) Accept-Encoding: identity\r\n
412 readline(-1) -> (27) Accept-Encoding: identity\r\n
413 readline(-1) -> (8) vary: \r\n
413 readline(-1) -> (8) vary: \r\n
414 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
414 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
415 readline(-1) -> (23) host: localhost:$HGPORT\r\n
415 readline(-1) -> (23) host: localhost:$HGPORT\r\n
416 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
416 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
417 readline(-1) -> (2) \r\n
417 readline(-1) -> (2) \r\n
418 write(36 from 36) -> (859) HTTP/1.1 200 Script output follows\r\n
418 write(36 from 36) -> (859) HTTP/1.1 200 Script output follows\r\n
419 write(23 from 23) -> (836) Server: badhttpserver\r\n
419 write(23 from 23) -> (836) Server: badhttpserver\r\n
420 write(37 from 37) -> (799) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
420 write(37 from 37) -> (799) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
421 write(41 from 41) -> (758) Content-Type: application/mercurial-0.1\r\n
421 write(41 from 41) -> (758) Content-Type: application/mercurial-0.1\r\n
422 write(21 from 21) -> (737) Content-Length: 405\r\n
422 write(21 from 21) -> (737) Content-Length: 405\r\n
423 write(2 from 2) -> (735) \r\n
423 write(2 from 2) -> (735) \r\n
424 write(405 from 405) -> (330) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
424 write(405 from 405) -> (330) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
425 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
425 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
426 readline(-1) -> (27) Accept-Encoding: identity\r\n
426 readline(-1) -> (27) Accept-Encoding: identity\r\n
427 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
427 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
428 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
428 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
429 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
429 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
430 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
430 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
431 readline(-1) -> (23) host: localhost:$HGPORT\r\n
431 readline(-1) -> (23) host: localhost:$HGPORT\r\n
432 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
432 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
433 readline(-1) -> (2) \r\n
433 readline(-1) -> (2) \r\n
434 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n
434 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n
435 write(23 from 23) -> (271) Server: badhttpserver\r\n
435 write(23 from 23) -> (271) Server: badhttpserver\r\n
436 write(37 from 37) -> (234) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
436 write(37 from 37) -> (234) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
437 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n
437 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n
438 write(20 from 20) -> (173) Content-Length: 42\r\n
438 write(20 from 20) -> (173) Content-Length: 42\r\n
439 write(2 from 2) -> (171) \r\n
439 write(2 from 2) -> (171) \r\n
440 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
440 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
441 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
441 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
442 readline(-1) -> (27) Accept-Encoding: identity\r\n
442 readline(-1) -> (27) Accept-Encoding: identity\r\n
443 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
443 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
444 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
444 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
445 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
445 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
446 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
446 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
447 readline(-1) -> (23) host: localhost:$HGPORT\r\n
447 readline(-1) -> (23) host: localhost:$HGPORT\r\n
448 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
448 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
449 readline(-1) -> (2) \r\n
449 readline(-1) -> (2) \r\n
450 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n
450 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n
451 write(23 from 23) -> (70) Server: badhttpserver\r\n
451 write(23 from 23) -> (70) Server: badhttpserver\r\n
452 write(37 from 37) -> (33) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
452 write(37 from 37) -> (33) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
453 write(33 from 41) -> (0) Content-Type: application/mercuri
453 write(33 from 41) -> (0) Content-Type: application/mercuri
454 write limit reached; closing socket
454 write limit reached; closing socket
455 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
455 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
456
456
457 $ rm -f error.log
457 $ rm -f error.log
458
458
459 Server sends empty HTTP body for getbundle
459 Server sends empty HTTP body for getbundle
460
460
461 $ hg --config badserver.closeaftersendbytes=933 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
461 $ hg --config badserver.closeaftersendbytes=933 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
462 $ cat hg.pid > $DAEMON_PIDS
462 $ cat hg.pid > $DAEMON_PIDS
463
463
464 TODO client spews a stack due to uncaught httplib.IncompleteRead
464 $ hg clone http://localhost:$HGPORT/ clone
465
466 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
467 requesting all changes
465 requesting all changes
468 [1]
466 abort: HTTP request error (incomplete response)
467 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
468 [255]
469
469
470 $ killdaemons.py $DAEMON_PIDS
470 $ killdaemons.py $DAEMON_PIDS
471
471
472 $ cat error.log
472 $ cat error.log
473 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
473 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
474 readline(-1) -> (27) Accept-Encoding: identity\r\n
474 readline(-1) -> (27) Accept-Encoding: identity\r\n
475 readline(-1) -> (8) vary: \r\n
475 readline(-1) -> (8) vary: \r\n
476 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
476 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
477 readline(-1) -> (23) host: localhost:$HGPORT\r\n
477 readline(-1) -> (23) host: localhost:$HGPORT\r\n
478 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
478 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
479 readline(-1) -> (2) \r\n
479 readline(-1) -> (2) \r\n
480 write(36 from 36) -> (897) HTTP/1.1 200 Script output follows\r\n
480 write(36 from 36) -> (897) HTTP/1.1 200 Script output follows\r\n
481 write(23 from 23) -> (874) Server: badhttpserver\r\n
481 write(23 from 23) -> (874) Server: badhttpserver\r\n
482 write(37 from 37) -> (837) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
482 write(37 from 37) -> (837) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
483 write(41 from 41) -> (796) Content-Type: application/mercurial-0.1\r\n
483 write(41 from 41) -> (796) Content-Type: application/mercurial-0.1\r\n
484 write(21 from 21) -> (775) Content-Length: 405\r\n
484 write(21 from 21) -> (775) Content-Length: 405\r\n
485 write(2 from 2) -> (773) \r\n
485 write(2 from 2) -> (773) \r\n
486 write(405 from 405) -> (368) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
486 write(405 from 405) -> (368) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
487 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
487 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
488 readline(-1) -> (27) Accept-Encoding: identity\r\n
488 readline(-1) -> (27) Accept-Encoding: identity\r\n
489 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
489 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
490 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
490 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
491 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
491 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
492 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
492 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
493 readline(-1) -> (23) host: localhost:$HGPORT\r\n
493 readline(-1) -> (23) host: localhost:$HGPORT\r\n
494 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
494 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
495 readline(-1) -> (2) \r\n
495 readline(-1) -> (2) \r\n
496 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n
496 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n
497 write(23 from 23) -> (309) Server: badhttpserver\r\n
497 write(23 from 23) -> (309) Server: badhttpserver\r\n
498 write(37 from 37) -> (272) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
498 write(37 from 37) -> (272) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
499 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n
499 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n
500 write(20 from 20) -> (211) Content-Length: 42\r\n
500 write(20 from 20) -> (211) Content-Length: 42\r\n
501 write(2 from 2) -> (209) \r\n
501 write(2 from 2) -> (209) \r\n
502 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
502 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
503 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
503 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
504 readline(-1) -> (27) Accept-Encoding: identity\r\n
504 readline(-1) -> (27) Accept-Encoding: identity\r\n
505 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
505 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
506 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
506 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
507 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
507 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
508 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
508 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
509 readline(-1) -> (23) host: localhost:$HGPORT\r\n
509 readline(-1) -> (23) host: localhost:$HGPORT\r\n
510 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
510 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
511 readline(-1) -> (2) \r\n
511 readline(-1) -> (2) \r\n
512 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n
512 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n
513 write(23 from 23) -> (108) Server: badhttpserver\r\n
513 write(23 from 23) -> (108) Server: badhttpserver\r\n
514 write(37 from 37) -> (71) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
514 write(37 from 37) -> (71) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
515 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n
515 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n
516 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n
516 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n
517 write(2 from 2) -> (0) \r\n
517 write(2 from 2) -> (0) \r\n
518 write limit reached; closing socket
518 write limit reached; closing socket
519 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
519 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
520
520
521 $ rm -f error.log
521 $ rm -f error.log
522
522
523 Server sends partial compression string
523 Server sends partial compression string
524
524
525 $ hg --config badserver.closeaftersendbytes=945 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
525 $ hg --config badserver.closeaftersendbytes=945 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
526 $ cat hg.pid > $DAEMON_PIDS
526 $ cat hg.pid > $DAEMON_PIDS
527
527
528 TODO client spews a stack due to uncaught httplib.IncompleteRead
528 $ hg clone http://localhost:$HGPORT/ clone
529
530 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
531 requesting all changes
529 requesting all changes
532 [1]
530 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
531 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
532 [255]
533
533
534 $ killdaemons.py $DAEMON_PIDS
534 $ killdaemons.py $DAEMON_PIDS
535
535
536 $ cat error.log
536 $ cat error.log
537 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
537 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
538 readline(-1) -> (27) Accept-Encoding: identity\r\n
538 readline(-1) -> (27) Accept-Encoding: identity\r\n
539 readline(-1) -> (8) vary: \r\n
539 readline(-1) -> (8) vary: \r\n
540 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
540 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
541 readline(-1) -> (23) host: localhost:$HGPORT\r\n
541 readline(-1) -> (23) host: localhost:$HGPORT\r\n
542 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
542 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
543 readline(-1) -> (2) \r\n
543 readline(-1) -> (2) \r\n
544 write(36 from 36) -> (909) HTTP/1.1 200 Script output follows\r\n
544 write(36 from 36) -> (909) HTTP/1.1 200 Script output follows\r\n
545 write(23 from 23) -> (886) Server: badhttpserver\r\n
545 write(23 from 23) -> (886) Server: badhttpserver\r\n
546 write(37 from 37) -> (849) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
546 write(37 from 37) -> (849) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
547 write(41 from 41) -> (808) Content-Type: application/mercurial-0.1\r\n
547 write(41 from 41) -> (808) Content-Type: application/mercurial-0.1\r\n
548 write(21 from 21) -> (787) Content-Length: 405\r\n
548 write(21 from 21) -> (787) Content-Length: 405\r\n
549 write(2 from 2) -> (785) \r\n
549 write(2 from 2) -> (785) \r\n
550 write(405 from 405) -> (380) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
550 write(405 from 405) -> (380) lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=none
551 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
551 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
552 readline(-1) -> (27) Accept-Encoding: identity\r\n
552 readline(-1) -> (27) Accept-Encoding: identity\r\n
553 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
553 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
554 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
554 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
555 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
555 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
556 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
556 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
557 readline(-1) -> (23) host: localhost:$HGPORT\r\n
557 readline(-1) -> (23) host: localhost:$HGPORT\r\n
558 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
558 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
559 readline(-1) -> (2) \r\n
559 readline(-1) -> (2) \r\n
560 write(36 from 36) -> (344) HTTP/1.1 200 Script output follows\r\n
560 write(36 from 36) -> (344) HTTP/1.1 200 Script output follows\r\n
561 write(23 from 23) -> (321) Server: badhttpserver\r\n
561 write(23 from 23) -> (321) Server: badhttpserver\r\n
562 write(37 from 37) -> (284) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
562 write(37 from 37) -> (284) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
563 write(41 from 41) -> (243) Content-Type: application/mercurial-0.1\r\n
563 write(41 from 41) -> (243) Content-Type: application/mercurial-0.1\r\n
564 write(20 from 20) -> (223) Content-Length: 42\r\n
564 write(20 from 20) -> (223) Content-Length: 42\r\n
565 write(2 from 2) -> (221) \r\n
565 write(2 from 2) -> (221) \r\n
566 write(42 from 42) -> (179) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
566 write(42 from 42) -> (179) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
567 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
567 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
568 readline(-1) -> (27) Accept-Encoding: identity\r\n
568 readline(-1) -> (27) Accept-Encoding: identity\r\n
569 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
569 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
570 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
570 readline(-1) -> (396) x-hgarg-1: bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
571 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
571 readline(-1) -> (48) x-hgproto-1: 0.1 0.2 comp=zstd,zlib,none,bzip2\r\n
572 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
572 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
573 readline(-1) -> (23) host: localhost:$HGPORT\r\n
573 readline(-1) -> (23) host: localhost:$HGPORT\r\n
574 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
574 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
575 readline(-1) -> (2) \r\n
575 readline(-1) -> (2) \r\n
576 write(36 from 36) -> (143) HTTP/1.1 200 Script output follows\r\n
576 write(36 from 36) -> (143) HTTP/1.1 200 Script output follows\r\n
577 write(23 from 23) -> (120) Server: badhttpserver\r\n
577 write(23 from 23) -> (120) Server: badhttpserver\r\n
578 write(37 from 37) -> (83) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
578 write(37 from 37) -> (83) Date: Fri, 14 Apr 2017 00:00:00 GMT\r\n
579 write(41 from 41) -> (42) Content-Type: application/mercurial-0.2\r\n
579 write(41 from 41) -> (42) Content-Type: application/mercurial-0.2\r\n
580 write(28 from 28) -> (14) Transfer-Encoding: chunked\r\n
580 write(28 from 28) -> (14) Transfer-Encoding: chunked\r\n
581 write(2 from 2) -> (12) \r\n
581 write(2 from 2) -> (12) \r\n
582 write(6 from 6) -> (6) 1\\r\\n\x04\\r\\n (esc)
582 write(6 from 6) -> (6) 1\\r\\n\x04\\r\\n (esc)
583 write(6 from 9) -> (0) 4\r\nnon
583 write(6 from 9) -> (0) 4\r\nnon
584 write limit reached; closing socket
584 write limit reached; closing socket
585 write(27) -> 15\r\nInternal Server Error\r\n
585 write(27) -> 15\r\nInternal Server Error\r\n
586
586
587 $ rm -f error.log
587 $ rm -f error.log
588
588
589 Server sends partial bundle2 header magic
589 Server sends partial bundle2 header magic
590
590
591 $ hg --config badserver.closeaftersendbytes=954 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
591 $ hg --config badserver.closeaftersendbytes=954 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
592 $ cat hg.pid > $DAEMON_PIDS
592 $ cat hg.pid > $DAEMON_PIDS
593
593
594 $ hg clone http://localhost:$HGPORT/ clone
594 $ hg clone http://localhost:$HGPORT/ clone
595 requesting all changes
595 requesting all changes
596 abort: connection ended unexpectedly
596 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
597 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
597 [255]
598 [255]
598
599
599 $ killdaemons.py $DAEMON_PIDS
600 $ killdaemons.py $DAEMON_PIDS
600
601
601 $ tail -7 error.log
602 $ tail -7 error.log
602 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n
603 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n
603 write(2 from 2) -> (21) \r\n
604 write(2 from 2) -> (21) \r\n
604 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
605 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
605 write(9 from 9) -> (6) 4\r\nnone\r\n
606 write(9 from 9) -> (6) 4\r\nnone\r\n
606 write(6 from 9) -> (0) 4\r\nHG2
607 write(6 from 9) -> (0) 4\r\nHG2
607 write limit reached; closing socket
608 write limit reached; closing socket
608 write(27) -> 15\r\nInternal Server Error\r\n
609 write(27) -> 15\r\nInternal Server Error\r\n
609
610
610 $ rm -f error.log
611 $ rm -f error.log
611
612
612 Server sends incomplete bundle2 stream params length
613 Server sends incomplete bundle2 stream params length
613
614
614 $ hg --config badserver.closeaftersendbytes=963 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
615 $ hg --config badserver.closeaftersendbytes=963 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
615 $ cat hg.pid > $DAEMON_PIDS
616 $ cat hg.pid > $DAEMON_PIDS
616
617
617 $ hg clone http://localhost:$HGPORT/ clone
618 $ hg clone http://localhost:$HGPORT/ clone
618 requesting all changes
619 requesting all changes
619 abort: connection ended unexpectedly
620 abort: HTTP request error (incomplete response; expected 1 bytes got 3)
621 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
620 [255]
622 [255]
621
623
622 $ killdaemons.py $DAEMON_PIDS
624 $ killdaemons.py $DAEMON_PIDS
623
625
624 $ tail -8 error.log
626 $ tail -8 error.log
625 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n
627 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n
626 write(2 from 2) -> (30) \r\n
628 write(2 from 2) -> (30) \r\n
627 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
629 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
628 write(9 from 9) -> (15) 4\r\nnone\r\n
630 write(9 from 9) -> (15) 4\r\nnone\r\n
629 write(9 from 9) -> (6) 4\r\nHG20\r\n
631 write(9 from 9) -> (6) 4\r\nHG20\r\n
630 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
632 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
631 write limit reached; closing socket
633 write limit reached; closing socket
632 write(27) -> 15\r\nInternal Server Error\r\n
634 write(27) -> 15\r\nInternal Server Error\r\n
633
635
634 $ rm -f error.log
636 $ rm -f error.log
635
637
636 Servers stops after bundle2 stream params header
638 Servers stops after bundle2 stream params header
637
639
638 $ hg --config badserver.closeaftersendbytes=966 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
640 $ hg --config badserver.closeaftersendbytes=966 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
639 $ cat hg.pid > $DAEMON_PIDS
641 $ cat hg.pid > $DAEMON_PIDS
640
642
641 $ hg clone http://localhost:$HGPORT/ clone
643 $ hg clone http://localhost:$HGPORT/ clone
642 requesting all changes
644 requesting all changes
643 abort: connection ended unexpectedly
645 abort: HTTP request error (incomplete response)
646 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
644 [255]
647 [255]
645
648
646 $ killdaemons.py $DAEMON_PIDS
649 $ killdaemons.py $DAEMON_PIDS
647
650
648 $ tail -8 error.log
651 $ tail -8 error.log
649 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n
652 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n
650 write(2 from 2) -> (33) \r\n
653 write(2 from 2) -> (33) \r\n
651 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
654 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
652 write(9 from 9) -> (18) 4\r\nnone\r\n
655 write(9 from 9) -> (18) 4\r\nnone\r\n
653 write(9 from 9) -> (9) 4\r\nHG20\r\n
656 write(9 from 9) -> (9) 4\r\nHG20\r\n
654 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
657 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
655 write limit reached; closing socket
658 write limit reached; closing socket
656 write(27) -> 15\r\nInternal Server Error\r\n
659 write(27) -> 15\r\nInternal Server Error\r\n
657
660
658 $ rm -f error.log
661 $ rm -f error.log
659
662
660 Server stops sending after bundle2 part header length
663 Server stops sending after bundle2 part header length
661
664
662 $ hg --config badserver.closeaftersendbytes=975 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
665 $ hg --config badserver.closeaftersendbytes=975 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
663 $ cat hg.pid > $DAEMON_PIDS
666 $ cat hg.pid > $DAEMON_PIDS
664
667
665 $ hg clone http://localhost:$HGPORT/ clone
668 $ hg clone http://localhost:$HGPORT/ clone
666 requesting all changes
669 requesting all changes
667 abort: connection ended unexpectedly
670 abort: HTTP request error (incomplete response)
671 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
668 [255]
672 [255]
669
673
670 $ killdaemons.py $DAEMON_PIDS
674 $ killdaemons.py $DAEMON_PIDS
671
675
672 $ tail -9 error.log
676 $ tail -9 error.log
673 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n
677 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n
674 write(2 from 2) -> (42) \r\n
678 write(2 from 2) -> (42) \r\n
675 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
679 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
676 write(9 from 9) -> (27) 4\r\nnone\r\n
680 write(9 from 9) -> (27) 4\r\nnone\r\n
677 write(9 from 9) -> (18) 4\r\nHG20\r\n
681 write(9 from 9) -> (18) 4\r\nHG20\r\n
678 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
682 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
679 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
683 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
680 write limit reached; closing socket
684 write limit reached; closing socket
681 write(27) -> 15\r\nInternal Server Error\r\n
685 write(27) -> 15\r\nInternal Server Error\r\n
682
686
683 $ rm -f error.log
687 $ rm -f error.log
684
688
685 Server stops sending after bundle2 part header
689 Server stops sending after bundle2 part header
686
690
687 $ hg --config badserver.closeaftersendbytes=1022 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
691 $ hg --config badserver.closeaftersendbytes=1022 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
688 $ cat hg.pid > $DAEMON_PIDS
692 $ cat hg.pid > $DAEMON_PIDS
689
693
690 $ hg clone http://localhost:$HGPORT/ clone
694 $ hg clone http://localhost:$HGPORT/ clone
691 requesting all changes
695 requesting all changes
692 adding changesets
696 adding changesets
693 transaction abort!
697 transaction abort!
694 rollback completed
698 rollback completed
695 abort: stream ended unexpectedly (got 0 bytes, expected 4)
699 abort: stream ended unexpectedly (got 0 bytes, expected 4)
696 [255]
700 [255]
697
701
698 $ killdaemons.py $DAEMON_PIDS
702 $ killdaemons.py $DAEMON_PIDS
699
703
700 $ tail -10 error.log
704 $ tail -10 error.log
701 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n
705 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n
702 write(2 from 2) -> (89) \r\n
706 write(2 from 2) -> (89) \r\n
703 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
707 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
704 write(9 from 9) -> (74) 4\r\nnone\r\n
708 write(9 from 9) -> (74) 4\r\nnone\r\n
705 write(9 from 9) -> (65) 4\r\nHG20\r\n
709 write(9 from 9) -> (65) 4\r\nHG20\r\n
706 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
710 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
707 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
711 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
708 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
712 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
709 write limit reached; closing socket
713 write limit reached; closing socket
710 write(27) -> 15\r\nInternal Server Error\r\n
714 write(27) -> 15\r\nInternal Server Error\r\n
711
715
712 $ rm -f error.log
716 $ rm -f error.log
713
717
714 Server stops after bundle2 part payload chunk size
718 Server stops after bundle2 part payload chunk size
715
719
716 $ hg --config badserver.closeaftersendbytes=1031 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
720 $ hg --config badserver.closeaftersendbytes=1031 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
717 $ cat hg.pid > $DAEMON_PIDS
721 $ cat hg.pid > $DAEMON_PIDS
718
722
719 $ hg clone http://localhost:$HGPORT/ clone
723 $ hg clone http://localhost:$HGPORT/ clone
720 requesting all changes
724 requesting all changes
721 adding changesets
725 adding changesets
722 transaction abort!
726 transaction abort!
723 rollback completed
727 rollback completed
724 abort: stream ended unexpectedly (got 0 bytes, expected 4)
728 abort: stream ended unexpectedly (got 0 bytes, expected 4)
725 [255]
729 [255]
726
730
727 $ killdaemons.py $DAEMON_PIDS
731 $ killdaemons.py $DAEMON_PIDS
728
732
729 $ tail -11 error.log
733 $ tail -11 error.log
730 write(28 from 28) -> (100) Transfer-Encoding: chunked\r\n
734 write(28 from 28) -> (100) Transfer-Encoding: chunked\r\n
731 write(2 from 2) -> (98) \r\n
735 write(2 from 2) -> (98) \r\n
732 write(6 from 6) -> (92) 1\\r\\n\x04\\r\\n (esc)
736 write(6 from 6) -> (92) 1\\r\\n\x04\\r\\n (esc)
733 write(9 from 9) -> (83) 4\r\nnone\r\n
737 write(9 from 9) -> (83) 4\r\nnone\r\n
734 write(9 from 9) -> (74) 4\r\nHG20\r\n
738 write(9 from 9) -> (74) 4\r\nHG20\r\n
735 write(9 from 9) -> (65) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
739 write(9 from 9) -> (65) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
736 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
740 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
737 write(47 from 47) -> (9) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
741 write(47 from 47) -> (9) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
738 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
742 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
739 write limit reached; closing socket
743 write limit reached; closing socket
740 write(27) -> 15\r\nInternal Server Error\r\n
744 write(27) -> 15\r\nInternal Server Error\r\n
741
745
742 $ rm -f error.log
746 $ rm -f error.log
743
747
744 Server stops sending in middle of bundle2 payload chunk
748 Server stops sending in middle of bundle2 payload chunk
745
749
746 $ hg --config badserver.closeaftersendbytes=1504 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
750 $ hg --config badserver.closeaftersendbytes=1504 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
747 $ cat hg.pid > $DAEMON_PIDS
751 $ cat hg.pid > $DAEMON_PIDS
748
752
749 $ hg clone http://localhost:$HGPORT/ clone
753 $ hg clone http://localhost:$HGPORT/ clone
750 requesting all changes
754 requesting all changes
751 adding changesets
755 adding changesets
752 transaction abort!
756 transaction abort!
753 rollback completed
757 rollback completed
754 abort: stream ended unexpectedly (got 0 bytes, expected 4)
758 abort: stream ended unexpectedly (got 0 bytes, expected 4)
755 [255]
759 [255]
756
760
757 $ killdaemons.py $DAEMON_PIDS
761 $ killdaemons.py $DAEMON_PIDS
758
762
759 $ tail -12 error.log
763 $ tail -12 error.log
760 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n
764 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n
761 write(2 from 2) -> (571) \r\n
765 write(2 from 2) -> (571) \r\n
762 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
766 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
763 write(9 from 9) -> (556) 4\r\nnone\r\n
767 write(9 from 9) -> (556) 4\r\nnone\r\n
764 write(9 from 9) -> (547) 4\r\nHG20\r\n
768 write(9 from 9) -> (547) 4\r\nHG20\r\n
765 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
769 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
766 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
770 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
767 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
771 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
768 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
772 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
769 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)
773 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)
770 write limit reached; closing socket
774 write limit reached; closing socket
771 write(27) -> 15\r\nInternal Server Error\r\n
775 write(27) -> 15\r\nInternal Server Error\r\n
772
776
773 $ rm -f error.log
777 $ rm -f error.log
774
778
775 Server stops sending after 0 length payload chunk size
779 Server stops sending after 0 length payload chunk size
776
780
777 $ hg --config badserver.closeaftersendbytes=1513 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
781 $ hg --config badserver.closeaftersendbytes=1513 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
778 $ cat hg.pid > $DAEMON_PIDS
782 $ cat hg.pid > $DAEMON_PIDS
779
783
780 $ hg clone http://localhost:$HGPORT/ clone
784 $ hg clone http://localhost:$HGPORT/ clone
781 requesting all changes
785 requesting all changes
782 adding changesets
786 adding changesets
783 adding manifests
787 adding manifests
784 adding file changes
788 adding file changes
785 added 1 changesets with 1 changes to 1 files
789 added 1 changesets with 1 changes to 1 files
786 transaction abort!
790 transaction abort!
787 rollback completed
791 rollback completed
788 abort: connection ended unexpectedly
792 abort: HTTP request error (incomplete response)
793 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
789 [255]
794 [255]
790
795
791 $ killdaemons.py $DAEMON_PIDS
796 $ killdaemons.py $DAEMON_PIDS
792
797
793 $ tail -13 error.log
798 $ tail -13 error.log
794 write(28 from 28) -> (582) Transfer-Encoding: chunked\r\n
799 write(28 from 28) -> (582) Transfer-Encoding: chunked\r\n
795 write(2 from 2) -> (580) \r\n
800 write(2 from 2) -> (580) \r\n
796 write(6 from 6) -> (574) 1\\r\\n\x04\\r\\n (esc)
801 write(6 from 6) -> (574) 1\\r\\n\x04\\r\\n (esc)
797 write(9 from 9) -> (565) 4\r\nnone\r\n
802 write(9 from 9) -> (565) 4\r\nnone\r\n
798 write(9 from 9) -> (556) 4\r\nHG20\r\n
803 write(9 from 9) -> (556) 4\r\nHG20\r\n
799 write(9 from 9) -> (547) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
804 write(9 from 9) -> (547) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
800 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
805 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
801 write(47 from 47) -> (491) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
806 write(47 from 47) -> (491) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
802 write(9 from 9) -> (482) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
807 write(9 from 9) -> (482) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
803 write(473 from 473) -> (9) 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)
808 write(473 from 473) -> (9) 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)
804 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
809 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
805 write limit reached; closing socket
810 write limit reached; closing socket
806 write(27) -> 15\r\nInternal Server Error\r\n
811 write(27) -> 15\r\nInternal Server Error\r\n
807
812
808 $ rm -f error.log
813 $ rm -f error.log
809
814
810 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
815 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
811 This is before the 0 size chunked transfer part that signals end of HTTP response.
816 This is before the 0 size chunked transfer part that signals end of HTTP response.
812
817
813 $ hg --config badserver.closeaftersendbytes=1710 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
818 $ hg --config badserver.closeaftersendbytes=1710 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
814 $ cat hg.pid > $DAEMON_PIDS
819 $ cat hg.pid > $DAEMON_PIDS
815
820
816 $ hg clone http://localhost:$HGPORT/ clone
821 $ hg clone http://localhost:$HGPORT/ clone
817 requesting all changes
822 requesting all changes
818 adding changesets
823 adding changesets
819 adding manifests
824 adding manifests
820 adding file changes
825 adding file changes
821 added 1 changesets with 1 changes to 1 files
826 added 1 changesets with 1 changes to 1 files
822 updating to branch default
827 updating to branch default
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
828 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824
829
825 $ killdaemons.py $DAEMON_PIDS
830 $ killdaemons.py $DAEMON_PIDS
826
831
827 $ tail -22 error.log
832 $ tail -22 error.log
828 write(28 from 28) -> (779) Transfer-Encoding: chunked\r\n
833 write(28 from 28) -> (779) Transfer-Encoding: chunked\r\n
829 write(2 from 2) -> (777) \r\n
834 write(2 from 2) -> (777) \r\n
830 write(6 from 6) -> (771) 1\\r\\n\x04\\r\\n (esc)
835 write(6 from 6) -> (771) 1\\r\\n\x04\\r\\n (esc)
831 write(9 from 9) -> (762) 4\r\nnone\r\n
836 write(9 from 9) -> (762) 4\r\nnone\r\n
832 write(9 from 9) -> (753) 4\r\nHG20\r\n
837 write(9 from 9) -> (753) 4\r\nHG20\r\n
833 write(9 from 9) -> (744) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
838 write(9 from 9) -> (744) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
834 write(9 from 9) -> (735) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
839 write(9 from 9) -> (735) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
835 write(47 from 47) -> (688) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
840 write(47 from 47) -> (688) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
836 write(9 from 9) -> (679) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
841 write(9 from 9) -> (679) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
837 write(473 from 473) -> (206) 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)
842 write(473 from 473) -> (206) 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)
838 write(9 from 9) -> (197) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
843 write(9 from 9) -> (197) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
839 write(9 from 9) -> (188) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
844 write(9 from 9) -> (188) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
840 write(38 from 38) -> (150) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
845 write(38 from 38) -> (150) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
841 write(9 from 9) -> (141) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
846 write(9 from 9) -> (141) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
842 write(64 from 64) -> (77) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
847 write(64 from 64) -> (77) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
843 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
848 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
844 write(9 from 9) -> (59) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
849 write(9 from 9) -> (59) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
845 write(41 from 41) -> (18) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
850 write(41 from 41) -> (18) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
846 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
851 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
847 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
852 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
848 write limit reached; closing socket
853 write limit reached; closing socket
849 write(27) -> 15\r\nInternal Server Error\r\n
854 write(27) -> 15\r\nInternal Server Error\r\n
850
855
851 $ rm -f error.log
856 $ rm -f error.log
852 $ rm -rf clone
857 $ rm -rf clone
853
858
854 Server sends a size 0 chunked-transfer size without terminating \r\n
859 Server sends a size 0 chunked-transfer size without terminating \r\n
855
860
856 $ hg --config badserver.closeaftersendbytes=1713 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
861 $ hg --config badserver.closeaftersendbytes=1713 serve -p $HGPORT -d --pid-file=hg.pid -E error.log
857 $ cat hg.pid > $DAEMON_PIDS
862 $ cat hg.pid > $DAEMON_PIDS
858
863
859 $ hg clone http://localhost:$HGPORT/ clone
864 $ hg clone http://localhost:$HGPORT/ clone
860 requesting all changes
865 requesting all changes
861 adding changesets
866 adding changesets
862 adding manifests
867 adding manifests
863 adding file changes
868 adding file changes
864 added 1 changesets with 1 changes to 1 files
869 added 1 changesets with 1 changes to 1 files
865 updating to branch default
870 updating to branch default
866 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
867
872
868 $ killdaemons.py $DAEMON_PIDS
873 $ killdaemons.py $DAEMON_PIDS
869
874
870 $ tail -23 error.log
875 $ tail -23 error.log
871 write(28 from 28) -> (782) Transfer-Encoding: chunked\r\n
876 write(28 from 28) -> (782) Transfer-Encoding: chunked\r\n
872 write(2 from 2) -> (780) \r\n
877 write(2 from 2) -> (780) \r\n
873 write(6 from 6) -> (774) 1\\r\\n\x04\\r\\n (esc)
878 write(6 from 6) -> (774) 1\\r\\n\x04\\r\\n (esc)
874 write(9 from 9) -> (765) 4\r\nnone\r\n
879 write(9 from 9) -> (765) 4\r\nnone\r\n
875 write(9 from 9) -> (756) 4\r\nHG20\r\n
880 write(9 from 9) -> (756) 4\r\nHG20\r\n
876 write(9 from 9) -> (747) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
881 write(9 from 9) -> (747) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
877 write(9 from 9) -> (738) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
882 write(9 from 9) -> (738) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
878 write(47 from 47) -> (691) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
883 write(47 from 47) -> (691) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
879 write(9 from 9) -> (682) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
884 write(9 from 9) -> (682) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
880 write(473 from 473) -> (209) 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)
885 write(473 from 473) -> (209) 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)
881 write(9 from 9) -> (200) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
886 write(9 from 9) -> (200) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
882 write(9 from 9) -> (191) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
887 write(9 from 9) -> (191) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
883 write(38 from 38) -> (153) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
888 write(38 from 38) -> (153) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
884 write(9 from 9) -> (144) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
889 write(9 from 9) -> (144) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
885 write(64 from 64) -> (80) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
890 write(64 from 64) -> (80) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
886 write(9 from 9) -> (71) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
891 write(9 from 9) -> (71) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
887 write(9 from 9) -> (62) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
892 write(9 from 9) -> (62) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
888 write(41 from 41) -> (21) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
893 write(41 from 41) -> (21) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
889 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
894 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
890 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
895 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
891 write(3 from 5) -> (0) 0\r\n
896 write(3 from 5) -> (0) 0\r\n
892 write limit reached; closing socket
897 write limit reached; closing socket
893 write(27) -> 15\r\nInternal Server Error\r\n
898 write(27) -> 15\r\nInternal Server Error\r\n
894
899
895 $ rm -f error.log
900 $ rm -f error.log
896 $ rm -rf clone
901 $ rm -rf clone
General Comments 0
You need to be logged in to leave comments. Login now