(** Parser combinators for HTTP/1.1 parsing. *) (** Parse error with detailed status. Alias for {!Err.Parse_error}. *) exception Parse_error of Buf_read.status (** Parser state holding buffer and length. *) type pstate = { buf : Base_bigstring.t; len : int } (** {1 Core Functions} *) (** Create parser state from buffer and length *) val make : Base_bigstring.t -> len:int -> pstate (** Remaining bytes at position *) val remaining : pstate -> pos:int -> int (** Check if at end of buffer *) val at_end : pstate -> pos:int -> bool (** {1 Basic Combinators} *) (** Peek current char without advancing. Raises [Partial] if at end. *) val peek_char : pstate -> pos:int -> char (** Peek char at offset from current position. Raises [Partial] if out of bounds. *) val peek_at : pstate -> pos:int -> int -> char (** Match single character, return new position. Raises [Partial] or [Malformed]. *) val char : char -> pstate -> pos:int -> int (** Match literal string, return new position. Raises [Partial] or [Malformed]. *) val string : string -> pstate -> pos:int -> int (** Take chars while predicate holds, return span and new position. *) val take_while : (char -> bool) -> pstate -> pos:int -> Span.t * int (** Skip chars while predicate holds, return new position. *) val skip_while : (char -> bool) -> pstate -> pos:int -> int (** Take exactly n chars as span, return span and new position. Raises [Partial]. *) val take : int -> pstate -> pos:int -> Span.t * int (** Skip exactly n chars, return new position. Raises [Partial]. *) val skip : int -> pstate -> pos:int -> int (** Match char satisfying predicate, return char and new position. *) val satisfy : (char -> bool) -> pstate -> pos:int -> char * int (** Try parser, return None and original pos on failure. *) val optional : (pstate -> pos:int -> 'a * int) -> pstate -> pos:int -> 'a option * int (** {1 HTTP-Specific Combinators} *) (** Match CRLF (\\r\\n), return new position. *) val crlf : pstate -> pos:int -> int (** Match SP (space), return new position. *) val sp : pstate -> pos:int -> int (** Take HTTP token chars (for method, header names), return span and new position. Must be non-empty. Raises [Malformed] if empty. *) val token : pstate -> pos:int -> Span.t * int (** Skip optional whitespace (OWS = SP / HTAB), return new position. *) val ows : pstate -> pos:int -> int (** Parse HTTP version (HTTP/1.0 or HTTP/1.1), return version and new position. *) val http_version : pstate -> pos:int -> Version.t * int (** Parse HTTP method from token, return method and new position. *) val parse_method : pstate -> pos:int -> Method.t * int (** Parse request target, return span and new position. Raises [Invalid_target] if empty. *) val parse_target : pstate -> pos:int -> Span.t * int (** Parse request line: METHOD SP target SP version CRLF. Returns (method, target_span, version, new_pos). *) val request_line : pstate -> pos:int -> Method.t * Span.t * Version.t * int (** Parse a single header line. Returns (header_name, name_span, value_span, new_pos). *) val parse_header : pstate -> pos:int -> Header_name.t * Span.t * Span.t * int (** Check if at end of headers (CRLF at current position). *) val is_headers_end : pstate -> pos:int -> bool (** Skip the empty line at end of headers, return new position. *) val end_headers : pstate -> pos:int -> int