(
self,
method: Optional[str] = None,
uri: Optional[str] = None,
version: str = "HTTP/1.0",
headers: Optional[HTTPHeaders] = None,
body: Optional[bytes] = None,
host: Optional[str] = None,
files: Optional[Dict[str, List["HTTPFile"]]] = None,
connection: Optional["HTTPConnection"] = None,
start_line: Optional["RequestStartLine"] = None,
server_connection: Optional[object] = None,
)
| 489 | _body_future = None # type: Future[None] |
| 490 | |
| 491 | def __init__( |
| 492 | self, |
| 493 | method: Optional[str] = None, |
| 494 | uri: Optional[str] = None, |
| 495 | version: str = "HTTP/1.0", |
| 496 | headers: Optional[HTTPHeaders] = None, |
| 497 | body: Optional[bytes] = None, |
| 498 | host: Optional[str] = None, |
| 499 | files: Optional[Dict[str, List["HTTPFile"]]] = None, |
| 500 | connection: Optional["HTTPConnection"] = None, |
| 501 | start_line: Optional["RequestStartLine"] = None, |
| 502 | server_connection: Optional[object] = None, |
| 503 | ) -> None: |
| 504 | if start_line is not None: |
| 505 | method, uri, version = start_line |
| 506 | self.method = method |
| 507 | self.uri = uri |
| 508 | self.version = version |
| 509 | self.headers = headers or HTTPHeaders() |
| 510 | self.body = body or b"" |
| 511 | |
| 512 | # set remote IP and protocol |
| 513 | context = getattr(connection, "context", None) |
| 514 | self.remote_ip = getattr(context, "remote_ip", None) |
| 515 | self.protocol = getattr(context, "protocol", "http") |
| 516 | |
| 517 | try: |
| 518 | self.host = host or self.headers["Host"] |
| 519 | except KeyError: |
| 520 | if version == "HTTP/1.0": |
| 521 | # HTTP/1.0 does not require the Host header. |
| 522 | self.host = "127.0.0.1" |
| 523 | else: |
| 524 | raise HTTPInputError("Missing Host header") |
| 525 | if not _ABNF.host.fullmatch(self.host): |
| 526 | raise HTTPInputError("Invalid Host header: %r" % self.host) |
| 527 | if "," in self.host: |
| 528 | # https://www.rfc-editor.org/rfc/rfc9112.html#name-request-target |
| 529 | # Server MUST respond with 400 Bad Request if multiple |
| 530 | # Host headers are present. |
| 531 | # |
| 532 | # We test for the presence of a comma instead of the number of |
| 533 | # headers received because a proxy may have converted |
| 534 | # multiple headers into a single comma-separated value |
| 535 | # (per RFC 9110 section 5.3). |
| 536 | # |
| 537 | # This is technically a departure from the RFC since the ABNF |
| 538 | # does not forbid commas in the host header. However, since |
| 539 | # commas are not allowed in DNS names, it is appropriate to |
| 540 | # disallow them. (The same argument could be made for other special |
| 541 | # characters, but commas are the most problematic since they could |
| 542 | # be used to exploit differences between proxies when multiple headers |
| 543 | # are supplied). |
| 544 | raise HTTPInputError("Multiple host headers not allowed: %r" % self.host) |
| 545 | self.host_name = split_host_and_port(self.host.lower())[0] |
| 546 | self.files = files or {} |
| 547 | self.connection = connection |
| 548 | self.server_connection = server_connection |
nothing calls this directly
no test coverage detected