Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
sendmail_handler.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
module Lwt_scheduler = Colombe.Sigs.Make (Lwt) let ( <.> ) f g x = f (g x) let lwt_bind x f = let open Lwt.Infix in let open Lwt_scheduler in inj (prj x >>= (prj <.> f)) ;; let lwt = { Colombe.Sigs.bind = lwt_bind; return = (fun x -> Lwt_scheduler.inj (Lwt.return x)) } ;; type flow = { ic : Lwt_io.input_channel ; oc : Lwt_io.output_channel } let rdwr = { Colombe.Sigs.rd = (fun { ic; _ } bytes off len -> let open Lwt.Infix in let res = Lwt_io.read_into ic bytes off len >>= function | 0 -> Lwt.return `End | len -> Lwt.return (`Len len) in Lwt_scheduler.inj res) ; wr = (fun { oc; _ } bytes off len -> let res = Lwt_io.write_from_exactly oc (Bytes.unsafe_of_string bytes) off len in Lwt_scheduler.inj res) } ;; let run_with_starttls ~hostname ?port ~domain ?authentication ~tls_authenticator ~from ~recipients ~mail = let port = match port with | Some port -> port | None -> 465 in let tls = Tls.Config.client ~authenticator:tls_authenticator () in let ctx = Sendmail_with_starttls.Context_with_tls.make () in let open Lwt.Infix in Lwt_unix.gethostbyname (Domain_name.to_string hostname) >>= fun res -> if Array.length res.Lwt_unix.h_addr_list = 0 then Lwt.fail_with (Fmt.str "%a can not be resolved" Domain_name.pp hostname) else ( let socket = Lwt_unix.socket Lwt_unix.PF_INET Unix.SOCK_STREAM 0 in Lwt_unix.connect socket (Lwt_unix.ADDR_INET (res.Lwt_unix.h_addr_list.(0), port)) >>= fun () -> let closed = ref false in let close () = if !closed then Lwt.return () else ( closed := true; Lwt_unix.close socket) in let ic = Lwt_io.of_fd ~close ~mode:Lwt_io.Input socket in let oc = Lwt_io.of_fd ~close ~mode:Lwt_io.Output socket in let mail_stream () = match mail () with | Some v -> Lwt_scheduler.inj (Lwt.return (Some v)) | None -> Lwt_scheduler.inj (Lwt.return None) in let fiber = Sendmail_with_starttls.sendmail lwt rdwr { ic; oc } ctx tls ?authentication ~domain from recipients mail_stream in Lwt_scheduler.prj fiber) ;; let run ~hostname ?port ~domain ?authentication ~tls_authenticator ~from ~recipients ~mail = let ( let* ) = Lwt.bind in let port = match port with | Some port -> port | None -> 465 in let ctx = Colombe.State.Context.make () in let* ic, oc = Tls_lwt.connect tls_authenticator (Domain_name.to_string hostname, port) in let mail_stream () = match mail () with | Some v -> Lwt_scheduler.inj (Lwt.return (Some v)) | None -> Lwt_scheduler.inj (Lwt.return None) in let fiber = Sendmail.sendmail lwt rdwr { ic; oc } ctx ?authentication ~domain from recipients mail_stream in Lwt_scheduler.prj fiber ;;