···518518end
519519520520let query_of_encoded = Query.query_of_encoded
521521-let encoded_of_query ?scheme = Query.encoded_of_query ?scheme
521521+let encoded_of_query ?scheme l = Query.encoded_of_query ?scheme l
522522523523(** {1 URI Type} *)
524524···599599600600(** {1 URI to String Conversion} *)
601601602602-let to_string ?(pct_encoder=pct_encoder ()) uri =
602602+let to_string_internal ?(pct_encoder=pct_encoder ()) uri =
603603 let scheme = match uri.scheme with
604604 | Some s -> Some (Pct.uncast_decoded s)
605605 | None -> None in
···669669 );
670670 Buffer.contents buf
671671672672+let to_string uri = to_string_internal uri
673673+672674(** {1 Accessor Functions} *)
673675674676let get_decoded_opt = function None -> None |Some x -> Some (Pct.uncast_decoded x)
···690692 |None -> default
691693 |Some h -> h
692694693693-let userinfo ?(pct_encoder=pct_encoder ()) uri = match uri.userinfo with
695695+let userinfo_internal ?(pct_encoder=pct_encoder ()) uri = match uri.userinfo with
694696 | None -> None
695697 | Some userinfo -> Some (Pct.uncast_encoded (match uri.scheme with
696698 | None -> encoded_of_userinfo ~component:pct_encoder.userinfo userinfo
697699 | Some s -> encoded_of_userinfo ~scheme:(Pct.uncast_decoded s) ~component:pct_encoder.userinfo userinfo))
700700+701701+let userinfo uri = userinfo_internal uri
698702699703let with_userinfo uri userinfo =
700704 let userinfo = match userinfo with
···734738 | Some _ -> { uri with host=Some (`Host (Pct.cast_decoded "")); port=port }
735739 end
736740737737-let path ?(pct_encoder=pct_encoder ()) uri = Pct.uncast_encoded (match uri.scheme with
741741+let path_internal ?(pct_encoder=pct_encoder ()) uri = Pct.uncast_encoded (match uri.scheme with
738742 | None -> encoded_of_path ~component:pct_encoder.path uri.path
739743 | Some s -> encoded_of_path ~scheme:(Pct.uncast_decoded s) ~component:pct_encoder.path uri.path)
744744+745745+let path uri = path_internal uri
740746741747let with_path uri path =
742748 let path = path_of_encoded path in
···13941400 | Ok t -> t
13951401 | Error (`Msg error) -> failwith error
1396140213971397- let to_string ?pct_encoder t = to_uri t |> to_string ?pct_encoder
14031403+ let to_string t = to_uri t |> to_string
1398140413991405 let normalize t =
14001406 { t with
+128-199
ocaml-requests/lib/uri.mli
···1818(** Uniform Resource Identifier handling that is RFC3986-compliant.
19192020 This module provides URI parsing, construction, and manipulation
2121- using Eio.Buf_read combinators for parsing.
2121+ for HTTP clients and servers.
22222323 {2 RFC 3986 Compliance}
24242525 This implementation follows {{:https://tools.ietf.org/html/rfc3986}RFC 3986}
2626- for URI syntax, reference resolution, and normalization. *)
2626+ for URI syntax. *)
2727+2828+(** {1 Types} *)
27292828-(** A single URI that is a compact sequence of characters that identifies
2929- an abstract or physical resource. *)
3030type t
3131+(** A URI: a compact sequence of characters that identifies an abstract
3232+ or physical resource. *)
31333234(** URI component types for percent-encoding customization. *)
3333-type component = [
3434- | `Scheme
3535+type component =
3636+ [ `Scheme
3537 | `Authority
3636- | `Userinfo (** subcomponent of authority in some schemes *)
3737- | `Host (** subcomponent of authority in some schemes *)
3838+ | `Userinfo
3939+ | `Host
3840 | `Path
3941 | `Query
4042 | `Query_key
4143 | `Query_value
4244 | `Fragment
4345 | `Generic
4444- | `Custom of (component * string * string) (** (component * safe chars * unsafe chars) *)
4545-]
4646+ | `Custom of component * string * string ]
46474747-(** For pct encoding customization when converting a URI to a string. *)
4848-type pct_encoder
4949-5050-(** {2 Core functionality } *)
4848+(** {1 Construction and Conversion} *)
51495250val empty : t
5353-(** The empty (zero length) URI reference. Useful for constructing
5454- URIs piece-by-piece. *)
5555-5656-val compare : t -> t -> int
5757-(** Comparator ordering by host, scheme, port, userinfo, path, query,
5858- and finally fragment. Designed to produce a reasonable sort order. *)
5959-6060-val equal : t -> t -> bool
6161-(** [equal a b] is [compare a b = 0]. *)
6262-6363-val pct_encode : ?scheme:string -> ?component:component -> string -> string
6464-(** Percent-encode a string. The [component] argument defaults to `Path *)
5151+(** The empty URI reference. Useful for constructing URIs piece-by-piece. *)
65526666-val pct_encoder :
6767- ?scheme:component ->
6868- ?userinfo:component ->
6969- ?host:component ->
7070- ?path:component ->
7171- ?query_key:component ->
7272- ?query_value:component ->
7373- ?fragment:component ->
5353+val make :
5454+ ?scheme:string ->
5555+ ?userinfo:string ->
5656+ ?host:string ->
5757+ ?port:int ->
5858+ ?path:string ->
5959+ ?query:(string * string list) list ->
6060+ ?fragment:string ->
7461 unit ->
7575- pct_encoder
7676-(** Construct a pct_encoder. *)
7777-7878-val pct_decode : string -> string
7979-(** Percent-decode a percent-encoded string *)
6262+ t
6363+(** Construct a URI from components. If userinfo or port are supplied without
6464+ host, an empty host is added. If path is supplied and authority components
6565+ are also supplied, path is made absolute. *)
80668167val of_string : string -> t
8282-(** Parse a URI string literal into a URI structure. A bare string will be
8383- interpreted as a path; a string prefixed with `//` will be interpreted as a
8484- host. *)
6868+(** Parse a URI string into a URI structure. A bare string is interpreted as
6969+ a path; a string prefixed with [//] is interpreted as a host. *)
85708686-val to_string : ?pct_encoder:pct_encoder -> t -> string
8787-(** Convert a URI structure into a percent-encoded URI string *)
7171+val to_string : t -> string
7272+(** Convert a URI to a percent-encoded string. *)
88738989-val resolve : string -> t -> t -> t
9090-(** [resolve scheme base uri] resolves [uri] against [base] URI using [scheme]
9191- as the default scheme. Per RFC 3986 Section 5. *)
7474+(** {1 Comparison} *)
92759393-val canonicalize : t -> t
9494-(** Canonicalize a URI according to Sec 6.2.3 "Scheme-Based
9595- Normalization". This transform is more aggressive than the
9696- standard URI-generic normalization automatically done. In
9797- particular, HTTP(S) URIs with empty path components will have
9898- their path components set to "/". Some applications like web
9999- servers may rely on the distinction between a path-less and a
100100- root-path URI to distinguish request URIs (e.g. OPTIONS * vs
101101- OPTIONS /).
7676+val compare : t -> t -> int
7777+(** Compare two URIs. Orders by host, scheme, port, userinfo, path, query,
7878+ then fragment. *)
10279103103- @see <https://tools.ietf.org/html/rfc3986#section-6.2.3> RFC 3986.6.2.3
104104-*)
8080+val equal : t -> t -> bool
8181+(** [equal a b] is [compare a b = 0]. *)
10582106106-val make : ?scheme:string -> ?userinfo:string -> ?host:string ->
107107- ?port:int -> ?path:string -> ?query:(string * string list) list ->
108108- ?fragment:string -> unit -> t
109109-(** Make a URI from supplied components. If userinfo or port are
110110- supplied without host, an empty host is added. If path is supplied
111111- and userinfo, host, or port is also supplied, path is made
112112- absolute but not resolved. *)
8383+(** {1 Percent Encoding} *)
11384114114-val with_uri : ?scheme:string option -> ?userinfo:string option ->
115115- ?host:string option -> ?port:int option -> ?path:string option ->
116116- ?query:(string * string list) list option -> ?fragment:string option -> t -> t
117117-(** Functional update for a URI using the supplied components. If a component
118118- is unspecified then it will be unchanged. If a component is supplied as
119119- [None] then the component will be removed in the returned URI. If a
120120- component is supplied as [Some x] then [x] will be added if it does not
121121- exist in the source URI or replaced if it does exist. *)
8585+val pct_encode : ?scheme:string -> ?component:component -> string -> string
8686+(** Percent-encode a string. The [component] argument controls which characters
8787+ are considered safe; defaults to [`Path]. *)
12288123123-(** {2 Query functions }
8989+val pct_decode : string -> string
9090+(** Decode a percent-encoded string. *)
12491125125- The query string API attempts to accommodate conventional query
126126- string representations (i.e. [?key0=value0&key1=value1]) while
127127- maximally exposing any meaning in those representations. For
128128- example, it is not necessarily the case that [/] and [/?] are
129129- equivalent to a web server. In the former case, we observe a zero
130130- query string whereas in the latter case, we observe a query string
131131- with a single key, [""] and a zero value. Compare this with [/?=]
132132- which has a single key and a single empty value,
133133- [""]. Additionally, some query functions return lists of values
134134- for a key. These list values are extracted from a {b single} key
135135- with a comma-separated value list. If a query string has multiple
136136- identical keys, you must use {! query} to retrieve the entirety of
137137- the structured query string.
138138-*)
9292+(** {1 Component Access} *)
13993140140-val query : t -> (string * string list) list
141141-(** Get a query string from a URI *)
9494+val scheme : t -> string option
9595+(** Get the scheme component (e.g., ["http"], ["https"]). *)
14296143143-val verbatim_query : ?pct_encoder:pct_encoder -> t -> string option
144144-(** Get a verbatim query string from a URI. If the provenance of the
145145- URI is a string and its query component has not been updated, this
146146- is the literal query string as parsed. Otherwise, this is the
147147- composition of {!query} and {!encoded_of_query} *)
9797+val userinfo : t -> string option
9898+(** Get the userinfo component (e.g., ["user:password"]). *)
14899149149-val encoded_of_query :
150150- ?scheme:string ->
151151- ?pct_encoder:pct_encoder ->
152152- (string * string list) list ->
153153- string
154154-(** Make a percent-encoded query string from percent-decoded query tuple *)
100100+val host : t -> string option
101101+(** Get the host component. *)
155102156156-val query_of_encoded : string -> (string * string list) list
157157-(** Parse a percent-encoded query string into a percent-decoded query tuple *)
103103+val port : t -> int option
104104+(** Get the port component. *)
158105159159-val with_query : t -> (string * string list) list -> t
160160-(** Replace the query URI with the supplied list.
161161- Input URI is not modified *)
106106+val path : t -> string
107107+(** Get the path component. *)
162108163163-val with_query' : t -> (string * string) list -> t
164164-(** Replace the query URI with the supplied singleton query list.
165165- Input URI is not modified *)
109109+val fragment : t -> string option
110110+(** Get the fragment component. *)
166111167167-val get_query_param' : t -> string -> string list option
168168-(** [get_query_param' q key] returns the list of values for the
169169- [key] parameter in query [q]. Note that an empty list is not the
170170- same as a [None] return value. *)
112112+val path_and_query : t -> string
113113+(** Get the combined path and query string, suitable for HTTP request lines. *)
171114172172-val get_query_param: t -> string -> string option
173173-(** [get_query_param q key] returns the value found for a [key] in
174174- query [q]. If there are multiple values for the key, then the
175175- first one is returned. *)
115115+(** {1 Component Modification} *)
176116177177-val add_query_param : t -> (string * string list) -> t
178178-(** Add a query parameter to the input query URI.
179179- Input URI is not modified *)
117117+val with_scheme : t -> string option -> t
118118+(** Return a new URI with the scheme replaced. *)
180119181181-val add_query_param' : t -> (string * string) -> t
182182-(** Add a query parameter to the input singleton query URI.
183183- Input URI is not modified *)
120120+val with_userinfo : t -> string option -> t
121121+(** Return a new URI with the userinfo replaced. Adds an empty host if none
122122+ is present. *)
184123185185-val add_query_params : t -> (string * string list) list -> t
186186-(** Add a query parameter list to the input query URI.
187187- Input URI is not modified *)
188188-189189-val add_query_params' : t -> (string * string) list -> t
190190-(** Add a query singleton parameter list to the input query URI.
191191- Input URI is not modified *)
192192-193193-val remove_query_param : t -> string -> t
194194-(** Remove a query key from the input query URI.
195195- Input URI is not modified, and no error is generated if the
196196- key does not already exist in the URI. *)
197197-198198-(** {2 Component getters and setters } *)
199199-200200-val path : ?pct_encoder:pct_encoder -> t -> string
201201-(** Get the encoded path component of a URI *)
124124+val with_host : t -> string option -> t
125125+(** Return a new URI with the host replaced. *)
202126203203-val path_and_query : t -> string
204204-(** Get the encoded path and query components of a URI *)
127127+val with_port : t -> int option -> t
128128+(** Return a new URI with the port replaced. Adds an empty host if none
129129+ is present. *)
205130206131val with_path : t -> string -> t
207207-(** Replace the path URI with the supplied encoded path.
208208- If a host is present in the supplied URI, the path is made absolute but not
209209- resolved. If the path is empty, the path component is removed.
210210- Input URI is not modified *)
132132+(** Return a new URI with the path replaced. If a host is present, the path
133133+ is made absolute. An empty path removes the path component. *)
211134212212-val scheme : t -> string option
213213-(** Get the scheme component of a URI *)
135135+val with_fragment : t -> string option -> t
136136+(** Return a new URI with the fragment replaced. *)
214137215215-val with_scheme : t -> string option -> t
216216-(** Replace the scheme portion of the URI with the supplied [scheme].
217217- Input URI is not modified *)
138138+(** {1 Query String} *)
218139219219-val userinfo : ?pct_encoder:pct_encoder -> t -> string option
220220-(** Get the userinfo component of a URI *)
140140+val query : t -> (string * string list) list
141141+(** Get the query parameters as a list of key-value pairs. Each key may have
142142+ multiple values. *)
221143222222-val with_userinfo : t -> string option -> t
223223-(** Replace the userinfo portion of the URI with the supplied [string option].
224224- If no host is present in the supplied URI, an empty host is added.
225225- Input URI is not modified. *)
144144+val encoded_of_query : ?scheme:string -> (string * string list) list -> string
145145+(** Encode query parameters to a percent-encoded query string. *)
226146227227-val user : t -> string option
228228-(** Get the username component of a URI *)
147147+val with_query : t -> (string * string list) list -> t
148148+(** Return a new URI with the query parameters replaced. *)
229149230230-val password : t -> string option
231231-(** Get the password component of a URI *)
150150+val get_query_param : t -> string -> string option
151151+(** [get_query_param uri key] returns the first value for [key], or [None]. *)
232152233233-val with_password : t -> string option -> t
234234-(** Replace the password portion of the URI with the supplied [string option].
235235- If no host is present in the supplied URI, an empty host is added.
236236- Input URI is not modified. *)
153153+val add_query_param : t -> string * string list -> t
154154+(** Add a query parameter (key with potentially multiple values). *)
237155238238-val host : t -> string option
239239-(** Get the host component of a URI *)
156156+val add_query_param' : t -> string * string -> t
157157+(** Add a single-valued query parameter. *)
240158241241-val with_host: t -> string option -> t
242242-(** Replace the host component of the URI.
243243- Input URI is not modified. *)
159159+val add_query_params : t -> (string * string list) list -> t
160160+(** Add multiple query parameters. *)
244161245245-val host_with_default: ?default:string -> t -> string
246246-(** Get the host component of a URI, with a default supplied if one is
247247- not present *)
162162+val remove_query_param : t -> string -> t
163163+(** Remove all values for a query key. *)
248164249249-val port : t -> int option
250250-(** Get the port component of a URI *)
165165+(** {1 Reference Resolution} *)
251166252252-val with_port : t -> int option -> t
253253-(** Replace the port component of the URI with the supplied port.
254254- If no host is present in the supplied URI, an empty host is added.
255255- Input URI is not modified. *)
256256-257257-val fragment : t -> string option
258258-(** Get the fragment component of a URI *)
259259-260260-val with_fragment : t -> string option -> t
261261-(** Replace the fragment component of a URI with the supplied fragment.
262262- Input URI is not modified *)
167167+val resolve : string -> t -> t -> t
168168+(** [resolve scheme base uri] resolves [uri] against [base] using [scheme]
169169+ as the default scheme. Per RFC 3986 Section 5. Used for handling relative
170170+ redirect URLs. *)
263171264264-(** {2 Formatters } *)
172172+(** {1 Formatting} *)
265173266174val pp : Format.formatter -> t -> unit
267267-(** [pp ppf t] will output a human readable version of the Uri [t]
268268- to the formatter [ppf] *)
175175+(** Pretty-print a URI. *)
269176270270-val pp_hum : Format.formatter -> t -> unit
271271-(** [pp_hum] is now an alias for the {!pp} function. *)
177177+(** {1 Parsing}
272178273273-(** {2 Buf_read Parsers}
179179+ Buf_read parsers for streaming URI parsing. *)
274180275275- These parsers use Eio.Buf_read for efficient streaming parsing. *)
276181module Parser : sig
277182 val ipv6 : Eio.Buf_read.t -> string
278183 (** Parse an IPv6 address (without brackets). *)
···281186 (** Parse a complete URI reference. *)
282187end
283188284284-(** Specializations for HTTP and HTTPS schemes as per RFC9110 *)
189189+(** {1 HTTP URIs}
190190+191191+ Specializations for HTTP and HTTPS schemes as per RFC 9110. These ensure
192192+ the URI has a valid scheme and host for HTTP requests. *)
193193+285194module Absolute_http : sig
286195 type uri := t
196196+287197 type t
198198+ (** An absolute HTTP or HTTPS URI with a required host. *)
288199289200 val of_uri : uri -> (t, [ `Msg of string ]) result
201201+ (** Convert a generic URI to an HTTP URI. Fails if scheme is not http/https
202202+ or if host is missing. *)
203203+290204 val to_uri : t -> uri
205205+ (** Convert back to a generic URI. *)
291206292207 val of_string : string -> t
293293- val to_string : ?pct_encoder:pct_encoder -> t -> string
208208+ (** Parse a string as an HTTP URI. Raises on invalid input. *)
294209295295- val make : scheme:[ `Http | `Https ]-> host:string ->
296296- ?userinfo:string -> ?port:int -> ?path:string ->
297297- ?query:(string * string list) list -> ?fragment:string -> unit -> t
210210+ val to_string : t -> string
211211+ (** Convert to a percent-encoded string. *)
212212+213213+ val make :
214214+ scheme:[ `Http | `Https ] ->
215215+ host:string ->
216216+ ?userinfo:string ->
217217+ ?port:int ->
218218+ ?path:string ->
219219+ ?query:(string * string list) list ->
220220+ ?fragment:string ->
221221+ unit ->
222222+ t
223223+ (** Construct an HTTP URI. *)
224224+225225+ val scheme : t -> [ `Http | `Https ]
226226+ (** Get the scheme. *)
298227299228 val host : t -> string
300300- val scheme : t -> [`Http | `Https]
229229+ (** Get the host (always present for HTTP URIs). *)
301230end