"""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 and the name of one case. """ import importlib.util import sys # Loading serve.py would otherwise leave a __pycache__ directory behind in # tools/, compiled bytecode the repository has no use for. sys.dont_write_bytecode = True 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 # Each case names the raw output, then the status, headers and body it should # split into. CASES = { "crlf-in-body": ( b"Content-Type: text/html\n\n\nmsg\r\n\r\ntail", 200, [("Content-Type", "text/html")], b"\nmsg\r\n\r\ntail", ), "lf-in-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", ), "status": ( b"Status: 404 Not Found\nContent-Type: text/html\n\nnope", 404, [("Content-Type", "text/html")], b"nope", ), "empty-body": ( b"Status: 302 Found\nLocation: /x\n\n", 302, [("Location", "/x")], b"", ), "no-blank-line": ( b"Content-Type: text/html\n", 200, [("Content-Type", "text/html")], b"", ), } def main(): root, name = sys.argv[1:] raw, status, headers, body = CASES[name] got = load_serve(root).split_cgi_output(raw) if (got.status, got.headers, got.body) == (status, headers, body): return 0 sys.stderr.write( "expected %r\ngot %r\n" % ((status, headers, body), (got.status, got.headers, got.body)) ) return 1 sys.exit(main())