Http.Path
Absolute paths.
The type for absolute URI paths represented as non-empty lists of percent-decoded path segments:
""
./
is represented by [""]
./a
is represented by ["a"]
, see more examples here.Warning. You should never concatenate these segments with a separator to get a file path: they may contain stray percent-decoded directory separators. Use the function Path.to_absolute_filepath
to interpret paths as file paths.
val none : t
none
is the path []
for when there is none.
val root : t
root
is the root path [""]
.
undot_and_compress p
removes "."
and ".."
according to the RFC 3986 algorithm and suppresses non-final empty ""
segments.
strip_prefix ~prefix p
removes the prefix path prefix
from p
.
If prefix
ends with an empty segment, it matches any corresponding segment at that point so that stripping /a/
from /a/b
results in /b
. However stripping /a/
from /a
yields []
(none
).
If p
is not prefixed by prefix
, or if any of prefix
or p
is []
(none
), []
is returned.
Given a path p
and the same path p'
with a trailing slash, the set of paths prefixed by p
is the the set of path prefixed by p'
plus p
itelf. Stripping p
to itself yields root
(see here for why we think that's desirable).
A few examples basic edge cases root
and none
:
strip_prefix [""] (_ :: _ as p) = p
strip_prefix (_ :: _ as p) p = [""]
strip_prefix _ [] -> []
strip_prefix [] _ = []
Stripping a prefix /a
:
strip_prefix ["a"] [""] = []
strip_prefix ["a"] ["a"] = [""]
strip_prefix ["a"] ["a"; ""] = [""]
strip_prefix ["a"] ["b"] = []
strip_prefix ["a"] ["a"; "b"] = ["b"]
strip_prefix ["a"] ["a"; "b"; ""] = ["b"; ""]
strip_prefix ["a"] ["a"; ""; "b"] = [""; "b"]
Stripping a prefix /a/
:
strip_prefix ["a"; ""] [""] = []
strip_prefix ["a"; ""] ["a"] = []
strip_prefix ["a"; ""] ["b"] = []
strip_prefix ["a"; ""] ["a"; ""] = [""]
strip_prefix ["a"; ""] ["a"; "b"] = ["b"]
strip_prefix ["a"; ""] ["a"; "b"; ""] = ["b"; ""]
strip_prefix ["a"; ""] ["a"; ""; "b"] = [""; "b"]
concat p0 p1
concatenates p0
and p1
. If p0
ends with an empty segment and p1
is not none
that empty segment is dropped. A few examples:
concat p [] = p
concat [] p = p
concat [""] [""] = [""]
concat [""] ["a"; "b"] = ["a"; "b"]
concat ["a"] [""] = ["a"; ""]
concat ["a"; ""] [""] = ["a"; ""]
concat ["a"; "b"] ["c"; "d"] = ["a"; "b"; "c"; "d"]
concat ["a"; "b"; ""] ["c"; "d"] = ["a"; "b"; "c"; "d"]
concat ["a"; "b"; ""] [""] = ["a"; "b"; ""]
concat ["a"; "b"; ""] [""; "c"] = ["a"; "b"; ""; "c"]
relative ~src ~dst
is the relative path rel
that goes from absolute src
to absolute dst
. This means that undot_and_compress (concat src rel)
should yield dst
.
Warning. This function assumes both src
and dst
have no relative or empty path components. If needed use undot_and_compress
to ensure that.
to_absolute_filepath p
is an absolute file path for undot_and_compress
p
. Errors if any of the path segments contains a stray slash or backslash or if p
is the empty list. The result always uses /
as a directory separator regardless of the platform and is guaranteed to be free of any .
or ..
segments.
prefix_filepath ~prefix p
prefixes p
by prefix
avoiding introducing empty segments. This function assumes /
is the directory separator regardless of the platform.
val filepath_ext : fpath -> string
filepath_ext p
is the file extension of file path p
. This function assumes /
is the directory separator regardless of the platform.
val encode : t -> string
encode p
encodes an absolute-path
for p
as follows:
unreserved
, sub-delims
, ':'
or '@'
to produce a valid URI segment
.'/'
.The empty list is special cased and yields ""
. This is for encoding HTTP paths, use to_absolute_filepath
to convert paths to file paths.
Here are a few examples:
encode [] = ""
encode [""] = "/"
encode [""; ""] = "//"
encode [""; "a"] = "//a"
encode ["a";"b";"c"] = "/a/b/c"
encode ["a";"b";"";"c";] = "/a/b//c"
encode ["a";"b";"c";""] = "/a/b/c/"
encode ["a";"b";"c";" "] = "/a/b/c/%20"
encode ["a";"b";"c";"";""] = "/a/b/c//"
encode ["a"; "b/"; "c"] = "/a/b%2F/c"
encode ["r\xC3\xC9volte"] = "/r%C3%C9volte"
encode ["a"; "not%20"; "b"] = "/a/not%2520/b"
val decode : string -> (t, string) Stdlib.result
decode s
decodes an absolute-path
to its percent-decoded list of segments. By definition of absolute-path
the list of segments is never empty.
Here are a few examples:
decode "/" = Ok [""]
decode "//" = Ok ["";""]
decode "//a" = Ok ["";"a"]
decode "/a/b/c" = Ok ["a";"b";"c"]
decode "/a/b//c" = Ok ["a";"b";"";"c"]
decode "/a/b/c/" = Ok ["a";"b";"c";""]
decode "/a/b/c/%20" = Ok ["a";"b";"c";" "]
decode "/a/b//c//" = Ok ["a";"b";"";"c";"";""]
decode "/a/b%2F/c" = Ok ["a"; "b/"; "c"]
decode "/r%C3%C9volte" = Ok ["r\xC3\xC9volte"]
decode "/a/not%2520/b" = Ok ["a"; "not%20"; "b"]
decode "" = Error _
decode "a/b/c" = Error _
val and_query_string_of_request_target :
string ->
(t * string option, string) Stdlib.result
and_query_string_of_request_target s
parses a path and a query string (without the '?') form the request target s
(which can be an URL).
val pp : Stdlib.Format.formatter -> t -> unit
pp
formats paths for inspection.
val pp_dump : Stdlib.Format.formatter -> t -> unit
pp_dump
formats paths for deeper inspection..