URI Structure #
This module defines an HTTP-oriented URI structure aligned with RFC 3986 and RFC 9110, including schemes, authorities, paths, queries, fragments, and request targets.
Host handling is intentionally strict: this module accepts IPv4, bracketed IPv6, and DNS-style
domain names (LDH labels). RFC 3986 reg-name forms that are not DNS-compatible are rejected.
All text components use the encoding types from Std.Http.URI.Encoding to ensure proper
percent-encoding is maintained throughout.
References:
Proposition that s is a valid URI scheme per RFC 3986:
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ).
The scheme value stored in this module is normalized to lowercase.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.1
Equations
- One or more equations did not get rendered due to their size.
Instances For
URI scheme identifier (e.g., "http", "https", "ftp").
Equations
Instances For
Equations
- Std.Http.URI.instInhabitedScheme = { default := ⟨"http", Std.Http.URI.instInhabitedScheme._proof_4⟩ }
Attempts to create a Scheme from a string, normalizing to lowercase.
Returns none if the scheme is invalid per RFC 3986 Section 3.1.
Equations
- Std.Http.URI.Scheme.ofString? s = if h : Std.Http.URI.IsValidScheme s.toLower then some ⟨s.toLower, h⟩ else none
Instances For
Creates a Scheme from a string, normalizing to lowercase. Panics if invalid.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Returns the URI scheme for a given port: "https" for 443, "http" otherwise.
Equations
- Std.Http.URI.Scheme.ofPort port = if (port == 443) = true then ⟨"https", Std.Http.URI.Scheme.ofPort._proof_1✝⟩ else ⟨"http", Std.Http.URI.Scheme.ofPort._proof_2✝⟩
Instances For
User information component containing an encoded username and optional encoded password.
The stored strings use URI userinfo percent-encoding so parsed URIs can be rendered without
losing percent-encoding choices (for example, %3A versus :).
Note: embedding passwords in URIs is deprecated per RFC 9110 Section 4.2.4. Avoid using the password field in new code, and never include it in logs or error messages.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.1
- username : EncodedUserInfo
The encoded username.
- password : Option EncodedUserInfo
The optional encoded password.
Instances For
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Equations
Builds a UserInfo value from raw strings by applying userinfo percent-encoding.
Equations
- Std.Http.URI.UserInfo.ofStrings username password = { username := Std.Http.URI.EncodedUserInfo.encode username, password := Std.Http.URI.EncodedUserInfo.encode <$> password }
Instances For
Returns the decoded password when present, or none if absent or decoding fails UTF-8 validation.
Equations
Instances For
Checks whether a single domain label is valid. A label must be non-empty, contain only ASCII
alphanumeric characters and -, cannot start or end with -, and must be at most 63 characters.
References:
- https://www.rfc-editor.org/rfc/rfc1034.html#section-3.5
- https://www.rfc-editor.org/rfc/rfc1123.html#section-2.1
Equations
- One or more equations did not get rendered due to their size.
Instances For
Proposition that asserts s is a valid dot-separated domain name.
Each label must satisfy IsValidDomainLabel, and the full name must be at most 255 characters.
Equations
Instances For
A domain name represented as a validated, lowercase-normalized string.
Only ASCII alphanumeric characters, hyphens, and dots are allowed.
Each label cannot start or end with - and is limited to 63 characters.
Internationalized domain names must be converted to punycode before use.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2
Equations
Instances For
Attempts to create a normalized domain name from a string.
Returns none if the name is empty, longer than 255 characters, or any label violates DNS label
constraints.
Equations
Instances For
Host component of a URI, supporting domain names and IP addresses.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2
- name
(name : DomainName)
: Host
A domain name (lowercase-normalized).
- ipv4
(ipv4 : Net.IPv4Addr)
: Host
An IPv4 address.
- ipv6
(ipv6 : Net.IPv6Addr)
: Host
An IPv6 address.
Instances For
Equations
Instances For
Equations
Equations
- Std.Http.URI.instBEqHost.beq (Std.Http.URI.Host.name a) (Std.Http.URI.Host.name b) = (a == b)
- Std.Http.URI.instBEqHost.beq (Std.Http.URI.Host.ipv4 a) (Std.Http.URI.Host.ipv4 b) = (a == b)
- Std.Http.URI.instBEqHost.beq (Std.Http.URI.Host.ipv6 a) (Std.Http.URI.Host.ipv6 b) = (a == b)
- Std.Http.URI.instBEqHost.beq x✝¹ x✝ = false
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Authority port representation, preserving the distinction between:
- no port separator (
example.com) - empty port (
example.com:) - numeric port (
example.com:443)
- omitted : Port
No
:port separator is present (for example,example.com). - empty : Port
A
:port separator is present with no digits after it (for example,example.com:). - value
(port : UInt16)
: Port
A numeric port value is present (for example,
example.com:443).
Instances For
Equations
Instances For
Equations
- Std.Http.URI.instReprPort = { reprPrec := Std.Http.URI.instReprPort.repr }
Equations
- One or more equations did not get rendered due to their size.
- Std.Http.URI.instReprPort.repr Std.Http.URI.Port.omitted prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Std.Http.URI.Port.omitted")).group prec✝
- Std.Http.URI.instReprPort.repr Std.Http.URI.Port.empty prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Std.Http.URI.Port.empty")).group prec✝
Instances For
Equations
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.omitted Std.Http.URI.Port.omitted = isTrue ⋯
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.omitted Std.Http.URI.Port.empty = isFalse Std.Http.URI.instDecidableEqPort.decEq._proof_1✝
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.omitted (Std.Http.URI.Port.value port) = isFalse ⋯
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.empty Std.Http.URI.Port.omitted = isFalse Std.Http.URI.instDecidableEqPort.decEq._proof_3✝
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.empty Std.Http.URI.Port.empty = isTrue ⋯
- Std.Http.URI.instDecidableEqPort.decEq Std.Http.URI.Port.empty (Std.Http.URI.Port.value port) = isFalse ⋯
- Std.Http.URI.instDecidableEqPort.decEq (Std.Http.URI.Port.value port) Std.Http.URI.Port.omitted = isFalse ⋯
- Std.Http.URI.instDecidableEqPort.decEq (Std.Http.URI.Port.value port) Std.Http.URI.Port.empty = isFalse ⋯
- Std.Http.URI.instDecidableEqPort.decEq (Std.Http.URI.Port.value a) (Std.Http.URI.Port.value b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
Instances For
The authority component of a URI, identifying the network location of the resource.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2
Optional user information (username and password).
- host : Host
The host identifying the network location.
- port : Port
Port component, preserving whether it is omitted (
example.com), explicitly empty (example.com:), or numeric (example.com:443).
Instances For
Equations
Instances For
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Hierarchical path component of a URI. Each segment is stored as an EncodedSegment to maintain
proper percent-encoding.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3
- segments : Array EncodedSegment
The path segments making up the hierarchical structure (each segment is percent-encoded).
- absolute : Bool
Whether the path is absolute (begins with '/') or relative.
Instances For
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Std.Http.URI.instReprPath = { reprPrec := Std.Http.URI.instReprPath.repr }
Equations
Equations
- One or more equations did not get rendered due to their size.
Joins two paths. If the second path is absolute, it is returned as-is. Otherwise, the second path's segments are appended to the first path.
Equations
Instances For
Appends an already-encoded segment to the path.
Instances For
Removes dot segments from the path according to RFC 3986 Section 5.2.4. This handles "." (current directory) and ".." (parent directory) segments.
Equations
Instances For
Returns the path segments as decoded strings. Segments that cannot be decoded as UTF-8 are returned as their raw encoded form.
Equations
- p.toDecodedSegments = Array.map (fun (seg : Std.Http.URI.EncodedSegment) => seg.decode.getD (toString seg)) p.segments
Instances For
Query string represented as an array of key-value pairs. Both keys and values are stored as
EncodedQueryParam for proper application/x-www-form-urlencoded encoding. Values are optional to
support parameters without values (e.g., "?flag"). Order is preserved based on insertion order.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.4
Equations
Instances For
Equations
- Std.Http.URI.instReprQuery = { reprPrec := Std.Http.URI.instReprQuery._aux_1 }
Equations
Equations
Extracts all unique query parameter names.
Equations
Instances For
Extracts all query parameter values.
Equations
- query.values = Array.map (fun (p : Std.Http.URI.EncodedQueryParam × Option Std.Http.URI.EncodedQueryParam) => p.snd) query
Instances For
Returns the query as an array of (key, value) pairs. This is an identity function since Query is already an array of pairs.
Instances For
Formats a query parameter as a string in the format "key" or "key=value". The key and value are
already percent-encoded as EncodedQueryParam.
Equations
Instances For
Finds the first value of a query parameter by key name. Returns none if the key is not found.
The value remains encoded as EncodedQueryParam.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Finds the first value of a query parameter by raw key string. The key is percent-encoded before matching. This avoids aliasing between raw and pre-encoded spellings.
Equations
- query.find? key = query.findEncoded? (Std.Http.URI.EncodedQueryParam.encode key)
Instances For
Finds all values of a query parameter by key name. Returns an empty array if the key is not found.
The values remain encoded as EncodedQueryParam.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Finds all values of a query parameter by raw key string. The key is percent-encoded before matching.
Equations
- query.findAll key = query.findAllEncoded (Std.Http.URI.EncodedQueryParam.encode key)
Instances For
Adds a query parameter to the query string.
Equations
- query.insert key value = Array.push query (Std.Http.URI.EncodedQueryParam.encode key, some (Std.Http.URI.EncodedQueryParam.encode value))
Instances For
Adds an already-encoded key-value pair to the query string.
Equations
- query.insertEncoded key value = Array.push query (key, value)
Instances For
Creates an empty query string.
Equations
Instances For
Creates a query string from a list of key-value pairs.
Equations
- Std.Http.URI.Query.ofList pairs = pairs.toArray
Instances For
Checks if a query parameter exists.
Equations
- query.containsEncoded key = Array.any query fun (x : Std.Http.URI.EncodedQueryParam × Option Std.Http.URI.EncodedQueryParam) => decide (x.fst.toByteArray = key.toByteArray)
Instances For
Checks if a query parameter exists by raw key string. The key is percent-encoded before matching.
Equations
- query.contains key = query.containsEncoded (Std.Http.URI.EncodedQueryParam.encode key)
Instances For
Removes all occurrences of a query parameter by key name.
Equations
- query.eraseEncoded key = Array.filter (fun (x : Std.Http.URI.EncodedQueryParam × Option Std.Http.URI.EncodedQueryParam) => decide (x.fst.toByteArray ≠ key.toByteArray)) query
Instances For
Removes all occurrences of a query parameter by raw key string. The key is percent-encoded before matching.
Equations
- query.erase key = query.eraseEncoded (Std.Http.URI.EncodedQueryParam.encode key)
Instances For
Gets the first value of a query parameter by key name, decoded as a string.
Returns none if the key is not found or if the value cannot be decoded as UTF-8.
Equations
Instances For
Gets the first value of a query parameter by key name, decoded as a string. Returns the default value if the key is not found or if the value cannot be decoded.
Instances For
Converts the query to a properly encoded query string format. Example: "key1=value1&key2=value2&flag"
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Std.Http.URI.Query.instEmptyCollection = { emptyCollection := Std.Http.URI.Query.empty }
Equations
- One or more equations did not get rendered due to their size.
Complete URI structure following RFC 3986. All text components use encoded string types to ensure proper percent-encoding.
Reference: https://www.rfc-editor.org/rfc/rfc3986.html
- scheme : Scheme
The URI scheme (e.g., "http", "https", "ftp").
- path : Path
The hierarchical path component.
- query : Query
Optional query string as key-value pairs.
Optional fragment identifier (the part after '#'), percent-encoded.
Instances For
Equations
- Std.Http.instReprURI = { reprPrec := Std.Http.instReprURI.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
- Std.Http.instBEqURI.beq x✝¹ x✝ = false
Instances For
Equations
- One or more equations did not get rendered due to their size.
Fluent builder for constructing URIs. Takes raw (unencoded) strings and handles encoding automatically when building the final URI.
The URI scheme (e.g., "http", "https").
User information (username and optional password).
The host component.
- port : Port
The port number.
Path segments (will be encoded when building).
Query parameters as (key, optional value) pairs (will be encoded when building).
Fragment identifier (will be encoded when building).
Instances For
Equations
Creates an empty URI builder.
Equations
Instances For
Attempts to set the URI scheme (e.g., "http", "https").
Returns none if the scheme is not a valid RFC 3986 scheme.
The stored scheme is normalized to lowercase.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the URI scheme (e.g., "http", "https"). Panics if the scheme is invalid.
Use setScheme? if you need a safe option-returning version.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the user information with username and optional password. The strings will be automatically percent-encoded.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the host as a domain name, returning none if the name contains invalid characters.
The domain name will be automatically lowercased.
Only ASCII alphanumeric characters, hyphens, and dots are allowed.
Each label cannot start or end with - and is limited to 63 characters.
Internationalized domain names must be converted to punycode before use.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the host as a domain name, panicking if the name contains invalid characters.
The domain name will be automatically lowercased.
Only ASCII alphanumeric characters, hyphens, and dots are allowed.
Each label cannot start or end with - and is limited to 63 characters.
Internationalized domain names must be converted to punycode before use.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the host as an IPv4 address.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the host as an IPv6 address.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the port number.
Equations
Instances For
Replaces all path segments. Segments will be automatically percent-encoded when building.
Equations
Instances For
Appends a single segment to the path. The segment will be automatically percent-encoded when building.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Adds a query parameter with a value. Both key and value will be automatically percent-encoded when building.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Adds a query parameter without a value (flag parameter). The key will be automatically percent-encoded when building.
Equations
Instances For
Replaces all query parameters. Keys and values will be automatically percent-encoded when building.
Equations
Instances For
Sets the fragment identifier. The fragment will be automatically percent-encoded when building.
Equations
Instances For
Builds a complete URI from the builder state, encoding all components. Defaults to "https" scheme if none is specified.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Returns a new URI with the scheme replaced.
Equations
- uri.withScheme! scheme = { scheme := Std.Http.URI.Scheme.ofString! scheme, authority := uri.authority, path := uri.path, query := uri.query, fragment := uri.fragment }
Instances For
Partially normalizes a URI by removing dot-segments from the path (. and ..)
according to RFC 3986 Section 5.2.4.
This does not apply the full normalization set from RFC 3986 Section 6 — for example, case normalization, percent-encoding normalization, and default-port normalization are not performed.
Equations
Instances For
HTTP request target forms as defined in RFC 9112 Section 3.3.
Reference: https://www.rfc-editor.org/rfc/rfc9112.html#section-3.3
- originForm
(path : URI.Path)
(query : Option URI.Query)
: RequestTarget
Origin-form request target (most common for HTTP requests). Consists of a path and an optional query string. Example:
/path/to/resource?key=value - absoluteForm
(uri : URI)
: RequestTarget
Absolute-form request target containing a complete URI. Used when making requests through a proxy. Example:
http://example.com:8080/path?key=value - authorityForm
(authority : URI.Authority)
: RequestTarget
Authority-form request target (used for CONNECT requests). Example:
example.com:443 - asteriskForm : RequestTarget
Asterisk-form request target (used with OPTIONS requests). Example:
*
Instances For
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Extracts the path component from a request target, if available. Returns an empty relative path for targets without a path.
Equations
Instances For
Extracts the query component from a request target, if available. Returns an empty array for targets without a query.
Equations
- (Std.Http.RequestTarget.originForm p query).query = query.getD Std.Http.URI.Query.empty
- (Std.Http.RequestTarget.absoluteForm uri).query = uri.query
- x✝.query = Std.Http.URI.Query.empty
Instances For
Extracts the authority component from a request target, if available.
Equations
Equations
- One or more equations did not get rendered due to their size.
Equations
- Std.Http.RequestTarget.instEncodeV11 = { encode := fun (buffer : Std.Http.Internal.ChunkedBuffer) (target : Std.Http.RequestTarget) => buffer.writeString (toString target) }