Пример #1
0
 def expect_handler(self):
     """
     Handler for Expect Header.
     """
     expect = self.request.headers.get(EXPECT_HEADER)
     if self.request.version == "1.1":
         if expect.lower() == "100-continue":
             self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
         else:
             self.write_error(
                 HeaderExpectationFailed(f"Unknown Expect: {expect}"))
Пример #2
0
    async def http1_request_header(self):
        """
        Receive and parse request header into self.request.
        """
        HEADER_MAX_SIZE = min(8192, self.request_max_size)
        # Receive until full header is in buffer
        buf = self.recv_buffer
        pos = 0

        while True:
            pos = buf.find(b"\r\n\r\n", pos)
            if pos != -1:
                break

            pos = max(0, len(buf) - 3)
            if pos >= HEADER_MAX_SIZE:
                break

            await self._receive_more()

        if pos >= HEADER_MAX_SIZE:
            raise PayloadTooLarge("Request header exceeds the size limit")

        # Parse header content
        try:
            head = buf[:pos]
            raw_headers = head.decode(errors="surrogateescape")
            reqline, *split_headers = raw_headers.split("\r\n")
            method, self.url, protocol = reqline.split(" ")

            if protocol == "HTTP/1.1":
                self.keep_alive = True
            elif protocol == "HTTP/1.0":
                self.keep_alive = False
            else:
                raise Exception  # Raise a Bad Request on try-except

            self.head_only = method.upper() == "HEAD"
            request_body = False
            headers = []

            for name, value in (h.split(":", 1) for h in split_headers):
                name, value = h = name.lower(), value.lstrip()

                if name in ("content-length", "transfer-encoding"):
                    request_body = True
                elif name == "connection":
                    self.keep_alive = value.lower() == "keep-alive"

                headers.append(h)
        except Exception:
            raise InvalidUsage("Bad Request")

        headers_instance = Header(headers)
        self.upgrade_websocket = (headers_instance.get(
            "upgrade", "").lower() == "websocket")

        # Prepare a Request object
        request = self.protocol.request_class(
            url_bytes=self.url.encode(),
            headers=headers_instance,
            head=bytes(head),
            version=protocol[5:],
            method=method,
            transport=self.protocol.transport,
            app=self.protocol.app,
        )

        # Prepare for request body
        self.request_bytes_left = self.request_bytes = 0
        if request_body:
            headers = request.headers
            expect = headers.get("expect")

            if expect is not None:
                if expect.lower() == "100-continue":
                    self.expecting_continue = True
                else:
                    raise HeaderExpectationFailed(f"Unknown Expect: {expect}")

            if headers.get("transfer-encoding") == "chunked":
                self.request_body = "chunked"
                pos -= 2  # One CRLF stays in buffer
            else:
                self.request_body = True
                self.request_bytes_left = self.request_bytes = int(
                    headers["content-length"])

        # Remove header and its trailing CRLF
        del buf[:pos + 4]
        self.stage = Stage.HANDLER
        self.request, request.stream = request, self
        self.protocol.state["requests_count"] += 1