(self)
| 656 | |
| 657 | @gen_test |
| 658 | def test_invalid_methods(self): |
| 659 | # RFC 9110 distinguishes between syntactically invalid methods and those that are |
| 660 | # valid but unknown. The former must give a 400 status code, while the latter should |
| 661 | # give a 405. |
| 662 | test_cases = [ |
| 663 | ("FOO", 405, None), |
| 664 | ("FOO,BAR", 400, ".*Malformed HTTP request line"), |
| 665 | ] |
| 666 | for method, code, log_msg in test_cases: |
| 667 | if log_msg is not None: |
| 668 | expect_log = ExpectLog(gen_log, log_msg, level=logging.INFO) |
| 669 | else: |
| 670 | |
| 671 | @contextmanager |
| 672 | def noop_context(): |
| 673 | yield |
| 674 | |
| 675 | expect_log = noop_context() # type: ignore |
| 676 | with ( |
| 677 | self.subTest(method=method), |
| 678 | closing(IOStream(socket.socket())) as stream, |
| 679 | expect_log, |
| 680 | ): |
| 681 | yield stream.connect(("127.0.0.1", self.get_http_port())) |
| 682 | stream.write(utf8(f"{method} /echo HTTP/1.1\r\nHost:127.0.0.1\r\n\r\n")) |
| 683 | resp = yield stream.read_until(b"\r\n\r\n") |
| 684 | self.assertTrue( |
| 685 | resp.startswith(b"HTTP/1.1 %d" % code), |
| 686 | f"expected status code {code} in {resp!r}", |
| 687 | ) |
| 688 | |
| 689 | |
| 690 | class XHeaderTest(HandlerBaseTestCase): |
nothing calls this directly
no test coverage detected