Skip to content

Commit

Permalink
cohttp-eio: client: use permissive argument type for make_generic
Browse files Browse the repository at this point in the history
Currently, Cohttp_eio.Client.make_generic takes a function that returns a value
of type `_ Eio.Net.stream_socket` as an argument. This type is too strict and
can be relaxed to `_ Eio.Flow.two_way`. The difference between these two
types is actually important when we use cohttp-eio with ocaml-tls. Consider the
following code:

```
let authenticator = Ca_certs.authenticator () |> Result.get_ok

let connect_via_tls url socket =
  let tls_config = Tls.Config.client ~authenticator () in
  let host =
    Uri.host url
    |> Option.map (fun x -> Domain_name.(host_exn (of_string_exn x)))
  in
  Tls_eio.client_of_flow ?host tls_config socket

let connect net ~sw url =
  (* NOTE: Do something different than `Cohttp_eio.Client.tcp_address` here and get `addr` *)
  let socket = Eio.Net.connect ~sw net addr in
  connect_via_tls url socket

let () =
  Eio_main.run @@ fun env ->
  Cohttp_eio.Client.make_generic (fun ~sw url ->
      let flow = connect (Eio.Stdenv.net env) ~sw url in
      flow (* <<---- TYPE ERROR HERE!

Error: This expression has type
         Tls_eio.t = [ `Flow | `R | `Shutdown | `Tls | `W ] Eio_unix.source
       but an expression was expected of type
         [> [> `Generic ] Eio.Net.stream_socket_ty ] Eio_unix.source
       Type [ `Flow | `R | `Shutdown | `Tls | `W ] is not compatible with type
         [> ([> `Generic ] as 'a) Eio.Net.stream_socket_ty ] =
           [> `Close
            | `Flow
            | `Platform of 'a
            | `R
            | `Shutdown
            | `Socket
            | `Stream
            | `W ]
       The first variant type does not allow tag(s)
       `Close, `Platform, `Socket, `Stream
*))
```

This code won't compile if `make_generic` expects `_ Eio.Net.stream_socket`,
but it will compile if `_ Eio.Flow.two_way`.

This patch solves the above problem by changing the interface of `make_generic`
to `(sw:Switch.t -> Uri.t -> _ Eio.Flow.two_way) -> t`. The implementation
of `make_generic` is effectively an identity function, so we don't need to
change the implementation.
  • Loading branch information
ushitora-anqou committed Apr 4, 2024
1 parent cf2ae33 commit 539db5c
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased

- cohttp-eio: client: use permissive argument type for make_generic
- cohttp-eio: Improve error handling in example server (talex5 #1023)
- cohttp-eio: Don't blow up `Server.callback` on client disconnections. (mefyl #1015)
- http: Fix assertion in `Source.to_string_trim` when `pos <> 0` (mefyl #1017)
Expand Down
2 changes: 1 addition & 1 deletion cohttp-eio/src/client.mli
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ val make :
- URIs of the form "httpunix://unix-path/http-path" connect to the given
Unix path. *)

val make_generic : (sw:Switch.t -> Uri.t -> _ Eio.Net.stream_socket) -> t
val make_generic : (sw:Switch.t -> Uri.t -> _ Eio.Flow.two_way) -> t
(** [make_generic connect] is an HTTP client that uses [connect] to get the
connection to use for a given URI. *)

0 comments on commit 539db5c

Please sign in to comment.