An OCaml webserver, but the allocating version (vs httpz which doesnt)
1(** Parser combinators for HTTP/1.1 parsing. *)
2
3(** Parse error with detailed status. Alias for {!Err.Parse_error}. *)
4exception Parse_error of Buf_read.status
5
6(** Parser state holding buffer and length. *)
7type pstate = { buf : Base_bigstring.t; len : int }
8
9(** {1 Core Functions} *)
10
11(** Create parser state from buffer and length *)
12val make : Base_bigstring.t -> len:int -> pstate
13
14(** Remaining bytes at position *)
15val remaining : pstate -> pos:int -> int
16
17(** Check if at end of buffer *)
18val at_end : pstate -> pos:int -> bool
19
20(** {1 Basic Combinators} *)
21
22(** Peek current char without advancing. Raises [Partial] if at end. *)
23val peek_char : pstate -> pos:int -> char
24
25(** Peek char at offset from current position. Raises [Partial] if out of bounds. *)
26val peek_at : pstate -> pos:int -> int -> char
27
28(** Match single character, return new position. Raises [Partial] or [Malformed]. *)
29val char : char -> pstate -> pos:int -> int
30
31(** Match literal string, return new position. Raises [Partial] or [Malformed]. *)
32val string : string -> pstate -> pos:int -> int
33
34(** Take chars while predicate holds, return span and new position. *)
35val take_while : (char -> bool) -> pstate -> pos:int -> Span.t * int
36
37(** Skip chars while predicate holds, return new position. *)
38val skip_while : (char -> bool) -> pstate -> pos:int -> int
39
40(** Take exactly n chars as span, return span and new position. Raises [Partial]. *)
41val take : int -> pstate -> pos:int -> Span.t * int
42
43(** Skip exactly n chars, return new position. Raises [Partial]. *)
44val skip : int -> pstate -> pos:int -> int
45
46(** Match char satisfying predicate, return char and new position. *)
47val satisfy : (char -> bool) -> pstate -> pos:int -> char * int
48
49(** Try parser, return None and original pos on failure. *)
50val optional : (pstate -> pos:int -> 'a * int) -> pstate -> pos:int -> 'a option * int
51
52(** {1 HTTP-Specific Combinators} *)
53
54(** Match CRLF (\\r\\n), return new position. *)
55val crlf : pstate -> pos:int -> int
56
57(** Match SP (space), return new position. *)
58val sp : pstate -> pos:int -> int
59
60(** Take HTTP token chars (for method, header names), return span and new position.
61 Must be non-empty. Raises [Malformed] if empty. *)
62val token : pstate -> pos:int -> Span.t * int
63
64(** Skip optional whitespace (OWS = SP / HTAB), return new position. *)
65val ows : pstate -> pos:int -> int
66
67(** Parse HTTP version (HTTP/1.0 or HTTP/1.1), return version and new position. *)
68val http_version : pstate -> pos:int -> Version.t * int
69
70(** Parse HTTP method from token, return method and new position. *)
71val parse_method : pstate -> pos:int -> Method.t * int
72
73(** Parse request target, return span and new position. Raises [Invalid_target] if empty. *)
74val parse_target : pstate -> pos:int -> Span.t * int
75
76(** Parse request line: METHOD SP target SP version CRLF.
77 Returns (method, target_span, version, new_pos). *)
78val request_line : pstate -> pos:int -> Method.t * Span.t * Version.t * int
79
80(** Parse a single header line.
81 Returns (header_name, name_span, value_span, new_pos). *)
82val parse_header : pstate -> pos:int -> Header_name.t * Span.t * Span.t * int
83
84(** Check if at end of headers (CRLF at current position). *)
85val is_headers_end : pstate -> pos:int -> bool
86
87(** Skip the empty line at end of headers, return new position. *)
88val end_headers : pstate -> pos:int -> int