Skip to content

Commit 1568940

Browse files
authored
feature: remove [scheme] from requests (#1086)
This makes it so that [Request.make ~uri |> Request.uri] will no longer return the same URI as [uri]. Also, this property was never preserved with respect to other URI fields. Signed-off-by: Rudi Grinberg <[email protected]>
1 parent 05cf245 commit 1568940

File tree

7 files changed

+62
-79
lines changed

7 files changed

+62
-79
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## Unreleased
22

3+
- http, cohttp: remove the scheme field from requests. This means that
4+
[Request.uri] no longer returns the same URI as was to create the request
5+
with [Request.make] (@rgrinberg 1086)
36
- cohttp-eio: Remove unused `Client_intf` module (talex5 #1081)
47
- cohttp-eio: Make server response type abstract and allow streaming in cohttp-eio (talex5 #1024)
58
- cohttp-{lwt,eio}: server: add connection header to response if not present (ushitora-anqou #1025)

cohttp/src/request.ml

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,24 @@ open Sexplib0.Sexp_conv
1919
type t = Http.Request.t = {
2020
headers : Header.t;
2121
meth : Code.meth;
22-
scheme : string option;
2322
resource : string;
2423
version : Code.version;
2524
}
2625
[@@deriving sexp]
2726

28-
let compare { headers; meth; scheme; resource; version } y =
27+
let compare { headers; meth; resource; version } y =
2928
match Header.compare headers y.headers with
3029
| 0 -> (
3130
match Code.compare_method meth y.meth with
3231
| 0 -> (
33-
match Option.compare String.compare scheme y.scheme with
34-
| 0 -> (
35-
match String.compare resource y.resource with
36-
| 0 -> Code.compare_version version y.version
37-
| i -> i)
32+
match String.compare resource y.resource with
33+
| 0 -> Code.compare_version version y.version
3834
| i -> i)
3935
| i -> i)
4036
| i -> i
4137

4238
let headers t = t.headers
4339
let meth t = t.meth
44-
let scheme t = t.scheme
4540
let resource t = t.resource
4641
let version t = t.version
4742
let encoding t = Header.get_transfer_encoding t.headers
@@ -71,14 +66,13 @@ let make ?(meth = `GET) ?(version = `HTTP_1_1) ?encoding
7166
Header.add_authorization headers auth
7267
| _, _, _ -> headers
7368
in
74-
let scheme = Uri.scheme uri in
7569
let resource = Uri.path_and_query uri in
7670
let headers =
7771
match encoding with
7872
| None -> headers
7973
| Some encoding -> Header.add_transfer_encoding headers encoding
8074
in
81-
{ headers; meth; scheme; resource; version }
75+
{ headers; meth; resource; version }
8276

8377
let is_keep_alive t = Http.Request.is_keep_alive t
8478

@@ -110,49 +104,42 @@ let is_valid_uri path meth =
110104
| Some _ -> true
111105
| None -> not (String.length path > 0 && path.[0] <> '/')
112106

113-
let uri { scheme; resource; headers; meth; _ } =
114-
let uri =
115-
match resource with
116-
| "*" -> (
117-
match Header.get headers "host" with
118-
| None -> Uri.of_string ""
119-
| Some host ->
120-
let host_uri = Uri.of_string ("//" ^ host) in
121-
Uri.(make ?host:(host host_uri) ?port:(port host_uri) ()))
122-
| authority when meth = `CONNECT -> Uri.of_string ("//" ^ authority)
123-
| path -> (
124-
let uri = Uri.of_string path in
125-
match Uri.scheme uri with
126-
| Some _ -> (
127-
Uri.(
128-
(* we have an absoluteURI *)
129-
match path uri with "" -> with_path uri "/" | _ -> uri))
130-
| None ->
131-
let empty = Uri.of_string "" in
132-
let empty_base = Uri.of_string "///" in
133-
let pqs =
134-
match Stringext.split ~max:2 path ~on:'?' with
135-
| [] -> empty_base
136-
| [ path ] ->
107+
let uri { resource; headers; meth; _ } =
108+
match resource with
109+
| "*" -> (
110+
match Header.get headers "host" with
111+
| None -> Uri.of_string ""
112+
| Some host ->
113+
let host_uri = Uri.of_string ("//" ^ host) in
114+
Uri.(make ?host:(host host_uri) ?port:(port host_uri) ()))
115+
| authority when meth = `CONNECT -> Uri.of_string ("//" ^ authority)
116+
| path -> (
117+
let uri = Uri.of_string path in
118+
match Uri.scheme uri with
119+
| Some _ -> (
120+
Uri.(
121+
(* we have an absoluteURI *)
122+
match path uri with "" -> with_path uri "/" | _ -> uri))
123+
| None -> (
124+
let empty = Uri.of_string "" in
125+
let empty_base = Uri.of_string "///" in
126+
let pqs =
127+
match Stringext.split ~max:2 path ~on:'?' with
128+
| [] -> empty_base
129+
| [ path ] ->
130+
Uri.resolve "http" empty_base (Uri.with_path empty path)
131+
| path :: qs :: _ ->
132+
let path_base =
137133
Uri.resolve "http" empty_base (Uri.with_path empty path)
138-
| path :: qs :: _ ->
139-
let path_base =
140-
Uri.resolve "http" empty_base (Uri.with_path empty path)
141-
in
142-
Uri.with_query path_base (Uri.query_of_encoded qs)
143-
in
144-
let uri =
145-
match Header.get headers "host" with
146-
| None -> Uri.(with_scheme (with_host pqs None) None)
147-
| Some host ->
148-
let host_uri = Uri.of_string ("//" ^ host) in
149-
let uri = Uri.with_host pqs (Uri.host host_uri) in
150-
Uri.with_port uri (Uri.port host_uri)
151-
in
152-
uri)
153-
in
154-
(* Only set the scheme if it's not already part of the URI *)
155-
match Uri.scheme uri with Some _ -> uri | None -> Uri.with_scheme uri scheme
134+
in
135+
Uri.with_query path_base (Uri.query_of_encoded qs)
136+
in
137+
match Header.get headers "host" with
138+
| None -> Uri.(with_scheme (with_host pqs None) None)
139+
| Some host ->
140+
let host_uri = Uri.of_string ("//" ^ host) in
141+
let uri = Uri.with_host pqs (Uri.host host_uri) in
142+
Uri.with_port uri (Uri.port host_uri)))
156143

157144
type tt = t
158145

cohttp/src/s.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,13 @@ module type Request = sig
8585
type t = {
8686
headers : Header.t; (** HTTP request headers *)
8787
meth : Code.meth; (** HTTP request method *)
88-
scheme : string option; (** URI scheme (http or https) *)
8988
resource : string; (** Request path and query *)
9089
version : Code.version; (** HTTP version, usually 1.1 *)
9190
}
9291
[@@deriving sexp]
9392

9493
val headers : t -> Header.t
9594
val meth : t -> Code.meth
96-
val scheme : t -> string option
9795
val resource : t -> string
9896
val version : t -> Code.version
9997
val encoding : t -> Transfer.encoding

cohttp/test/test_request.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,16 @@ let parse_request_uri_host_traversal _ =
249249
parse_request_uri_ r uri "parse_request_uri_host_traversal"
250250

251251
let uri_round_trip _ =
252-
let expected_uri = Uri.of_string "https://www.example.com/test" in
253-
let actual_uri = Request.make expected_uri |> Request.uri in
252+
let expected_uri =
253+
let uri = Uri.of_string "https://www.example.com/test" in
254+
Uri.with_userinfo uri (Some "foo")
255+
in
256+
let actual_uri =
257+
let uri = Request.make expected_uri |> Request.uri in
258+
(* These are the fields that aren't preserved: *)
259+
let uri = Uri.with_scheme uri (Uri.scheme expected_uri) in
260+
Uri.with_userinfo uri (Uri.userinfo expected_uri)
261+
in
254262
Alcotest.check uri_testable "Request.make uri round-trip" actual_uri
255263
expected_uri
256264

http/src/http.ml

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -739,27 +739,22 @@ module Request = struct
739739
type t = {
740740
headers : Header.t; (** HTTP request headers *)
741741
meth : Method.t; (** HTTP request method *)
742-
scheme : string option; (** URI scheme (http or https) *)
743742
resource : string; (** Request path and query *)
744743
version : Version.t; (** HTTP version, usually 1.1 *)
745744
}
746745

747746
let headers t = t.headers
748747
let meth t = t.meth
749-
let scheme t = t.scheme
750748
let resource t = t.resource
751749
let version t = t.version
752750

753-
let compare { headers; meth; scheme; resource; version } y =
751+
let compare { headers; meth; resource; version } y =
754752
match Header.compare headers y.headers with
755753
| 0 -> (
756754
match Method.compare meth y.meth with
757755
| 0 -> (
758-
match Option.compare String.compare scheme y.scheme with
759-
| 0 -> (
760-
match String.compare resource y.resource with
761-
| 0 -> Version.compare version y.version
762-
| i -> i)
756+
match String.compare resource y.resource with
757+
| 0 -> Version.compare version y.version
763758
| i -> i)
764759
| i -> i)
765760
| i -> i
@@ -786,8 +781,8 @@ module Request = struct
786781
else `No
787782

788783
let make ?(meth = `GET) ?(version = `HTTP_1_1) ?(headers = Header.empty)
789-
?scheme resource =
790-
{ headers; meth; scheme; resource; version }
784+
resource =
785+
{ headers; meth; resource; version }
791786

792787
let pp fmt t =
793788
let open Format in
@@ -1133,7 +1128,7 @@ module Parser = struct
11331128
let path = token source in
11341129
let version = version source in
11351130
let headers = headers source in
1136-
{ Request.headers; meth; scheme = None; resource = path; version }
1131+
{ Request.headers; meth; resource = path; version }
11371132

11381133
type error = Partial | Msg of string
11391134

http/src/http.mli

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,15 +385,13 @@ module Request : sig
385385
type t = {
386386
headers : Header.t; (** HTTP request headers *)
387387
meth : Method.t; (** HTTP request method *)
388-
scheme : string option; (** URI scheme (http or https) *)
389388
resource : string; (** Request path and query *)
390389
version : Version.t; (** HTTP version, usually 1.1 *)
391390
}
392391

393392
val has_body : t -> [ `No | `Unknown | `Yes ]
394393
val headers : t -> Header.t
395394
val meth : t -> Method.t
396-
val scheme : t -> string option
397395
val resource : t -> string
398396
val version : t -> Version.t
399397
val compare : t -> t -> int
@@ -428,17 +426,11 @@ module Request : sig
428426
that a user-agent can handle HTTP chunked trailers headers. *)
429427

430428
val make :
431-
?meth:Method.t ->
432-
?version:Version.t ->
433-
?headers:Header.t ->
434-
?scheme:string ->
435-
string ->
436-
t
429+
?meth:Method.t -> ?version:Version.t -> ?headers:Header.t -> string -> t
437430
(** [make resource] is a value of {!type:t}. The default values for the
438431
response, if not specified, are as follows: [meth] is [`GET], [version] is
439-
[`HTTP_1_1], [headers] is [Header.empty] and [scheme] is [None]. The
440-
request encoding value is determined via the
441-
[Header.get_transfer_encoding] function.*)
432+
[`HTTP_1_1], [headers] is [Header.empty]. The request encoding value is
433+
determined via the [Header.get_transfer_encoding] function.*)
442434

443435
val pp : Format.formatter -> t -> unit
444436
end

http/test/test_parser.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let assert_req_success ~here ~expected_req ~expected_consumed ?pos ?len buf =
3838
[%test_result: int] ~here ~expect:expected_consumed consumed
3939

4040
let[@warning "-3"] make_req ~headers meth resource =
41-
{ Http.Request.headers; meth; resource; scheme = None; version = `HTTP_1_1 }
41+
{ Http.Request.headers; meth; resource; version = `HTTP_1_1 }
4242

4343
let req_expected =
4444
make_req

0 commit comments

Comments
 (0)