tests/testlib/badserverext.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 21 Jan 2022 01:07:50 +0100
changeset 48632 caa6694dac45
parent 48631 8039cca948f8
child 48633 f91f98e9834a
permissions -rw-r--r--
test-http-bad-server: track close condition in an object In order to make the logic more advanced, we need to unify it. To unify it, we introduce a small object that will be responsible for tracking and enforcing "premature socket close" conditions for both proxy object (socketproxy and fileobjectproxy). More logic will be moved into the object in later changesets. Differential Revision: https://phab.mercurial-scm.org/D12041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    17
close-before-accept
32001
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
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    21
close-after-accept
32001
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
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    25
close-after-recv-bytes
32001
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
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    28
close-after-send-bytes
32001
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
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    36
from mercurial import (
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
    37
    pycompat,
33193
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    38
    registrar,
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    39
)
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    40
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    41
from mercurial.hgweb import server
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
33193
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    43
configtable = {}
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    44
configitem = registrar.configitem(configtable)
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    45
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    46
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    47
    b'badserver',
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    48
    b'close-after-accept',
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    49
    default=False,
33193
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    50
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    51
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    52
    b'badserver',
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    53
    b'close-after-recv-bytes',
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    54
    default=b'0',
33194
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33193
diff changeset
    55
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    56
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    57
    b'badserver',
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    58
    b'close-after-send-bytes',
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    59
    default=b'0',
33195
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33194
diff changeset
    60
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
    61
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    62
    b'badserver',
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
    63
    b'close-before-accept',
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43076
diff changeset
    64
    default=False,
33196
c077eac329e2 configitems: register the 'badserver.closebeforeaccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33195
diff changeset
    65
)
33193
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    66
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    67
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    68
class ConditionTracker(object):
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    69
    def __init__(self, close_after_recv_bytes, close_after_send_bytes):
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    70
        self._all_close_after_recv_bytes = close_after_recv_bytes
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    71
        self._all_close_after_send_bytes = close_after_send_bytes
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    72
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    73
    def start_next_request(self):
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    74
        """move to the next set of close condition"""
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    75
        if self._all_close_after_recv_bytes:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    76
            self.target_recv_bytes = self._all_close_after_recv_bytes.pop(0)
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    77
            self.remaining_recv_bytes = self.target_recv_bytes
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    78
        else:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    79
            self.target_recv_bytes = None
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    80
            self.remaining_recv_bytes = None
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    81
        if self._all_close_after_send_bytes:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    82
            self.target_send_bytes = self._all_close_after_send_bytes.pop(0)
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    83
            self.remaining_send_bytes = self.target_send_bytes
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    84
        else:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    85
            self.target_send_bytes = None
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    86
            self.remaining_send_bytes = None
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    87
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    88
    def might_close(self):
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    89
        """True, if any processing will be needed"""
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    90
        if self.remaining_recv_bytes is not None:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    91
            return True
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    92
        if self.remaining_send_bytes is not None:
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    93
            return True
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    94
        return False
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    95
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    96
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
# 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
    98
class socketproxy(object):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
    99
    __slots__ = ('_orig', '_logfp', '_cond')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   101
    def __init__(self, obj, logfp, condition_tracked):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
        object.__setattr__(self, '_orig', obj)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   103
        object.__setattr__(self, '_logfp', logfp)
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   104
        object.__setattr__(self, '_cond', condition_tracked)
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   106
    def __getattribute__(self, name):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   107
        if name in ('makefile', 'sendall', '_writelog', '_cond_close'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
            return object.__getattribute__(self, name)
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
        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
   111
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   112
    def __delattr__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   113
        delattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   114
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   115
    def __setattr__(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   116
        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
   117
41480
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   118
    def _writelog(self, msg):
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   119
        msg = msg.replace(b'\r', b'\\r').replace(b'\n', b'\\n')
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   120
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   121
        object.__getattribute__(self, '_logfp').write(msg)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   122
        object.__getattribute__(self, '_logfp').write(b'\n')
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   123
        object.__getattribute__(self, '_logfp').flush()
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   124
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
    def makefile(self, mode, bufsize):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   126
        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
   127
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   128
        logfp = object.__getattribute__(self, '_logfp')
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   129
        cond = object.__getattribute__(self, '_cond')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   130
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   131
        return fileobjectproxy(f, logfp, cond)
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   132
41480
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   133
    def sendall(self, data, flags=0):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   134
        remaining = object.__getattribute__(self, '_cond').remaining_send_bytes
41480
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   135
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   136
        # No read limit. Call original function.
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   137
        if not remaining:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   138
            result = object.__getattribute__(self, '_orig').sendall(data, flags)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   139
            self._writelog(b'sendall(%d) -> %s' % (len(data), data))
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   140
            return result
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   141
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   142
        if len(data) > remaining:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   143
            newdata = data[0:remaining]
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   144
        else:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   145
            newdata = data
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   146
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   147
        remaining -= len(newdata)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   148
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   149
        result = object.__getattribute__(self, '_orig').sendall(newdata, flags)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   150
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   151
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   152
            b'sendall(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   153
            % (len(newdata), len(data), remaining, newdata)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   154
        )
41480
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   155
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   156
        object.__getattribute__(self, '_cond').remaining_send_bytes = remaining
41480
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   157
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   158
        if remaining <= 0:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   159
            self._writelog(b'write limit reached; closing socket')
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   160
            object.__getattribute__(self, '_orig').shutdown(socket.SHUT_RDWR)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   161
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   162
            raise Exception('connection closed after sending N bytes')
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   163
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   164
        return result
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   165
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41478
diff changeset
   166
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   167
# 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
   168
class fileobjectproxy(object):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   169
    __slots__ = ('_orig', '_logfp', '_cond')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   170
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   171
    def __init__(self, obj, logfp, condition_tracked):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   172
        object.__setattr__(self, '_orig', obj)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   173
        object.__setattr__(self, '_logfp', logfp)
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   174
        object.__setattr__(self, '_cond', condition_tracked)
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   175
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   176
    def __getattribute__(self, name):
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   177
        if name in ('_close', 'read', 'readline', 'write', '_writelog'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   178
            return object.__getattribute__(self, name)
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
        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
   181
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   182
    def __delattr__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   183
        delattr(object.__getattribute__(self, '_orig'), name)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   184
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   185
    def __setattr__(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   186
        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
   187
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   188
    def _writelog(self, msg):
41477
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39447
diff changeset
   189
        msg = msg.replace(b'\r', b'\\r').replace(b'\n', b'\\n')
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   190
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   191
        object.__getattribute__(self, '_logfp').write(msg)
41477
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39447
diff changeset
   192
        object.__getattribute__(self, '_logfp').write(b'\n')
32021
08e46fcb8637 badserverext: explicitly flush each log write
Matt Harbison <matt_harbison@yahoo.com>
parents: 32001
diff changeset
   193
        object.__getattribute__(self, '_logfp').flush()
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   194
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   195
    def _close(self):
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   196
        # Python 3 uses an io.BufferedIO instance. Python 2 uses some file
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   197
        # object wrapper.
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   198
        if pycompat.ispy3:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   199
            orig = object.__getattribute__(self, '_orig')
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   200
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   201
            if hasattr(orig, 'raw'):
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   202
                orig.raw._sock.shutdown(socket.SHUT_RDWR)
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   203
            else:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   204
                self.close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   205
        else:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   206
            self._sock.shutdown(socket.SHUT_RDWR)
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   207
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   208
    def read(self, size=-1):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   209
        remaining = object.__getattribute__(self, '_cond').remaining_recv_bytes
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   210
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   211
        # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   212
        if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   213
            result = object.__getattribute__(self, '_orig').read(size)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   214
            self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   215
                b'read(%d) -> (%d) (%s) %s' % (size, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   216
            )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   217
            return result
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
        origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   220
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   221
        if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   222
            size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   223
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   224
            size = min(remaining, size)
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
        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
   227
        remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   228
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   229
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   230
            b'read(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   231
            % (size, origsize, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   232
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   233
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   234
        object.__getattribute__(self, '_cond').remaining_recv_bytes = remaining
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   235
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   236
        if remaining <= 0:
48630
f87b632406a9 test-http-bad-server: align output by using `;`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48628
diff changeset
   237
            self._writelog(b'read limit reached; closing socket')
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   238
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   239
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   240
            # 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
   241
            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
   242
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   243
        return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   244
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   245
    def readline(self, size=-1):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   246
        remaining = object.__getattribute__(self, '_cond').remaining_recv_bytes
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   247
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   248
        # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   249
        if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   250
            result = object.__getattribute__(self, '_orig').readline(size)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   251
            self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   252
                b'readline(%d) -> (%d) %s' % (size, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   253
            )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   254
            return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   255
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   256
        origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   257
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   258
        if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   259
            size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   260
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   261
            size = min(remaining, size)
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
        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
   264
        remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   265
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   266
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   267
            b'readline(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   268
            % (size, origsize, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   269
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   270
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   271
        object.__getattribute__(self, '_cond').remaining_recv_bytes = remaining
32001
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
        if remaining <= 0:
41477
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39447
diff changeset
   274
            self._writelog(b'read limit reached; closing socket')
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   275
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   276
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   277
            # 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
   278
            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
   279
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   280
        return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   281
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   282
    def write(self, data):
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   283
        remaining = object.__getattribute__(self, '_cond').remaining_send_bytes
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   284
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   285
        # 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
   286
        if not remaining:
41477
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39447
diff changeset
   287
            self._writelog(b'write(%d) -> %s' % (len(data), data))
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   288
            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
   289
            return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   290
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   291
        if len(data) > remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   292
            newdata = data[0:remaining]
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   293
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   294
            newdata = data
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   295
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   296
        remaining -= len(newdata)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   297
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   298
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   299
            b'write(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   300
            % (len(newdata), len(data), remaining, newdata)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   301
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   302
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   303
        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
   304
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   305
        object.__getattribute__(self, '_cond').remaining_send_bytes = remaining
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   306
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   307
        if remaining <= 0:
41477
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39447
diff changeset
   308
            self._writelog(b'write limit reached; closing socket')
41478
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   309
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41477
diff changeset
   310
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   311
            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
   312
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   313
        return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   314
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   315
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   316
def process_config(value):
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   317
    parts = value.split(b',')
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   318
    integers = [int(v) for v in parts if v]
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   319
    return [v if v else None for v in integers]
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   320
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   321
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   322
def extsetup(ui):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   323
    # 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
   324
    # 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
   325
    class badserver(server.MercurialHTTPServer):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   326
        def __init__(self, ui, *args, **kwargs):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   327
            self._ui = ui
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   328
            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
   329
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   330
            all_recv_bytes = self._ui.config(
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   331
                b'badserver', b'close-after-recv-bytes'
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   332
            )
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   333
            all_recv_bytes = process_config(all_recv_bytes)
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   334
            all_send_bytes = self._ui.config(
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   335
                b'badserver', b'close-after-send-bytes'
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   336
            )
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   337
            all_send_bytes = process_config(all_send_bytes)
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   338
            self._cond = ConditionTracker(all_recv_bytes, all_send_bytes)
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36425
diff changeset
   339
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   340
            # 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
   341
            class badrequesthandler(self.RequestHandlerClass, object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   342
                def send_header(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   343
                    # Make headers deterministic to facilitate testing.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   344
                    if name.lower() == 'date':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   345
                        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
   346
                    elif name.lower() == 'server':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   347
                        value = 'badhttpserver'
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   348
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   349
                    return super(badrequesthandler, self).send_header(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   350
                        name, value
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   351
                    )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   352
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   353
            self.RequestHandlerClass = badrequesthandler
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   354
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   355
        # Called to accept() a pending socket.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   356
        def get_request(self):
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
   357
            if self._ui.configbool(b'badserver', b'close-before-accept'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   358
                self.socket.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   359
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   360
                # 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
   361
                self.__shutdown_request = True
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   362
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   363
                # 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
   364
                raise socket.error('close before accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   365
48628
ee1235afda4b test-http-bad-server: rename config to use `-`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48627
diff changeset
   366
            if self._ui.configbool(b'badserver', b'close-after-accept'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   367
                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
   368
                request.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   369
                raise socket.error('close after accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   370
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   371
            return super(badserver, self).get_request()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   372
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   373
        # 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
   374
        # 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
   375
        # is a hgweb.server._httprequesthandler.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   376
        def process_request(self, socket, address):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   377
            # Wrap socket in a proxy if we need to count bytes.
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   378
            self._cond.start_next_request()
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   379
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   380
            if self._cond.might_close():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   381
                socket = socketproxy(
48632
caa6694dac45 test-http-bad-server: track close condition in an object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48631
diff changeset
   382
                    socket, self.errorlog, condition_tracked=self._cond
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41480
diff changeset
   383
                )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   384
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   385
            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
   386
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   387
    server.MercurialHTTPServer = badserver