annotate tests/badserverext.py @ 36755:ff4bc0ab6740 stable

wireproto: check permissions when executing "batch" command (BC) (SEC) For as long as the "batch" command has existed (introduced by bd88561afb4b and first released as part of Mercurial 1.9), that command (like most wire commands introduced after 2008) lacked an entry in the hgweb permissions table. And since we don't verify permissions if an entry is missing from the permissions table, this meant that executing a command via "batch" would bypass all permissions checks. The security implications are significant: a Mercurial HTTP server would allow writes via "batch" wire protocol commands as long as the HTTP request were processed by Mercurial and the process running the Mercurial HTTP server had write access to the repository. The Mercurial defaults of servers being read-only and the various web.* config options to define access control were bypassed. In addition, "batch" could be used to exfiltrate data from servers that were configured to not allow read access. Both forms of permissions bypass could be mitigated to some extent by using HTTP authentication. This would prevent HTTP requests from hitting Mercurial's server logic. However, any authenticated request would still be able to bypass permissions checks via "batch" commands. The easiest exploit was to send "pushkey" commands via "batch" and modify the state of bookmarks, phases, and obsolescence markers. However, I suspect a well-crafted HTTP request could trick the server into running the "unbundle" wire protocol command, effectively performing a full `hg push` to create new changesets on the remote. This commit plugs this gaping security hole by having the "batch" command perform permissions checking on each sub-command that is being batched. We do this by threading a permissions checking callable all the way to the protocol handler. The threading is a bit hacky from a code perspective. But it preserves API compatibility, which is the proper thing to do on the stable branch. One of the subtle things we do is assume that a command with an undefined permission is a "push" command. This is the safest thing to do from a security perspective: we don't want to take chances that a command could perform a write even though the server is configured to not allow writes. As the test changes demonstrate, it is no longer possible to bypass permissions via the "batch" wire protocol command. .. bc:: The "batch" wire protocol command now enforces permissions of each invoked sub-command. Wire protocol commands must define their operation type or the "batch" command will assume they can write data and will prevent their execution on HTTP servers unless the HTTP request method is POST, the server is configured to allow pushes, and the (possibly authenticated) HTTP user is authorized to perform a push.
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 20 Feb 2018 18:55:58 -0800
parents c077eac329e2
children fb7897e53d49
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 # badserverext.py - Extension making servers behave badly
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
2 #
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
3 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
4 #
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
7
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
8 # no-check-code
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
9
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
10 """Extension to make servers behave badly.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
11
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
12 This extension is useful for testing Mercurial behavior when various network
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
13 events occur.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
14
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
15 Various config options in the [badserver] section influence behavior:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
16
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
17 closebeforeaccept
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
18 If true, close() the server socket when a new connection arrives before
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
19 accept() is called. The server will then exit.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
20
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
21 closeafteraccept
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
22 If true, the server will close() the client socket immediately after
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
23 accept().
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
24
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
25 closeafterrecvbytes
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
26 If defined, close the client socket after receiving this many bytes.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
27
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
28 closeaftersendbytes
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
29 If defined, close the client socket after sending this many bytes.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
30 """
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
31
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
32 from __future__ import absolute_import
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
33
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
34 import socket
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
35
33191
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
36 from mercurial import(
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
37 registrar,
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
38 )
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
39
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
40 from mercurial.hgweb import (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
41 server,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
42 )
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
43
33191
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
44 configtable = {}
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
45 configitem = registrar.configitem(configtable)
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
46
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
47 configitem('badserver', 'closeafteraccept',
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
48 default=False,
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
49 )
33192
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33191
diff changeset
50 configitem('badserver', 'closeafterrecvbytes',
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33191
diff changeset
51 default=0,
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33191
diff changeset
52 )
33193
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33192
diff changeset
53 configitem('badserver', 'closeaftersendbytes',
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33192
diff changeset
54 default=0,
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33192
diff changeset
55 )
33194
c077eac329e2 configitems: register the 'badserver.closebeforeaccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33193
diff changeset
56 configitem('badserver', 'closebeforeaccept',
c077eac329e2 configitems: register the 'badserver.closebeforeaccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33193
diff changeset
57 default=False,
c077eac329e2 configitems: register the 'badserver.closebeforeaccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33193
diff changeset
58 )
33191
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
59
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
60 # We can't adjust __class__ on a socket instance. So we define a proxy type.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
61 class socketproxy(object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
62 __slots__ = (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
63 '_orig',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
64 '_logfp',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
65 '_closeafterrecvbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
66 '_closeaftersendbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
67 )
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
68
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
69 def __init__(self, obj, logfp, closeafterrecvbytes=0,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
70 closeaftersendbytes=0):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
71 object.__setattr__(self, '_orig', obj)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
72 object.__setattr__(self, '_logfp', logfp)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
73 object.__setattr__(self, '_closeafterrecvbytes', closeafterrecvbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
74 object.__setattr__(self, '_closeaftersendbytes', closeaftersendbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
75
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
76 def __getattribute__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
77 if name in ('makefile',):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
78 return object.__getattribute__(self, name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
79
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
80 return getattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
81
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
82 def __delattr__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
83 delattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
84
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
85 def __setattr__(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
86 setattr(object.__getattribute__(self, '_orig'), name, value)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
87
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
88 def makefile(self, mode, bufsize):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
89 f = object.__getattribute__(self, '_orig').makefile(mode, bufsize)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
90
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
91 logfp = object.__getattribute__(self, '_logfp')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
92 closeafterrecvbytes = object.__getattribute__(self,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
93 '_closeafterrecvbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
94 closeaftersendbytes = object.__getattribute__(self,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
95 '_closeaftersendbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
96
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
97 return fileobjectproxy(f, logfp,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
98 closeafterrecvbytes=closeafterrecvbytes,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
99 closeaftersendbytes=closeaftersendbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
100
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
101 # We can't adjust __class__ on socket._fileobject, so define a proxy.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
102 class fileobjectproxy(object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
103 __slots__ = (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
104 '_orig',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
105 '_logfp',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
106 '_closeafterrecvbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
107 '_closeaftersendbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
108 )
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
109
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
110 def __init__(self, obj, logfp, closeafterrecvbytes=0,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
111 closeaftersendbytes=0):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
112 object.__setattr__(self, '_orig', obj)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
113 object.__setattr__(self, '_logfp', logfp)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
114 object.__setattr__(self, '_closeafterrecvbytes', closeafterrecvbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
115 object.__setattr__(self, '_closeaftersendbytes', closeaftersendbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
116
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
117 def __getattribute__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
118 if name in ('read', 'readline', 'write', '_writelog'):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
119 return object.__getattribute__(self, name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
120
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
121 return getattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
122
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
123 def __delattr__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
124 delattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
125
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
126 def __setattr__(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
127 setattr(object.__getattribute__(self, '_orig'), name, value)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
128
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
129 def _writelog(self, msg):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
130 msg = msg.replace('\r', '\\r').replace('\n', '\\n')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
131
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
132 object.__getattribute__(self, '_logfp').write(msg)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
133 object.__getattribute__(self, '_logfp').write('\n')
32021
08e46fcb8637 badserverext: explicitly flush each log write
Matt Harbison <matt_harbison@yahoo.com>
parents: 32001
diff changeset
134 object.__getattribute__(self, '_logfp').flush()
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
135
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
136 def read(self, size=-1):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
137 remaining = object.__getattribute__(self, '_closeafterrecvbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
138
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
139 # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
140 if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
141 result = object.__getattribute__(self, '_orig').read(size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
142 self._writelog('read(%d) -> (%d) (%s) %s' % (size,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
143 len(result),
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
144 result))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
145 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
147 origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
148
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150 size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
151 else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152 size = min(remaining, size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
154 result = object.__getattribute__(self, '_orig').read(size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155 remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
157 self._writelog('read(%d from %d) -> (%d) %s' % (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 size, origsize, len(result), result))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
160 object.__setattr__(self, '_closeafterrecvbytes', remaining)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
161
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
162 if remaining <= 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
163 self._writelog('read limit reached, closing socket')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
164 self._sock.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
165 # This is the easiest way to abort the current request.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
166 raise Exception('connection closed after receiving N bytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
170 def readline(self, size=-1):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 remaining = object.__getattribute__(self, '_closeafterrecvbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 result = object.__getattribute__(self, '_orig').readline(size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
176 self._writelog('readline(%d) -> (%d) %s' % (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 size, len(result), result))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
180 origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182 if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
183 size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
184 else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
185 size = min(remaining, size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
186
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
187 result = object.__getattribute__(self, '_orig').readline(size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
188 remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
189
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
190 self._writelog('readline(%d from %d) -> (%d) %s' % (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
191 size, origsize, len(result), result))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
192
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
193 object.__setattr__(self, '_closeafterrecvbytes', remaining)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
194
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
195 if remaining <= 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
196 self._writelog('read limit reached; closing socket')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
197 self._sock.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
198 # This is the easiest way to abort the current request.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
199 raise Exception('connection closed after receiving N bytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
200
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
201 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
202
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
203 def write(self, data):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
204 remaining = object.__getattribute__(self, '_closeaftersendbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
205
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206 # No byte limit on this operation. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
207 if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
208 self._writelog('write(%d) -> %s' % (len(data), data))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
209 result = object.__getattribute__(self, '_orig').write(data)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
210 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
211
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
212 if len(data) > remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213 newdata = data[0:remaining]
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
214 else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215 newdata = data
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
217 remaining -= len(newdata)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219 self._writelog('write(%d from %d) -> (%d) %s' % (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
220 len(newdata), len(data), remaining, newdata))
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
221
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222 result = object.__getattribute__(self, '_orig').write(newdata)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224 object.__setattr__(self, '_closeaftersendbytes', remaining)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
226 if remaining <= 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227 self._writelog('write limit reached; closing socket')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 self._sock.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229 raise Exception('connection closed after sending N bytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 def extsetup(ui):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 # Change the base HTTP server class so various events can be performed.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235 # See SocketServer.BaseServer for how the specially named methods work.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236 class badserver(server.MercurialHTTPServer):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237 def __init__(self, ui, *args, **kwargs):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 self._ui = ui
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 super(badserver, self).__init__(ui, *args, **kwargs)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
240
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
241 # Need to inherit object so super() works.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
242 class badrequesthandler(self.RequestHandlerClass, object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
243 def send_header(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
244 # Make headers deterministic to facilitate testing.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
245 if name.lower() == 'date':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
246 value = 'Fri, 14 Apr 2017 00:00:00 GMT'
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
247 elif name.lower() == 'server':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
248 value = 'badhttpserver'
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
249
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
250 return super(badrequesthandler, self).send_header(name,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251 value)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 self.RequestHandlerClass = badrequesthandler
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
254
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
255 # Called to accept() a pending socket.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256 def get_request(self):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 if self._ui.configbool('badserver', 'closebeforeaccept'):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 self.socket.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
259
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
260 # Tells the server to stop processing more requests.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
261 self.__shutdown_request = True
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
262
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 # Simulate failure to stop processing this request.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264 raise socket.error('close before accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
265
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266 if self._ui.configbool('badserver', 'closeafteraccept'):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 request, client_address = super(badserver, self).get_request()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268 request.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269 raise socket.error('close after accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271 return super(badserver, self).get_request()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273 # Does heavy lifting of processing a request. Invokes
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274 # self.finish_request() which calls self.RequestHandlerClass() which
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275 # is a hgweb.server._httprequesthandler.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
276 def process_request(self, socket, address):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277 # Wrap socket in a proxy if we need to count bytes.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278 closeafterrecvbytes = self._ui.configint('badserver',
33192
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33191
diff changeset
279 'closeafterrecvbytes')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 closeaftersendbytes = self._ui.configint('badserver',
33193
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33192
diff changeset
281 'closeaftersendbytes')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
282
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283 if closeafterrecvbytes or closeaftersendbytes:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284 socket = socketproxy(socket, self.errorlog,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285 closeafterrecvbytes=closeafterrecvbytes,
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286 closeaftersendbytes=closeaftersendbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
287
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 return super(badserver, self).process_request(socket, address)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
290 server.MercurialHTTPServer = badserver