blob: 63c8f97f35bd96d58345f3c132b353b8a398ecf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""Check that tools/serve.py splits a CGI response at the right place.

A CGI response ends its header block at the first blank line. cgit writes its
own headers with bare LF endings, so a body carrying a CRLF blank line, which
any commit message written on DOS does, must not be mistaken for that end.
Getting it wrong takes the document head into the header block, and the page
that reaches the browser then has no stylesheet and no chrome. Run with the
repository root as the only argument.
"""

import importlib.util
import sys


def load_serve(root):
    path = root + "/tools/serve.py"
    spec = importlib.util.spec_from_file_location("serve", path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


def main():
    split = load_serve(sys.argv[1]).split_cgi_output
    cases = (
        (
            "bare LF headers, CRLF blank line inside the body",
            b"Content-Type: text/html\n\n<!DOCTYPE html>\nmsg\r\n\r\ntail",
            200,
            [("Content-Type", "text/html")],
            b"<!DOCTYPE html>\nmsg\r\n\r\ntail",
        ),
        (
            "CRLF headers, LF blank line inside the body",
            b"Content-Type: text/plain\r\nX: y\r\n\r\nline\n\nline2",
            200,
            [("Content-Type", "text/plain"), ("X", "y")],
            b"line\n\nline2",
        ),
        (
            "a status line is taken off the headers",
            b"Status: 404 Not Found\nContent-Type: text/html\n\nnope",
            404,
            [("Content-Type", "text/html")],
            b"nope",
        ),
        (
            "an empty body survives, as a redirect leaves one",
            b"Status: 302 Found\nLocation: /x\n\n",
            302,
            [("Location", "/x")],
            b"",
        ),
        (
            "output with no blank line at all is all headers",
            b"Content-Type: text/html\n",
            200,
            [("Content-Type", "text/html")],
            b"",
        ),
    )

    failed = 0
    for name, raw, status, headers, body in cases:
        got = split(raw)
        if (got.status, got.headers, got.body) == (status, headers, body):
            continue
        failed += 1
        sys.stderr.write(
            "%s\n  expected %r\n  got      %r\n"
            % (name, (status, headers, body), (got.status, got.headers, got.body))
        )
    return 1 if failed else 0


sys.exit(main())