(* $Id: https_client.ml 1916 2013-10-01 14:24:54Z gerd $ *) open Uq_engines.Operators type channel_binding_id = int class type transport_channel_type = object method setup_e : Unix.file_descr -> channel_binding_id -> float -> exn -> string -> int -> Unixqueue.event_system -> (Uq_engines.multiplex_controller * exn option) Uq_engines.engine method continue : Unix.file_descr -> channel_binding_id -> float -> exn -> string -> int -> Unixqueue.event_system -> exn option -> Uq_engines.multiplex_controller end exception HTTPS_client_private_data of Ssl.socket let https_transport_channel_type ?(verify = fun _ _ _ -> ()) ctx : transport_channel_type = let ctx_of_fd = Hashtbl.create 12 in let preclose fd () = Hashtbl.remove ctx_of_fd fd in ( object(self) method setup_e fd cb tmo tmo_x host port esys = let mplex = Uq_ssl.create_ssl_multiplex_controller ~close_inactive_descr:true ~preclose:(preclose fd) ~timeout:(tmo, tmo_x) fd ctx esys in Uq_ssl.ssl_connect_engine mplex ++ (fun () -> verify ctx mplex#ssl_socket fd; Hashtbl.replace ctx_of_fd fd mplex; let base_mplex = (mplex :> Uq_engines.multiplex_controller) in let priv_data = Some(HTTPS_client_private_data mplex#ssl_socket) in eps_e (`Done (base_mplex, priv_data)) esys ) (* NB. It is not possible to call here mplex#inactivate in case of an error because this would close fd and violate the interface. Instead, Uq_ssl has been changed so that the state after an erroneous ssl_connect_engine is cleaned up within this class. *) method continue fd cb tmo tmo_x host port esys priv_data = let ssl_socket = match priv_data with | Some(HTTPS_client_private_data s) -> s | _ -> raise Not_found in let mplex = Uq_ssl.create_ssl_multiplex_controller ~close_inactive_descr:true ~preclose:(preclose fd) ~initial_state:`Client ~timeout:(tmo, tmo_x) ~ssl_socket fd ctx esys in (mplex :> Uq_engines.multiplex_controller) end )