tests/get-with-headers.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Sat, 10 Jul 2021 17:19:07 +0200
changeset 47582 6bceecb28806
parent 47500 23f5ed6dbcb1
child 48875 6000f5b25c9b
permissions -rwxr-xr-x
windows: make sure we fully read and cleanly close the connection Maybe this will prevent server on Windows to sometimes complains about the client closing the connection too soon. So we make sure we read everything and we officially close the connection. Hopefully Windows will be happier and the test will stop being flaky. Differential Revision: https://phab.mercurial-scm.org/D11073
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47500
23f5ed6dbcb1 run-tests: stop writing a `python3` symlink pointing to python2
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45830
diff changeset
     1
#!/usr/bin/env python
2532
84655f721f39 Add a test for getting raw files via the web UI.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     2
8447
d5ebcf8f6855 tests: fix doc string in get-with-headers.py
Martin Geisler <mg@lazybytes.net>
parents: 7544
diff changeset
     3
"""This does HTTP GET requests given a host:port and path and returns
2532
84655f721f39 Add a test for getting raw files via the web UI.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     4
a subset of the headers plus the body of the result."""
84655f721f39 Add a test for getting raw files via the web UI.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     5
36576
cfd0c1df5e33 get-with-headers: use bytes stdout thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 36276
diff changeset
     6
from __future__ import absolute_import
27296
8e86679d8acd tests: use absolute_import in /get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25208
diff changeset
     7
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
     8
import argparse
27296
8e86679d8acd tests: use absolute_import in /get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25208
diff changeset
     9
import json
8e86679d8acd tests: use absolute_import in /get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25208
diff changeset
    10
import os
8e86679d8acd tests: use absolute_import in /get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25208
diff changeset
    11
import sys
7054
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    12
29455
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    13
from mercurial import (
40154
fe11fc7e541f py3: encode JSON str to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36576
diff changeset
    14
    pycompat,
29455
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    15
    util,
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    16
)
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    17
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    18
httplib = util.httplib
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28726
diff changeset
    19
7054
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    20
try:
27296
8e86679d8acd tests: use absolute_import in /get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25208
diff changeset
    21
    import msvcrt
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    22
7054
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    23
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    24
    msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    25
except ImportError:
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    26
    pass
e837f2294643 get-with-headers: fix stream modes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5561
diff changeset
    27
36576
cfd0c1df5e33 get-with-headers: use bytes stdout thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 36276
diff changeset
    28
stdout = getattr(sys.stdout, 'buffer', sys.stdout)
cfd0c1df5e33 get-with-headers: use bytes stdout thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 36276
diff changeset
    29
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    30
parser = argparse.ArgumentParser()
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    31
parser.add_argument('--twice', action='store_true')
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    32
parser.add_argument('--headeronly', action='store_true')
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    33
parser.add_argument('--json', action='store_true')
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    34
parser.add_argument('--hgproto')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    35
parser.add_argument(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    36
    '--requestheader',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    37
    nargs='*',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    38
    default=[],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    39
    help='Send an additional HTTP request header. Argument '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    40
    'value is <header>=<value>',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    41
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    42
parser.add_argument('--bodyfile', help='Write HTTP response body to a file')
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    43
parser.add_argument('host')
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    44
parser.add_argument('path')
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    45
parser.add_argument('show', nargs='*')
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    46
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    47
args = parser.parse_args()
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    48
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    49
twice = args.twice
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    50
headeronly = args.headeronly
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    51
formatjson = args.json
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
    52
hgproto = args.hgproto
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    53
requestheaders = args.requestheader
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29455
diff changeset
    54
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    55
tag = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    56
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    57
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    58
def request(host, path, show):
17017
953faba28e91 tests: prepare get-with-headers.py for MSYS
Mads Kiilerich <mads@kiilerich.com>
parents: 12250
diff changeset
    59
    assert not path.startswith('/'), path
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    60
    global tag
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    61
    headers = {}
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    62
    if tag:
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    63
        headers['If-None-Match'] = tag
30764
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29455
diff changeset
    64
    if hgproto:
e75463e3179f protocol: send application/mercurial-0.2 responses to capable clients
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29455
diff changeset
    65
        headers['X-HgProto-1'] = hgproto
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 2532
diff changeset
    66
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    67
    for header in requestheaders:
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    68
        key, value = header.split('=', 1)
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    69
        headers[key] = value
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    70
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    71
    conn = httplib.HTTPConnection(host)
17017
953faba28e91 tests: prepare get-with-headers.py for MSYS
Mads Kiilerich <mads@kiilerich.com>
parents: 12250
diff changeset
    72
    conn.request("GET", '/' + path, None, headers)
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    73
    response = conn.getresponse()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    74
    stdout.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    75
        b'%d %s\n' % (response.status, response.reason.encode('ascii'))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    76
    )
18380
a4d7fd7ad1f7 serve: don't send any content headers with 304 responses
Mads Kiilerich <madski@unity3d.com>
parents: 17017
diff changeset
    77
    if show[:1] == ['-']:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    78
        show = sorted(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    79
            h for h, v in response.getheaders() if h.lower() not in show
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    80
        )
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    81
    for h in [h.lower() for h in show]:
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
    82
        if response.getheader(h, None) is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    83
            stdout.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    84
                b"%s: %s\n"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    85
                % (h.encode('ascii'), response.getheader(h).encode('ascii'))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
    86
            )
47582
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
    87
    if headeronly:
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
    88
        # still read the body to prevent windows to be unhappy about that
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
    89
        # (this might some flakyness in test-hgweb-filelog.t on Windows)
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
    90
        data = response.read()
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
    91
    else:
36576
cfd0c1df5e33 get-with-headers: use bytes stdout thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 36276
diff changeset
    92
        stdout.write(b'\n')
23409
dc4d2cd3aa3e hgweb: send proper HTTP response after uncaught exception
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19865
diff changeset
    93
        data = response.read()
24543
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
    94
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    95
        if args.bodyfile:
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    96
            bodyfh = open(args.bodyfile, 'wb')
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    97
        else:
36576
cfd0c1df5e33 get-with-headers: use bytes stdout thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 36276
diff changeset
    98
            bodyfh = stdout
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
    99
24543
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   100
        # Pretty print JSON. This also has the beneficial side-effect
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   101
        # of verifying emitted JSON is well-formed.
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   102
        if formatjson:
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   103
            # json.dumps() will print trailing newlines. Eliminate them
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   104
            # to make tests easier to write.
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   105
            data = pycompat.json_loads(data)
24543
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   106
            lines = json.dumps(data, sort_keys=True, indent=2).splitlines()
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   107
            for line in lines:
40154
fe11fc7e541f py3: encode JSON str to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36576
diff changeset
   108
                bodyfh.write(pycompat.sysbytes(line.rstrip()))
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
   109
                bodyfh.write(b'\n')
24543
747401086a38 get-with-headers: support parsing and pretty printing JSON
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23409
diff changeset
   110
        else:
35781
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
   111
            bodyfh.write(data)
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
   112
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
   113
        if args.bodyfile:
c6ef8e841873 tests: teach get-with-headers.py some new tricks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35780
diff changeset
   114
            bodyfh.close()
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   115
31791
39f6333e968c tests: store ETag when using --headeronly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30764
diff changeset
   116
    if twice and response.getheader('ETag', None):
39f6333e968c tests: store ETag when using --headeronly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30764
diff changeset
   117
        tag = response.getheader('ETag')
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   118
47582
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
   119
    # further try to please the windows-flakyness deity
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
   120
    conn.close()
6bceecb28806 windows: make sure we fully read and cleanly close the connection
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47500
diff changeset
   121
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   122
    return response.status
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   123
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40154
diff changeset
   124
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
   125
status = request(args.host, args.path, args.show)
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   126
if twice:
35780
32317f8bbe2a tests: use argparse in get-with-headers.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31791
diff changeset
   127
    status = request(args.host, args.path, args.show)
12182
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   128
1121af239761 tests: extend get-with-headers to support cache testing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10905
diff changeset
   129
if 200 <= status <= 305:
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 2532
diff changeset
   130
    sys.exit(0)
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 2532
diff changeset
   131
sys.exit(1)