Source code for runtimepy.net.http.state
"""
A module implementing an HTTP-header processing state interface.
"""
# built-in
from dataclasses import dataclass
from typing import Optional, TypeVar
# third-party
from vcorelib import DEFAULT_ENCODING
from vcorelib.io import ByteFifo
# internal
from runtimepy.net.http.common import HeadersMixin
T = TypeVar("T", bound=HeadersMixin)
[docs]
@dataclass
class HeaderProcessingState:
    """A container for header-related processing state."""
    lines: list[str]
    line: str
[docs]
    @staticmethod
    def create() -> "HeaderProcessingState":
        """Create a default instance."""
        return HeaderProcessingState([], "")
[docs]
    def service(self, buffer: ByteFifo, kind: type[T]) -> Optional[T]:
        """
        Continue processing the input fifo as if it contains request-header
        data.
        """
        result = None
        while result is None and buffer.size:
            curr_raw = buffer.pop(1)
            if curr_raw is not None:
                curr = curr_raw.decode(encoding=DEFAULT_ENCODING)
                # Any '\r\n' sequence signifies the end of a header line.
                if curr == "\n":
                    if self.line:
                        self.lines.append(self.line)
                        self.line = ""
                    # Two sequences in a row signifies the end of the header
                    # section.
                    else:
                        result = kind()
                        result.from_lines(self.lines)
                        self.lines = []
                elif curr != "\r":
                    self.line += curr
        return result
