Skip to content

Commit 01fffd5

Browse files
authored
Merge pull request #5770 from xapi-project/revert-5726-private/asultanov/uri-improvement
Revert "CP-49953: Remove parse_uri, switch to using Uri module instead'"
2 parents ee8e800 + 753a655 commit 01fffd5

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

ocaml/libs/http-lib/http.ml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ let parse_keyvalpairs xs =
208208
)
209209
kvpairs
210210

211+
let parse_uri x =
212+
match Astring.String.cuts ~sep:"?" x with
213+
| [uri] ->
214+
(uri, [])
215+
| [uri; params] ->
216+
(uri, parse_keyvalpairs params)
217+
| _ ->
218+
raise Http_parse_failure
219+
211220
type authorization = Basic of string * string | UnknownAuth of string
212221
[@@deriving rpc]
213222

@@ -620,6 +629,42 @@ module Request = struct
620629

621630
let get_version x = x.version
622631

632+
let of_request_line x =
633+
match Astring.String.fields ~empty:false x with
634+
| [m; uri; version] -> (
635+
(* Request-Line = Method SP Request-URI SP HTTP-Version CRLF *)
636+
let uri, query = parse_uri uri in
637+
(* strip the "HTTP/" prefix from the version string *)
638+
match Astring.String.cut ~sep:"/" version with
639+
| Some (_, version) ->
640+
{
641+
m= method_t_of_string m
642+
; frame= false
643+
; uri
644+
; query
645+
; content_length= None
646+
; transfer_encoding= None
647+
; accept= None
648+
; version
649+
; cookie= []
650+
; auth= None
651+
; task= None
652+
; subtask_of= None
653+
; content_type= None
654+
; host= None
655+
; user_agent= None
656+
; close= false
657+
; additional_headers= []
658+
; body= None
659+
; traceparent= None
660+
}
661+
| None ->
662+
error "Failed to parse: %s" x ;
663+
raise Http_parse_failure
664+
)
665+
| _ ->
666+
raise Http_parse_failure
667+
623668
let to_string x =
624669
let kvpairs x =
625670
String.concat "; " (List.map (fun (k, v) -> k ^ "=" ^ v) x)

ocaml/libs/http-lib/http.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ module Request : sig
119119
val get_version : t -> string
120120
(** [get_version t] returns the HTTP protocol version *)
121121

122+
val of_request_line : string -> t
123+
(** [of_request_line l] parses [l] of the form "METHOD HTTP/VERSION" and
124+
returns the corresponding [t] *)
125+
122126
val to_string : t -> string
123127
(** [to_string t] returns a short string summarising [t] *)
124128

@@ -172,6 +176,8 @@ end
172176

173177
val authorization_of_string : string -> authorization
174178

179+
val parse_uri : string -> string * (string * string) list
180+
175181
val http_403_forbidden : ?version:string -> unit -> string list
176182

177183
val http_200_ok : ?version:string -> ?keep_alive:bool -> unit -> string list

ocaml/libs/http-lib/http_svr.ml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,6 @@ let request_of_bio_exn ~proxy_seen ~read_timeout ~total_timeout ~max_length bio
359359
proxy |> Option.fold ~none:[] ~some:(fun p -> [("STUNNEL_PROXY", p)])
360360
in
361361
let open Http.Request in
362-
(* Below transformation only keeps one value per key, whereas
363-
a fully compliant implementation following Uri's interface
364-
would operate on list of values for each key instead *)
365-
let kvlist_flatten ls =
366-
List.map (function k, v :: _ -> (k, v) | k, [] -> (k, "")) ls
367-
in
368362
let request =
369363
Astring.String.cuts ~sep:"\n" headers
370364
|> List.fold_left
@@ -373,10 +367,7 @@ let request_of_bio_exn ~proxy_seen ~read_timeout ~total_timeout ~max_length bio
373367
match Astring.String.fields ~empty:false header with
374368
| [meth; uri; version] ->
375369
(* Request-Line = Method SP Request-URI SP HTTP-Version CRLF *)
376-
let uri_t = Uri.of_string uri in
377-
if uri_t = Uri.empty then raise Http_parse_failure ;
378-
let uri = Uri.path uri_t in
379-
let query = Uri.query uri_t |> kvlist_flatten in
370+
let uri, query = Http.parse_uri uri in
380371
let m = Http.method_t_of_string meth in
381372
let version =
382373
let x = String.trim version in

0 commit comments

Comments
 (0)