@@ -74,7 +74,7 @@ module type Scheme = sig
7474 val canonicalize_path : string list -> string list
7575end
7676
77- module Generic : Scheme = struct
77+ module Generic = struct
7878 let sub_delims a =
7979 let subd = " !$&'()*+,;=" in
8080 for i = 0 to String. length subd - 1 do
@@ -201,12 +201,32 @@ module Urn : Scheme = struct
201201
202202end
203203
204+ module Aws : Scheme = struct
205+ include Http
206+
207+ let safe_chars_query_key =
208+ let a = Array. copy Generic. safe_chars in
209+ a.(Char. code '/' ) < - true ;
210+ a
211+
212+ let safe_chars_for_component = function
213+ | `Query_key -> safe_chars_query_key
214+ | `Query_value -> Generic. safe_chars
215+ | `Query -> Http. safe_chars_for_component `Query
216+ | `Path
217+ | `Userinfo
218+ | `Fragment
219+ | `Scheme -> failwith " Aws scheme is only for query encoding"
220+ | x -> Http. safe_chars_for_component x
221+ end
222+
204223let module_of_scheme = function
205224 | Some s -> begin match String. lowercase s with
206225 | "http" -> (module Http : Scheme )
207226 | "https" -> (module Https : Scheme )
208227 | "file" -> (module File : Scheme )
209228 | "urn" -> (module Urn : Scheme )
229+ | "aws" -> (module Aws : Scheme )
210230 | _ -> (module Generic : Scheme )
211231 end
212232 | None -> (module Generic : Scheme )
@@ -509,6 +529,7 @@ let encoded_of_query ?scheme = Query.encoded_of_query ?scheme
509529
510530(* Type of the URI, with most bits being optional *)
511531type t = {
532+ query_scheme : Pct .decoded sexp_option ;
512533 scheme : Pct .decoded sexp_option ;
513534 userinfo : Userinfo .t sexp_option ;
514535 host : Pct .decoded sexp_option ;
@@ -519,6 +540,7 @@ type t = {
519540} with sexp
520541
521542let empty = {
543+ query_scheme = None ;
522544 scheme = None ;
523545 userinfo = None ;
524546 host = None ;
@@ -572,7 +594,7 @@ let normalize schem uri =
572594 * casting/uncasting (which isn't fully identity due to the option box), but it is
573595 * no big deal for now.
574596*)
575- let make ?scheme ?userinfo ?host ?port ?path ?query ?fragment () =
597+ let make ?query_scheme ? scheme ?userinfo ?host ?port ?path ?query ?fragment () =
576598 let decode = function
577599 | Some x -> Some (Pct. cast_decoded x) | None -> None in
578600 let host = match userinfo, host, port with
@@ -593,9 +615,10 @@ let make ?scheme ?userinfo ?host ?port ?path ?query ?fragment () =
593615 | Some p -> Query. KV p
594616 in
595617 let scheme = decode scheme in
618+ let query_scheme = decode query_scheme in
596619 normalize scheme
597- { scheme; userinfo;
598- host = decode host; port; path; query; fragment= decode fragment }
620+ { scheme ; query_scheme ; userinfo ; host = decode host ; port ; path
621+ ; query ; fragment= decode fragment }
599622
600623(* * Parse a URI string into a structure *)
601624let of_string s =
@@ -645,7 +668,8 @@ let of_string s =
645668 | None -> Query. Raw (None , Lazy. from_val [] )
646669 in
647670 let fragment = get_opt subs 9 in
648- normalize scheme { scheme; userinfo; host; port; path; query; fragment }
671+ normalize scheme { query_scheme= None ; scheme ; userinfo ; host ; port
672+ ; path ; query ; fragment }
649673
650674(* * Convert a URI structure into a percent-encoded string
651675 <http://tools.ietf.org/html/rfc3986#section-5.3>
@@ -687,6 +711,14 @@ let to_string uri =
687711 Buffer. add_char buf ':' ;
688712 Buffer. add_string buf (string_of_int port)
689713 );
714+ let scheme =
715+ match uri.query_scheme with
716+ | None -> scheme
717+ | Some s ->
718+ let s' = Pct. uncast_decoded s in
719+ (if s' = " aws" then
720+ failwith @@ Printf. sprintf " using scheme %s\n " s');
721+ Some (Pct. uncast_decoded s) in
690722 (match uri.path with (* Handle relative paths correctly *)
691723 | [] -> ()
692724 | "/" ::_ ->
@@ -725,6 +757,11 @@ let with_scheme uri =
725757 | Some scheme -> { uri with scheme= Some (Pct. cast_decoded scheme) }
726758 | None -> { uri with scheme= None }
727759
760+ let with_query_scheme uri =
761+ function
762+ | Some scheme -> { uri with query_scheme= Some (Pct. cast_decoded scheme) }
763+ | None -> { uri with query_scheme= None }
764+
728765let host uri = get_decoded_opt uri.host
729766let with_host uri =
730767 function
@@ -818,16 +855,21 @@ let remove_query_param uri k = Query.(
818855 { uri with query= KV (List. filter (fun (k' ,_ ) -> k<> k') (kv uri.query)) }
819856)
820857
858+ let q_scheme uri =
859+ match uri.query_scheme with
860+ | None -> uri.scheme
861+ | t -> t
862+
821863(* Construct encoded path and query components *)
822864let path_and_query uri =
823865 match (path uri), (query uri) with
824866 | " " , [] -> " /" (* TODO: What about same document? (/) *)
825867 | " " , q -> (* TODO: What about same document? (/) *)
826- let scheme = uncast_opt uri.scheme in
868+ let scheme = uncast_opt (q_scheme uri) in
827869 Printf. sprintf " /?%s" (encoded_of_query ?scheme q)
828870 | p , [] -> p
829871 | p , q ->
830- let scheme = uncast_opt uri.scheme in
872+ let scheme = uncast_opt (q_scheme uri) in
831873 Printf. sprintf " %s?%s" p (encoded_of_query ?scheme q)
832874
833875(* TODO: functions to add and remove from a URI *)
0 commit comments