##// END OF EJS Templates
py3: byteify the fakeversion extension in test-http-bad-server.t...
Matt Harbison -
r41018:c296b8fa default
parent child Browse files
Show More
@@ -1,936 +1,936 b''
1 1 #require serve zstd
2 2
3 3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
4 4 version so behavior is deterministic.
5 5
6 6 $ cat > fakeversion.py << EOF
7 7 > from mercurial import util
8 > util.version = lambda: '4.2'
8 > util.version = lambda: b'4.2'
9 9 > EOF
10 10
11 11 $ cat >> $HGRCPATH << EOF
12 12 > [extensions]
13 13 > fakeversion = `pwd`/fakeversion.py
14 14 > [format]
15 15 > sparse-revlog = no
16 16 > [devel]
17 17 > legacy.exchange = phases
18 18 > EOF
19 19
20 20 $ hg init server0
21 21 $ cd server0
22 22 $ touch foo
23 23 $ hg -q commit -A -m initial
24 24
25 25 Also disable compression because zstd is optional and causes output to vary
26 26 and because debugging partial responses is hard when compression is involved
27 27
28 28 $ cat > .hg/hgrc << EOF
29 29 > [extensions]
30 30 > badserver = $TESTDIR/badserverext.py
31 31 > [server]
32 32 > compressionengines = none
33 33 > EOF
34 34
35 35 Failure to accept() socket should result in connection related error message
36 36
37 37 $ hg serve --config badserver.closebeforeaccept=true -p $HGPORT -d --pid-file=hg.pid
38 38 $ cat hg.pid > $DAEMON_PIDS
39 39
40 40 $ hg clone http://localhost:$HGPORT/ clone
41 41 abort: error: (\$ECONNRESET\$|\$EADDRNOTAVAIL\$) (re)
42 42 [255]
43 43
44 44 (The server exits on its own, but there is a race between that and starting a new server.
45 45 So ensure the process is dead.)
46 46
47 47 $ killdaemons.py $DAEMON_PIDS
48 48
49 49 Failure immediately after accept() should yield connection related error message
50 50
51 51 $ hg serve --config badserver.closeafteraccept=true -p $HGPORT -d --pid-file=hg.pid
52 52 $ cat hg.pid > $DAEMON_PIDS
53 53
54 54 TODO: this usually outputs good results, but sometimes emits abort:
55 55 error: '' on FreeBSD and OS X.
56 56 What we ideally want are:
57 57
58 58 abort: error: $ECONNRESET$
59 59
60 60 The flakiness in this output was observable easily with
61 61 --runs-per-test=20 on macOS 10.12 during the freeze for 4.2.
62 62 $ hg clone http://localhost:$HGPORT/ clone
63 63 abort: error: * (glob)
64 64 [255]
65 65
66 66 $ killdaemons.py $DAEMON_PIDS
67 67
68 68 Failure to read all bytes in initial HTTP request should yield connection related error message
69 69
70 70 $ hg serve --config badserver.closeafterrecvbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
71 71 $ cat hg.pid > $DAEMON_PIDS
72 72
73 73 $ hg clone http://localhost:$HGPORT/ clone
74 74 abort: error: bad HTTP status line: * (glob)
75 75 [255]
76 76
77 77 $ killdaemons.py $DAEMON_PIDS
78 78
79 79 $ cat error.log
80 80 readline(1 from 65537) -> (1) G
81 81 read limit reached; closing socket
82 82
83 83 $ rm -f error.log
84 84
85 85 Same failure, but server reads full HTTP request line
86 86
87 87 $ hg serve --config badserver.closeafterrecvbytes=40 -p $HGPORT -d --pid-file=hg.pid -E error.log
88 88 $ cat hg.pid > $DAEMON_PIDS
89 89 $ hg clone http://localhost:$HGPORT/ clone
90 90 abort: error: bad HTTP status line: * (glob)
91 91 [255]
92 92
93 93 $ killdaemons.py $DAEMON_PIDS
94 94
95 95 $ cat error.log
96 96 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
97 97 readline(7 from -1) -> (7) Accept-
98 98 read limit reached; closing socket
99 99
100 100 $ rm -f error.log
101 101
102 102 Failure on subsequent HTTP request on the same socket (cmd?batch)
103 103
104 104 $ hg serve --config badserver.closeafterrecvbytes=210,223 -p $HGPORT -d --pid-file=hg.pid -E error.log
105 105 $ cat hg.pid > $DAEMON_PIDS
106 106 $ hg clone http://localhost:$HGPORT/ clone
107 107 abort: error: bad HTTP status line: * (glob)
108 108 [255]
109 109
110 110 $ killdaemons.py $DAEMON_PIDS
111 111
112 112 $ cat error.log
113 113 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
114 114 readline(177 from -1) -> (27) Accept-Encoding: identity\r\n
115 115 readline(150 from -1) -> (35) accept: application/mercurial-0.1\r\n
116 116 readline(115 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
117 117 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
118 118 readline(* from -1) -> (2) \r\n (glob)
119 119 write(36) -> HTTP/1.1 200 Script output follows\r\n
120 120 write(23) -> Server: badhttpserver\r\n
121 121 write(37) -> Date: $HTTP_DATE$\r\n
122 122 write(41) -> Content-Type: application/mercurial-0.1\r\n
123 123 write(21) -> Content-Length: 450\r\n
124 124 write(2) -> \r\n
125 125 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
126 126 readline(4? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
127 127 readline(1? from -1) -> (1?) Accept-Encoding* (glob)
128 128 read limit reached; closing socket
129 129 readline(223 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
130 130 readline(197 from -1) -> (27) Accept-Encoding: identity\r\n
131 131 readline(170 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
132 132 readline(141 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
133 133 readline(100 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
134 134 readline(39 from -1) -> (35) accept: application/mercurial-0.1\r\n
135 135 readline(4 from -1) -> (4) host
136 136 read limit reached; closing socket
137 137
138 138 $ rm -f error.log
139 139
140 140 Failure to read getbundle HTTP request
141 141
142 142 $ hg serve --config badserver.closeafterrecvbytes=308,317,304 -p $HGPORT -d --pid-file=hg.pid -E error.log
143 143 $ cat hg.pid > $DAEMON_PIDS
144 144 $ hg clone http://localhost:$HGPORT/ clone
145 145 requesting all changes
146 146 abort: error: bad HTTP status line: * (glob)
147 147 [255]
148 148
149 149 $ killdaemons.py $DAEMON_PIDS
150 150
151 151 $ cat error.log
152 152 readline(1 from -1) -> (1) x (?)
153 153 readline(1 from -1) -> (1) x (?)
154 154 readline(308 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
155 155 readline(275 from -1) -> (27) Accept-Encoding: identity\r\n
156 156 readline(248 from -1) -> (35) accept: application/mercurial-0.1\r\n
157 157 readline(213 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
158 158 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
159 159 readline(* from -1) -> (2) \r\n (glob)
160 160 write(36) -> HTTP/1.1 200 Script output follows\r\n
161 161 write(23) -> Server: badhttpserver\r\n
162 162 write(37) -> Date: $HTTP_DATE$\r\n
163 163 write(41) -> Content-Type: application/mercurial-0.1\r\n
164 164 write(21) -> Content-Length: 450\r\n
165 165 write(2) -> \r\n
166 166 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
167 167 readline(13? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
168 168 readline(1?? from -1) -> (27) Accept-Encoding: identity\r\n (glob)
169 169 readline(8? from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
170 170 readline(5? from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
171 171 readline(1? from -1) -> (1?) x-hgproto-1:* (glob)
172 172 read limit reached; closing socket
173 173 readline(317 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
174 174 readline(291 from -1) -> (27) Accept-Encoding: identity\r\n
175 175 readline(264 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
176 176 readline(235 from -1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
177 177 readline(194 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
178 178 readline(133 from -1) -> (35) accept: application/mercurial-0.1\r\n
179 179 readline(98 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
180 180 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
181 181 readline(* from -1) -> (2) \r\n (glob)
182 182 write(36) -> HTTP/1.1 200 Script output follows\r\n
183 183 write(23) -> Server: badhttpserver\r\n
184 184 write(37) -> Date: $HTTP_DATE$\r\n
185 185 write(41) -> Content-Type: application/mercurial-0.1\r\n
186 186 write(20) -> Content-Length: 42\r\n
187 187 write(2) -> \r\n
188 188 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
189 189 readline(* from 65537) -> (*) GET /?cmd=getbundle HTTP* (glob)
190 190 read limit reached; closing socket
191 191 readline(304 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
192 192 readline(274 from -1) -> (27) Accept-Encoding: identity\r\n
193 193 readline(247 from -1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
194 194 readline(218 from -1) -> (218) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtag
195 195 read limit reached; closing socket
196 196
197 197 $ rm -f error.log
198 198
199 199 Now do a variation using POST to send arguments
200 200
201 201 $ hg serve --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=329,344 -p $HGPORT -d --pid-file=hg.pid -E error.log
202 202 $ cat hg.pid > $DAEMON_PIDS
203 203
204 204 $ hg clone http://localhost:$HGPORT/ clone
205 205 abort: error: bad HTTP status line: * (glob)
206 206 [255]
207 207
208 208 $ killdaemons.py $DAEMON_PIDS
209 209
210 210 $ cat error.log
211 211 readline(329 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
212 212 readline(296 from -1) -> (27) Accept-Encoding: identity\r\n
213 213 readline(269 from -1) -> (35) accept: application/mercurial-0.1\r\n
214 214 readline(234 from -1) -> (2?) host: localhost:$HGPORT\r\n (glob)
215 215 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
216 216 readline(* from -1) -> (2) \r\n (glob)
217 217 write(36) -> HTTP/1.1 200 Script output follows\r\n
218 218 write(23) -> Server: badhttpserver\r\n
219 219 write(37) -> Date: $HTTP_DATE$\r\n
220 220 write(41) -> Content-Type: application/mercurial-0.1\r\n
221 221 write(21) -> Content-Length: 463\r\n
222 222 write(2) -> \r\n
223 223 write(463) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
224 224 readline(1?? from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n (glob)
225 225 readline(1?? from -1) -> (27) Accept-Encoding: identity\r\n (glob)
226 226 readline(1?? from -1) -> (41) content-type: application/mercurial-0.1\r\n (glob)
227 227 readline(6? from -1) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
228 228 readline(3? from -1) -> (19) x-hgargs-post: 28\r\n (glob)
229 229 readline(1? from -1) -> (1?) x-hgproto-1: * (glob)
230 230 read limit reached; closing socket
231 231 readline(344 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
232 232 readline(317 from -1) -> (27) Accept-Encoding: identity\r\n
233 233 readline(290 from -1) -> (41) content-type: application/mercurial-0.1\r\n
234 234 readline(249 from -1) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n
235 235 readline(216 from -1) -> (19) x-hgargs-post: 28\r\n
236 236 readline(197 from -1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
237 237 readline(136 from -1) -> (35) accept: application/mercurial-0.1\r\n
238 238 readline(101 from -1) -> (20) content-length: 28\r\n
239 239 readline(81 from -1) -> (*) host: localhost:$HGPORT\r\n (glob)
240 240 readline(* from -1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
241 241 readline(* from -1) -> (2) \r\n (glob)
242 242 read(* from 28) -> (*) cmds=* (glob)
243 243 read limit reached, closing socket
244 244 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
245 245
246 246 $ rm -f error.log
247 247
248 248 Now move on to partial server responses
249 249
250 250 Server sends a single character from the HTTP response line
251 251
252 252 $ hg serve --config badserver.closeaftersendbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
253 253 $ cat hg.pid > $DAEMON_PIDS
254 254
255 255 $ hg clone http://localhost:$HGPORT/ clone
256 256 abort: error: bad HTTP status line: H
257 257 [255]
258 258
259 259 $ killdaemons.py $DAEMON_PIDS
260 260
261 261 $ cat error.log
262 262 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
263 263 readline(-1) -> (27) Accept-Encoding: identity\r\n
264 264 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
265 265 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
266 266 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
267 267 readline(-1) -> (2) \r\n
268 268 write(1 from 36) -> (0) H
269 269 write limit reached; closing socket
270 270 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
271 271
272 272 $ rm -f error.log
273 273
274 274 Server sends an incomplete capabilities response body
275 275
276 276 $ hg serve --config badserver.closeaftersendbytes=180 -p $HGPORT -d --pid-file=hg.pid -E error.log
277 277 $ cat hg.pid > $DAEMON_PIDS
278 278
279 279 $ hg clone http://localhost:$HGPORT/ clone
280 280 abort: HTTP request error (incomplete response; expected 450 bytes got 20)
281 281 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
282 282 [255]
283 283
284 284 $ killdaemons.py $DAEMON_PIDS
285 285
286 286 $ cat error.log
287 287 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
288 288 readline(-1) -> (27) Accept-Encoding: identity\r\n
289 289 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
290 290 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
291 291 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
292 292 readline(-1) -> (2) \r\n
293 293 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n
294 294 write(23 from 23) -> (121) Server: badhttpserver\r\n
295 295 write(37 from 37) -> (84) Date: $HTTP_DATE$\r\n
296 296 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n
297 297 write(21 from 21) -> (22) Content-Length: 450\r\n
298 298 write(2 from 2) -> (20) \r\n
299 299 write(20 from 450) -> (0) batch branchmap bund
300 300 write limit reached; closing socket
301 301
302 302 $ rm -f error.log
303 303
304 304 Server sends incomplete headers for batch request
305 305
306 306 $ hg serve --config badserver.closeaftersendbytes=728 -p $HGPORT -d --pid-file=hg.pid -E error.log
307 307 $ cat hg.pid > $DAEMON_PIDS
308 308
309 309 TODO this output is horrible
310 310
311 311 $ hg clone http://localhost:$HGPORT/ clone
312 312 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
313 313 ---%<--- (applicat)
314 314
315 315 ---%<---
316 316 !
317 317 [255]
318 318
319 319 $ killdaemons.py $DAEMON_PIDS
320 320
321 321 $ cat error.log
322 322 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
323 323 readline(-1) -> (27) Accept-Encoding: identity\r\n
324 324 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
325 325 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
326 326 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
327 327 readline(-1) -> (2) \r\n
328 328 write(36 from 36) -> (692) HTTP/1.1 200 Script output follows\r\n
329 329 write(23 from 23) -> (669) Server: badhttpserver\r\n
330 330 write(37 from 37) -> (632) Date: $HTTP_DATE$\r\n
331 331 write(41 from 41) -> (591) Content-Type: application/mercurial-0.1\r\n
332 332 write(21 from 21) -> (570) Content-Length: 450\r\n
333 333 write(2 from 2) -> (568) \r\n
334 334 write(450 from 450) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
335 335 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
336 336 readline(-1) -> (27) Accept-Encoding: identity\r\n
337 337 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
338 338 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
339 339 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
340 340 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
341 341 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
342 342 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
343 343 readline(-1) -> (2) \r\n
344 344 write(36 from 36) -> (82) HTTP/1.1 200 Script output follows\r\n
345 345 write(23 from 23) -> (59) Server: badhttpserver\r\n
346 346 write(37 from 37) -> (22) Date: $HTTP_DATE$\r\n
347 347 write(22 from 41) -> (0) Content-Type: applicat
348 348 write limit reached; closing socket
349 349 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
350 350
351 351 $ rm -f error.log
352 352
353 353 Server sends an incomplete HTTP response body to batch request
354 354
355 355 $ hg serve --config badserver.closeaftersendbytes=793 -p $HGPORT -d --pid-file=hg.pid -E error.log
356 356 $ cat hg.pid > $DAEMON_PIDS
357 357
358 358 TODO client spews a stack due to uncaught ValueError in batch.results()
359 359 #if no-chg
360 360 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
361 361 [1]
362 362 #else
363 363 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
364 364 [255]
365 365 #endif
366 366
367 367 $ killdaemons.py $DAEMON_PIDS
368 368
369 369 $ cat error.log
370 370 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
371 371 readline(-1) -> (27) Accept-Encoding: identity\r\n
372 372 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
373 373 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
374 374 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
375 375 readline(-1) -> (2) \r\n
376 376 write(36 from 36) -> (757) HTTP/1.1 200 Script output follows\r\n
377 377 write(23 from 23) -> (734) Server: badhttpserver\r\n
378 378 write(37 from 37) -> (697) Date: $HTTP_DATE$\r\n
379 379 write(41 from 41) -> (656) Content-Type: application/mercurial-0.1\r\n
380 380 write(21 from 21) -> (635) Content-Length: 450\r\n
381 381 write(2 from 2) -> (633) \r\n
382 382 write(450 from 450) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
383 383 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
384 384 readline(-1) -> (27) Accept-Encoding: identity\r\n
385 385 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
386 386 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
387 387 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
388 388 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
389 389 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
390 390 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
391 391 readline(-1) -> (2) \r\n
392 392 write(36 from 36) -> (147) HTTP/1.1 200 Script output follows\r\n
393 393 write(23 from 23) -> (124) Server: badhttpserver\r\n
394 394 write(37 from 37) -> (87) Date: $HTTP_DATE$\r\n
395 395 write(41 from 41) -> (46) Content-Type: application/mercurial-0.1\r\n
396 396 write(20 from 20) -> (26) Content-Length: 42\r\n
397 397 write(2 from 2) -> (24) \r\n
398 398 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672
399 399 write limit reached; closing socket
400 400
401 401 $ rm -f error.log
402 402
403 403 Server sends incomplete headers for getbundle response
404 404
405 405 $ hg serve --config badserver.closeaftersendbytes=940 -p $HGPORT -d --pid-file=hg.pid -E error.log
406 406 $ cat hg.pid > $DAEMON_PIDS
407 407
408 408 TODO this output is terrible
409 409
410 410 $ hg clone http://localhost:$HGPORT/ clone
411 411 requesting all changes
412 412 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
413 413 ---%<--- (application/mercuri)
414 414
415 415 ---%<---
416 416 !
417 417 [255]
418 418
419 419 $ killdaemons.py $DAEMON_PIDS
420 420
421 421 $ cat error.log
422 422 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
423 423 readline(-1) -> (27) Accept-Encoding: identity\r\n
424 424 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
425 425 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
426 426 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
427 427 readline(-1) -> (2) \r\n
428 428 write(36 from 36) -> (904) HTTP/1.1 200 Script output follows\r\n
429 429 write(23 from 23) -> (881) Server: badhttpserver\r\n
430 430 write(37 from 37) -> (844) Date: $HTTP_DATE$\r\n
431 431 write(41 from 41) -> (803) Content-Type: application/mercurial-0.1\r\n
432 432 write(21 from 21) -> (782) Content-Length: 450\r\n
433 433 write(2 from 2) -> (780) \r\n
434 434 write(450 from 450) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
435 435 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
436 436 readline(-1) -> (27) Accept-Encoding: identity\r\n
437 437 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
438 438 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
439 439 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
440 440 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
441 441 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
442 442 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
443 443 readline(-1) -> (2) \r\n
444 444 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n
445 445 write(23 from 23) -> (271) Server: badhttpserver\r\n
446 446 write(37 from 37) -> (234) Date: $HTTP_DATE$\r\n
447 447 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n
448 448 write(20 from 20) -> (173) Content-Length: 42\r\n
449 449 write(2 from 2) -> (171) \r\n
450 450 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
451 451 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
452 452 readline(-1) -> (27) Accept-Encoding: identity\r\n
453 453 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
454 454 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
455 455 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
456 456 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
457 457 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
458 458 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
459 459 readline(-1) -> (2) \r\n
460 460 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n
461 461 write(23 from 23) -> (70) Server: badhttpserver\r\n
462 462 write(37 from 37) -> (33) Date: $HTTP_DATE$\r\n
463 463 write(33 from 41) -> (0) Content-Type: application/mercuri
464 464 write limit reached; closing socket
465 465 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
466 466
467 467 $ rm -f error.log
468 468
469 469 Server stops before it sends transfer encoding
470 470
471 471 $ hg serve --config badserver.closeaftersendbytes=973 -p $HGPORT -d --pid-file=hg.pid -E error.log
472 472 $ cat hg.pid > $DAEMON_PIDS
473 473
474 474 $ hg clone http://localhost:$HGPORT/ clone
475 475 requesting all changes
476 476 abort: stream ended unexpectedly (got 0 bytes, expected 1)
477 477 [255]
478 478
479 479 $ killdaemons.py $DAEMON_PIDS
480 480
481 481 $ tail -4 error.log
482 482 write(41 from 41) -> (25) Content-Type: application/mercurial-0.2\r\n
483 483 write(25 from 28) -> (0) Transfer-Encoding: chunke
484 484 write limit reached; closing socket
485 485 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
486 486
487 487 $ rm -f error.log
488 488
489 489 Server sends empty HTTP body for getbundle
490 490
491 491 $ hg serve --config badserver.closeaftersendbytes=978 -p $HGPORT -d --pid-file=hg.pid -E error.log
492 492 $ cat hg.pid > $DAEMON_PIDS
493 493
494 494 $ hg clone http://localhost:$HGPORT/ clone
495 495 requesting all changes
496 496 abort: HTTP request error (incomplete response)
497 497 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
498 498 [255]
499 499
500 500 $ killdaemons.py $DAEMON_PIDS
501 501
502 502 $ cat error.log
503 503 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
504 504 readline(-1) -> (27) Accept-Encoding: identity\r\n
505 505 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
506 506 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
507 507 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
508 508 readline(-1) -> (2) \r\n
509 509 write(36 from 36) -> (942) HTTP/1.1 200 Script output follows\r\n
510 510 write(23 from 23) -> (919) Server: badhttpserver\r\n
511 511 write(37 from 37) -> (882) Date: $HTTP_DATE$\r\n
512 512 write(41 from 41) -> (841) Content-Type: application/mercurial-0.1\r\n
513 513 write(21 from 21) -> (820) Content-Length: 450\r\n
514 514 write(2 from 2) -> (818) \r\n
515 515 write(450 from 450) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
516 516 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
517 517 readline(-1) -> (27) Accept-Encoding: identity\r\n
518 518 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
519 519 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
520 520 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
521 521 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
522 522 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
523 523 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
524 524 readline(-1) -> (2) \r\n
525 525 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n
526 526 write(23 from 23) -> (309) Server: badhttpserver\r\n
527 527 write(37 from 37) -> (272) Date: $HTTP_DATE$\r\n
528 528 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n
529 529 write(20 from 20) -> (211) Content-Length: 42\r\n
530 530 write(2 from 2) -> (209) \r\n
531 531 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
532 532 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
533 533 readline(-1) -> (27) Accept-Encoding: identity\r\n
534 534 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
535 535 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
536 536 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
537 537 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
538 538 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
539 539 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
540 540 readline(-1) -> (2) \r\n
541 541 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n
542 542 write(23 from 23) -> (108) Server: badhttpserver\r\n
543 543 write(37 from 37) -> (71) Date: $HTTP_DATE$\r\n
544 544 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n
545 545 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n
546 546 write(2 from 2) -> (0) \r\n
547 547 write limit reached; closing socket
548 548 write(36) -> HTTP/1.1 500 Internal Server Error\r\n
549 549
550 550 $ rm -f error.log
551 551
552 552 Server sends partial compression string
553 553
554 554 $ hg serve --config badserver.closeaftersendbytes=1002 -p $HGPORT -d --pid-file=hg.pid -E error.log
555 555 $ cat hg.pid > $DAEMON_PIDS
556 556
557 557 $ hg clone http://localhost:$HGPORT/ clone
558 558 requesting all changes
559 559 abort: HTTP request error (incomplete response)
560 560 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
561 561 [255]
562 562
563 563 $ killdaemons.py $DAEMON_PIDS
564 564
565 565 $ cat error.log
566 566 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
567 567 readline(-1) -> (27) Accept-Encoding: identity\r\n
568 568 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
569 569 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
570 570 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
571 571 readline(-1) -> (2) \r\n
572 572 write(36 from 36) -> (966) HTTP/1.1 200 Script output follows\r\n
573 573 write(23 from 23) -> (943) Server: badhttpserver\r\n
574 574 write(37 from 37) -> (906) Date: $HTTP_DATE$\r\n
575 575 write(41 from 41) -> (865) Content-Type: application/mercurial-0.1\r\n
576 576 write(21 from 21) -> (844) Content-Length: 450\r\n
577 577 write(2 from 2) -> (842) \r\n
578 578 write(450 from 450) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
579 579 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
580 580 readline(-1) -> (27) Accept-Encoding: identity\r\n
581 581 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
582 582 readline(-1) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n
583 583 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
584 584 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
585 585 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
586 586 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
587 587 readline(-1) -> (2) \r\n
588 588 write(36 from 36) -> (356) HTTP/1.1 200 Script output follows\r\n
589 589 write(23 from 23) -> (333) Server: badhttpserver\r\n
590 590 write(37 from 37) -> (296) Date: $HTTP_DATE$\r\n
591 591 write(41 from 41) -> (255) Content-Type: application/mercurial-0.1\r\n
592 592 write(20 from 20) -> (235) Content-Length: 42\r\n
593 593 write(2 from 2) -> (233) \r\n
594 594 write(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n;
595 595 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
596 596 readline(-1) -> (27) Accept-Encoding: identity\r\n
597 597 readline(-1) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n
598 598 readline(-1) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n
599 599 readline(-1) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
600 600 readline(-1) -> (35) accept: application/mercurial-0.1\r\n
601 601 readline(-1) -> (2?) host: localhost:$HGPORT\r\n (glob)
602 602 readline(-1) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n
603 603 readline(-1) -> (2) \r\n
604 604 write(36 from 36) -> (155) HTTP/1.1 200 Script output follows\r\n
605 605 write(23 from 23) -> (132) Server: badhttpserver\r\n
606 606 write(37 from 37) -> (95) Date: $HTTP_DATE$\r\n
607 607 write(41 from 41) -> (54) Content-Type: application/mercurial-0.2\r\n
608 608 write(28 from 28) -> (26) Transfer-Encoding: chunked\r\n
609 609 write(2 from 2) -> (24) \r\n
610 610 write(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc)
611 611 write(9 from 9) -> (9) 4\r\nnone\r\n
612 612 write(9 from 9) -> (0) 4\r\nHG20\r\n
613 613 write limit reached; closing socket
614 614 write(27) -> 15\r\nInternal Server Error\r\n
615 615
616 616 $ rm -f error.log
617 617
618 618 Server sends partial bundle2 header magic
619 619
620 620 $ hg serve --config badserver.closeaftersendbytes=999 -p $HGPORT -d --pid-file=hg.pid -E error.log
621 621 $ cat hg.pid > $DAEMON_PIDS
622 622
623 623 $ hg clone http://localhost:$HGPORT/ clone
624 624 requesting all changes
625 625 abort: HTTP request error (incomplete response; expected 4 bytes got 3)
626 626 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
627 627 [255]
628 628
629 629 $ killdaemons.py $DAEMON_PIDS
630 630
631 631 $ tail -7 error.log
632 632 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n
633 633 write(2 from 2) -> (21) \r\n
634 634 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
635 635 write(9 from 9) -> (6) 4\r\nnone\r\n
636 636 write(6 from 9) -> (0) 4\r\nHG2
637 637 write limit reached; closing socket
638 638 write(27) -> 15\r\nInternal Server Error\r\n
639 639
640 640 $ rm -f error.log
641 641
642 642 Server sends incomplete bundle2 stream params length
643 643
644 644 $ hg serve --config badserver.closeaftersendbytes=1008 -p $HGPORT -d --pid-file=hg.pid -E error.log
645 645 $ cat hg.pid > $DAEMON_PIDS
646 646
647 647 $ hg clone http://localhost:$HGPORT/ clone
648 648 requesting all changes
649 649 abort: HTTP request error (incomplete response; expected 4 bytes got 3)
650 650 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
651 651 [255]
652 652
653 653 $ killdaemons.py $DAEMON_PIDS
654 654
655 655 $ tail -8 error.log
656 656 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n
657 657 write(2 from 2) -> (30) \r\n
658 658 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
659 659 write(9 from 9) -> (15) 4\r\nnone\r\n
660 660 write(9 from 9) -> (6) 4\r\nHG20\r\n
661 661 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
662 662 write limit reached; closing socket
663 663 write(27) -> 15\r\nInternal Server Error\r\n
664 664
665 665 $ rm -f error.log
666 666
667 667 Servers stops after bundle2 stream params header
668 668
669 669 $ hg serve --config badserver.closeaftersendbytes=1011 -p $HGPORT -d --pid-file=hg.pid -E error.log
670 670 $ cat hg.pid > $DAEMON_PIDS
671 671
672 672 $ hg clone http://localhost:$HGPORT/ clone
673 673 requesting all changes
674 674 abort: HTTP request error (incomplete response)
675 675 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
676 676 [255]
677 677
678 678 $ killdaemons.py $DAEMON_PIDS
679 679
680 680 $ tail -8 error.log
681 681 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n
682 682 write(2 from 2) -> (33) \r\n
683 683 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
684 684 write(9 from 9) -> (18) 4\r\nnone\r\n
685 685 write(9 from 9) -> (9) 4\r\nHG20\r\n
686 686 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
687 687 write limit reached; closing socket
688 688 write(27) -> 15\r\nInternal Server Error\r\n
689 689
690 690 $ rm -f error.log
691 691
692 692 Server stops sending after bundle2 part header length
693 693
694 694 $ hg serve --config badserver.closeaftersendbytes=1020 -p $HGPORT -d --pid-file=hg.pid -E error.log
695 695 $ cat hg.pid > $DAEMON_PIDS
696 696
697 697 $ hg clone http://localhost:$HGPORT/ clone
698 698 requesting all changes
699 699 abort: HTTP request error (incomplete response)
700 700 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
701 701 [255]
702 702
703 703 $ killdaemons.py $DAEMON_PIDS
704 704
705 705 $ tail -9 error.log
706 706 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n
707 707 write(2 from 2) -> (42) \r\n
708 708 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
709 709 write(9 from 9) -> (27) 4\r\nnone\r\n
710 710 write(9 from 9) -> (18) 4\r\nHG20\r\n
711 711 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
712 712 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
713 713 write limit reached; closing socket
714 714 write(27) -> 15\r\nInternal Server Error\r\n
715 715
716 716 $ rm -f error.log
717 717
718 718 Server stops sending after bundle2 part header
719 719
720 720 $ hg serve --config badserver.closeaftersendbytes=1067 -p $HGPORT -d --pid-file=hg.pid -E error.log
721 721 $ cat hg.pid > $DAEMON_PIDS
722 722
723 723 $ hg clone http://localhost:$HGPORT/ clone
724 724 requesting all changes
725 725 adding changesets
726 726 transaction abort!
727 727 rollback completed
728 728 abort: HTTP request error (incomplete response)
729 729 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
730 730 [255]
731 731
732 732 $ killdaemons.py $DAEMON_PIDS
733 733
734 734 $ tail -10 error.log
735 735 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n
736 736 write(2 from 2) -> (89) \r\n
737 737 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
738 738 write(9 from 9) -> (74) 4\r\nnone\r\n
739 739 write(9 from 9) -> (65) 4\r\nHG20\r\n
740 740 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
741 741 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
742 742 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
743 743 write limit reached; closing socket
744 744 write(27) -> 15\r\nInternal Server Error\r\n
745 745
746 746 $ rm -f error.log
747 747
748 748 Server stops after bundle2 part payload chunk size
749 749
750 750 $ hg serve --config badserver.closeaftersendbytes=1088 -p $HGPORT -d --pid-file=hg.pid -E error.log
751 751 $ cat hg.pid > $DAEMON_PIDS
752 752
753 753 $ hg clone http://localhost:$HGPORT/ clone
754 754 requesting all changes
755 755 adding changesets
756 756 transaction abort!
757 757 rollback completed
758 758 abort: HTTP request error (incomplete response; expected 466 bytes got 7)
759 759 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
760 760 [255]
761 761
762 762 $ killdaemons.py $DAEMON_PIDS
763 763
764 764 $ tail -11 error.log
765 765 write(2 from 2) -> (110) \r\n
766 766 write(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
767 767 write(9 from 9) -> (95) 4\r\nnone\r\n
768 768 write(9 from 9) -> (86) 4\r\nHG20\r\n
769 769 write(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
770 770 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
771 771 write(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
772 772 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
773 773 write(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
774 774 write limit reached; closing socket
775 775 write(27) -> 15\r\nInternal Server Error\r\n
776 776
777 777 $ rm -f error.log
778 778
779 779 Server stops sending in middle of bundle2 payload chunk
780 780
781 781 $ hg serve --config badserver.closeaftersendbytes=1549 -p $HGPORT -d --pid-file=hg.pid -E error.log
782 782 $ cat hg.pid > $DAEMON_PIDS
783 783
784 784 $ hg clone http://localhost:$HGPORT/ clone
785 785 requesting all changes
786 786 adding changesets
787 787 transaction abort!
788 788 rollback completed
789 789 abort: HTTP request error (incomplete response)
790 790 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
791 791 [255]
792 792
793 793 $ killdaemons.py $DAEMON_PIDS
794 794
795 795 $ tail -12 error.log
796 796 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n
797 797 write(2 from 2) -> (571) \r\n
798 798 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
799 799 write(9 from 9) -> (556) 4\r\nnone\r\n
800 800 write(9 from 9) -> (547) 4\r\nHG20\r\n
801 801 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
802 802 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
803 803 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
804 804 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
805 805 write(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
806 806 write limit reached; closing socket
807 807 write(27) -> 15\r\nInternal Server Error\r\n
808 808
809 809 $ rm -f error.log
810 810
811 811 Server stops sending after 0 length payload chunk size
812 812
813 813 $ hg serve --config badserver.closeaftersendbytes=1580 -p $HGPORT -d --pid-file=hg.pid -E error.log
814 814 $ cat hg.pid > $DAEMON_PIDS
815 815
816 816 $ hg clone http://localhost:$HGPORT/ clone
817 817 requesting all changes
818 818 adding changesets
819 819 adding manifests
820 820 adding file changes
821 821 added 1 changesets with 1 changes to 1 files
822 822 transaction abort!
823 823 rollback completed
824 824 abort: HTTP request error (incomplete response; expected 32 bytes got 9)
825 825 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
826 826 [255]
827 827
828 828 $ killdaemons.py $DAEMON_PIDS
829 829
830 830 $ tail -13 error.log
831 831 write(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
832 832 write(9 from 9) -> (587) 4\r\nnone\r\n
833 833 write(9 from 9) -> (578) 4\r\nHG20\r\n
834 834 write(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
835 835 write(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
836 836 write(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
837 837 write(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
838 838 write(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
839 839 write(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
840 840 write(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
841 841 write(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
842 842 write limit reached; closing socket
843 843 write(27) -> 15\r\nInternal Server Error\r\n
844 844
845 845 $ rm -f error.log
846 846
847 847 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
848 848 This is before the 0 size chunked transfer part that signals end of HTTP response.
849 849
850 850 # $ hg serve --config badserver.closeaftersendbytes=1755 -p $HGPORT -d --pid-file=hg.pid -E error.log
851 851 $ hg serve --config badserver.closeaftersendbytes=1862 -p $HGPORT -d --pid-file=hg.pid -E error.log
852 852 $ cat hg.pid > $DAEMON_PIDS
853 853
854 854 $ hg clone http://localhost:$HGPORT/ clone
855 855 requesting all changes
856 856 adding changesets
857 857 adding manifests
858 858 adding file changes
859 859 added 1 changesets with 1 changes to 1 files
860 860 new changesets 96ee1d7354c4
861 861 updating to branch default
862 862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 863
864 864 $ killdaemons.py $DAEMON_PIDS
865 865
866 866 $ tail -22 error.log
867 867 write(9 from 9) -> (851) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
868 868 write(9 from 9) -> (842) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
869 869 write(47 from 47) -> (795) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
870 870 write(9 from 9) -> (786) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
871 871 write(473 from 473) -> (313) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
872 872 write(9 from 9) -> (304) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
873 873 write(9 from 9) -> (295) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
874 874 write(38 from 38) -> (257) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
875 875 write(9 from 9) -> (248) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
876 876 write(64 from 64) -> (184) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
877 877 write(9 from 9) -> (175) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
878 878 write(9 from 9) -> (166) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
879 879 write(41 from 41) -> (125) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
880 880 write(9 from 9) -> (116) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
881 881 write(9 from 9) -> (107) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
882 882 write(35 from 35) -> (72) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
883 883 write(9 from 9) -> (63) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
884 884 write(45 from 45) -> (18) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
885 885 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
886 886 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
887 887 write limit reached; closing socket
888 888 write(27) -> 15\r\nInternal Server Error\r\n
889 889
890 890 $ rm -f error.log
891 891 $ rm -rf clone
892 892
893 893 Server sends a size 0 chunked-transfer size without terminating \r\n
894 894
895 895 $ hg serve --config badserver.closeaftersendbytes=1865 -p $HGPORT -d --pid-file=hg.pid -E error.log
896 896 $ cat hg.pid > $DAEMON_PIDS
897 897
898 898 $ hg clone http://localhost:$HGPORT/ clone
899 899 requesting all changes
900 900 adding changesets
901 901 adding manifests
902 902 adding file changes
903 903 added 1 changesets with 1 changes to 1 files
904 904 new changesets 96ee1d7354c4
905 905 updating to branch default
906 906 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
907 907
908 908 $ killdaemons.py $DAEMON_PIDS
909 909
910 910 $ tail -23 error.log
911 911 write(9 from 9) -> (854) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
912 912 write(9 from 9) -> (845) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
913 913 write(47 from 47) -> (798) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
914 914 write(9 from 9) -> (789) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
915 915 write(473 from 473) -> (316) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
916 916 write(9 from 9) -> (307) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
917 917 write(9 from 9) -> (298) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
918 918 write(38 from 38) -> (260) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
919 919 write(9 from 9) -> (251) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
920 920 write(64 from 64) -> (187) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
921 921 write(9 from 9) -> (178) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
922 922 write(9 from 9) -> (169) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
923 923 write(41 from 41) -> (128) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
924 924 write(9 from 9) -> (119) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
925 925 write(9 from 9) -> (110) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
926 926 write(35 from 35) -> (75) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
927 927 write(9 from 9) -> (66) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
928 928 write(45 from 45) -> (21) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
929 929 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
930 930 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
931 931 write(3 from 5) -> (0) 0\r\n
932 932 write limit reached; closing socket
933 933 write(27) -> 15\r\nInternal Server Error\r\n
934 934
935 935 $ rm -f error.log
936 936 $ rm -rf clone
General Comments 0
You need to be logged in to leave comments. Login now