Plasma GitLab Archive
Projects Blog Knowledge

(* $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
  )

This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml