blob: d79c088f510c00cf754611647bf8e13620ccd058 (
plain) (
blame)
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
|
open Lwt.Syntax
open Lwt_unix
exception MalformedStanza of Markup.location * Markup.Error.t
(** [xmpp_port domain] is the port where [domain]'s XMPP server is hosted.
Currently, it falls back to 5222 (always), but should use SRV records in the near
future. *)
let xmpp_port (_domain : string) : int = 5222
(** [tcp_stream domain] is a (stream, socket) tuple communicating with the XMPP server
hosted on [domain] via plaintext TCP. *)
let tcp_stream (domain : string) : (string Lwt_stream.t * file_descr) Lwt.t =
let get_socket {ai_addr; ai_family; _} =
let sock = socket ai_family SOCK_STREAM 0
in let+ () = Lwt_unix.connect sock ai_addr
in sock
and port_number = xmpp_port domain |> string_of_int in
let* addrinfos = getaddrinfo domain port_number [AI_SOCKTYPE SOCK_STREAM]
in let+ sock = List.map get_socket addrinfos |> Lwt.pick
in let stream =
Lwt_stream.from (fun () ->
let bsize = 4096 in
let buffer = Bytes.create bsize in
let* len = read sock buffer 0 bsize
in match len with
| 0 -> Lwt.return_none
| len -> Lwt.return_some (Bytes.sub_string buffer 0 len))
in (stream, sock)
let connect (domain : string) =
let+ tcp_stream, tcp_socket = tcp_stream domain
in let push msg =
let none () = close tcp_socket
and some s () =
write_string tcp_socket s 0 (String.length s) |> Lwt.map ignore
in Option.fold ~none ~some msg |> Lwt.async
in tcp_stream, push
|