tests/badserverext.py
author Kyle Lippincott <spectral@google.com>
Thu, 02 Jan 2020 11:04:18 -0800
branchstable
changeset 44247 c443b9ba6f63
parent 43076 2372284d9457
child 45942 89a2afe31e82
permissions -rw-r--r--
py3: __repr__ needs to return str, not bytes Differential Revision: https://phab.mercurial-scm.org/D8089
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
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
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    36
from mercurial import (
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
    37
    pycompat,
33191
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: 41466
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
33191
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: 41466
diff changeset
    46
configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    47
    b'badserver', b'closeafteraccept', default=False,
33191
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    48
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    49
configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    50
    b'badserver', b'closeafterrecvbytes', default=b'0',
33192
c538fca0d511 configitems: register the 'badserver.closeafterrecvbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33191
diff changeset
    51
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    52
configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    53
    b'badserver', b'closeaftersendbytes', default=b'0',
33193
cbb50fd830ea configitems: register the 'badserver.closeaftersendbytes' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33192
diff changeset
    54
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    55
configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    56
    b'badserver', b'closebeforeaccept', default=False,
33194
c077eac329e2 configitems: register the 'badserver.closebeforeaccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33193
diff changeset
    57
)
33191
8065b4ab0ed7 configitems: register the 'badserver.closeafteraccept' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32021
diff changeset
    58
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
# 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
    60
class socketproxy(object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
    __slots__ = (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
        '_orig',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
        '_logfp',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
        '_closeafterrecvbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
        '_closeaftersendbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
    )
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    68
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    69
        self, obj, logfp, closeafterrecvbytes=0, closeaftersendbytes=0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    70
    ):
32001
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):
41466
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
    77
        if name in ('makefile', 'sendall', '_writelog'):
32001
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
41466
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
    88
    def _writelog(self, msg):
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
    89
        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: 41464
diff changeset
    90
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
    91
        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: 41464
diff changeset
    92
        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: 41464
diff changeset
    93
        object.__getattribute__(self, '_logfp').flush()
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
    94
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
    def makefile(self, mode, bufsize):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
        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
    97
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    98
        logfp = object.__getattribute__(self, '_logfp')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
    99
        closeafterrecvbytes = object.__getattribute__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   100
            self, '_closeafterrecvbytes'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   101
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   102
        closeaftersendbytes = object.__getattribute__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   103
            self, '_closeaftersendbytes'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   104
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   106
        return fileobjectproxy(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   107
            f,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   108
            logfp,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   109
            closeafterrecvbytes=closeafterrecvbytes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   110
            closeaftersendbytes=closeaftersendbytes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   111
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   112
41466
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   113
    def sendall(self, data, flags=0):
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   114
        remaining = object.__getattribute__(self, '_closeaftersendbytes')
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   115
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   116
        # 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: 41464
diff changeset
   117
        if not remaining:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   118
            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: 41464
diff changeset
   119
            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: 41464
diff changeset
   120
            return result
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   121
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   122
        if len(data) > remaining:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   123
            newdata = data[0:remaining]
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   124
        else:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   125
            newdata = data
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   126
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   127
        remaining -= len(newdata)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   128
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   129
        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: 41464
diff changeset
   130
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   131
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   132
            b'sendall(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   133
            % (len(newdata), len(data), remaining, newdata)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   134
        )
41466
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   135
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   136
        object.__setattr__(self, '_closeaftersendbytes', remaining)
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   137
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   138
        if remaining <= 0:
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   139
            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: 41464
diff changeset
   140
            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: 41464
diff changeset
   141
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   142
            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: 41464
diff changeset
   143
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   144
        return result
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   145
4d5aae86c9bd tests: log sendall() operations and port test-http-bad-server.t
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41464
diff changeset
   146
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   147
# 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
   148
class fileobjectproxy(object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   149
    __slots__ = (
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   150
        '_orig',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   151
        '_logfp',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   152
        '_closeafterrecvbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   153
        '_closeaftersendbytes',
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   154
    )
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   155
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   156
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   157
        self, obj, logfp, closeafterrecvbytes=0, closeaftersendbytes=0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   158
    ):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   159
        object.__setattr__(self, '_orig', obj)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   160
        object.__setattr__(self, '_logfp', logfp)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   161
        object.__setattr__(self, '_closeafterrecvbytes', closeafterrecvbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   162
        object.__setattr__(self, '_closeaftersendbytes', closeaftersendbytes)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   163
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   164
    def __getattribute__(self, name):
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   165
        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
   166
            return object.__getattribute__(self, name)
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 getattr(object.__getattribute__(self, '_orig'), name)
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 __delattr__(self, name):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   171
        delattr(object.__getattribute__(self, '_orig'), name)
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
    def __setattr__(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   174
        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
   175
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   176
    def _writelog(self, msg):
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   177
        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
   178
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   179
        object.__getattribute__(self, '_logfp').write(msg)
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   180
        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
   181
        object.__getattribute__(self, '_logfp').flush()
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   182
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   183
    def _close(self):
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   184
        # 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: 41463
diff changeset
   185
        # object wrapper.
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   186
        if pycompat.ispy3:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   187
            orig = object.__getattribute__(self, '_orig')
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   188
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   189
            if hasattr(orig, 'raw'):
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   190
                orig.raw._sock.shutdown(socket.SHUT_RDWR)
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   191
            else:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   192
                self.close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   193
        else:
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   194
            self._sock.shutdown(socket.SHUT_RDWR)
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   195
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   196
    def read(self, size=-1):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   197
        remaining = object.__getattribute__(self, '_closeafterrecvbytes')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   198
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   199
        # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   200
        if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   201
            result = object.__getattribute__(self, '_orig').read(size)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   202
            self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   203
                b'read(%d) -> (%d) (%s) %s' % (size, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   204
            )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   205
            return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   206
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   207
        origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   208
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   209
        if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   210
            size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   211
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   212
            size = min(remaining, size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   213
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   214
        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
   215
        remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   216
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   217
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   218
            b'read(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   219
            % (size, origsize, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   220
        )
32001
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
        object.__setattr__(self, '_closeafterrecvbytes', remaining)
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
        if remaining <= 0:
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   225
            self._writelog(b'read limit reached, closing socket')
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   226
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   227
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   228
            # 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
   229
            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
   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 readline(self, size=-1):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   234
        remaining = object.__getattribute__(self, '_closeafterrecvbytes')
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
        # No read limit. Call original function.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   237
        if not remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   238
            result = object.__getattribute__(self, '_orig').readline(size)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   239
            self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   240
                b'readline(%d) -> (%d) %s' % (size, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   241
            )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   242
            return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   243
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   244
        origsize = size
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   245
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   246
        if size < 0:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   247
            size = remaining
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   248
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   249
            size = min(remaining, size)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   250
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   251
        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
   252
        remaining -= len(result)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   253
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   254
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   255
            b'readline(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   256
            % (size, origsize, len(result), result)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   257
        )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   258
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   259
        object.__setattr__(self, '_closeafterrecvbytes', remaining)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   260
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   261
        if remaining <= 0:
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   262
            self._writelog(b'read limit reached; closing socket')
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   263
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   264
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   265
            # 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
   266
            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
   267
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   268
        return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   269
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   270
    def write(self, data):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   271
        remaining = object.__getattribute__(self, '_closeaftersendbytes')
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
        # 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
   274
        if not remaining:
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   275
            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
   276
            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
   277
            return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   278
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   279
        if len(data) > remaining:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   280
            newdata = data[0:remaining]
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   281
        else:
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   282
            newdata = data
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   283
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   284
        remaining -= len(newdata)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   285
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   286
        self._writelog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   287
            b'write(%d from %d) -> (%d) %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   288
            % (len(newdata), len(data), remaining, newdata)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   289
        )
32001
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
        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
   292
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   293
        object.__setattr__(self, '_closeaftersendbytes', remaining)
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   294
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   295
        if remaining <= 0:
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   296
            self._writelog(b'write limit reached; closing socket')
41464
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   297
            self._close()
d343d9ac173e tests: change how sockets are closed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41463
diff changeset
   298
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   299
            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
   300
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   301
        return result
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   302
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   303
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   304
def extsetup(ui):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   305
    # 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
   306
    # 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
   307
    class badserver(server.MercurialHTTPServer):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   308
        def __init__(self, ui, *args, **kwargs):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   309
            self._ui = ui
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   310
            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
   311
39428
cbfab495dbcf py3: add missing b'' prefixes in tests/badserverext.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 37498
diff changeset
   312
            recvbytes = self._ui.config(b'badserver', b'closeafterrecvbytes')
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   313
            recvbytes = recvbytes.split(b',')
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   314
            self.closeafterrecvbytes = [int(v) for v in recvbytes if v]
39428
cbfab495dbcf py3: add missing b'' prefixes in tests/badserverext.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 37498
diff changeset
   315
            sendbytes = self._ui.config(b'badserver', b'closeaftersendbytes')
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   316
            sendbytes = sendbytes.split(b',')
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   317
            self.closeaftersendbytes = [int(v) for v in sendbytes if v]
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   318
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   319
            # 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
   320
            class badrequesthandler(self.RequestHandlerClass, object):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   321
                def send_header(self, name, value):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   322
                    # Make headers deterministic to facilitate testing.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   323
                    if name.lower() == 'date':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   324
                        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
   325
                    elif name.lower() == 'server':
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   326
                        value = 'badhttpserver'
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   327
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   328
                    return super(badrequesthandler, self).send_header(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   329
                        name, value
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   330
                    )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   331
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   332
            self.RequestHandlerClass = badrequesthandler
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   333
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   334
        # Called to accept() a pending socket.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   335
        def get_request(self):
39428
cbfab495dbcf py3: add missing b'' prefixes in tests/badserverext.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 37498
diff changeset
   336
            if self._ui.configbool(b'badserver', b'closebeforeaccept'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   337
                self.socket.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   338
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   339
                # 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
   340
                self.__shutdown_request = True
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   341
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   342
                # 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
   343
                raise socket.error('close before accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   344
41463
ba7298160357 tests: add b'' prefixes to badserverext.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39428
diff changeset
   345
            if self._ui.configbool(b'badserver', b'closeafteraccept'):
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   346
                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
   347
                request.close()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   348
                raise socket.error('close after accept')
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   349
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   350
            return super(badserver, self).get_request()
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   351
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   352
        # 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
   353
        # 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
   354
        # is a hgweb.server._httprequesthandler.
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   355
        def process_request(self, socket, address):
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   356
            # Wrap socket in a proxy if we need to count bytes.
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   357
            if self.closeafterrecvbytes:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   358
                closeafterrecvbytes = self.closeafterrecvbytes.pop(0)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   359
            else:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   360
                closeafterrecvbytes = 0
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   361
            if self.closeaftersendbytes:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   362
                closeaftersendbytes = self.closeaftersendbytes.pop(0)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   363
            else:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 36395
diff changeset
   364
                closeaftersendbytes = 0
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   365
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   366
            if closeafterrecvbytes or closeaftersendbytes:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   367
                socket = socketproxy(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   368
                    socket,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   369
                    self.errorlog,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   370
                    closeafterrecvbytes=closeafterrecvbytes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   371
                    closeaftersendbytes=closeaftersendbytes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41466
diff changeset
   372
                )
32001
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   373
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   374
            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
   375
c85f19c66e8d tests: add tests for poorly behaving HTTP server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   376
    server.MercurialHTTPServer = badserver