aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClombrong <cromblong@egregore.fun>2025-06-26 22:15:12 +0200
committerClombrong <cromblong@egregore.fun>2025-06-27 08:56:42 +0200
commit41aa93cf6465201447e13e9db0440aaac00cb4e2 (patch)
tree6a5e6e810870b8c180f6cb2015a448de72a30134
parent3f9271f38f49d38a583ec99ec1ddf81a45945e73 (diff)
feat(portal): change type t into a record
-rw-r--r--lib/sasl.ml2
-rw-r--r--lib/stream.ml6
-rw-r--r--portal/portal.mli7
-rw-r--r--portal/tcp/portal.ml13
-rw-r--r--portal/ws/portal.ml13
-rw-r--r--test/hello.ml14
6 files changed, 32 insertions, 23 deletions
diff --git a/lib/sasl.ml b/lib/sasl.ml
index 137d84a..02c9222 100644
--- a/lib/sasl.ml
+++ b/lib/sasl.ml
@@ -29,7 +29,7 @@ let parse_sasl_error = function
type sasl_auth = (string option, sasl_error * (string * string) option) result
-let send_auth_stanza (stream, push) localpart pass mechanism =
+let send_auth_stanza ({stream; push} : Portal.t) localpart pass mechanism =
let gen_auth = function
| PLAIN -> Base64.encode_exn ("\x00" ^ localpart ^ "\x00" ^ pass)
| Unknown s -> failwith "Unsupported authentication mechanism " ^ s
diff --git a/lib/stream.ml b/lib/stream.ml
index ff3b939..a4795ef 100644
--- a/lib/stream.ml
+++ b/lib/stream.ml
@@ -43,7 +43,7 @@ let parse_features (el : Xml.element) : features =
Basically, it conforms to
{{: https://datatracker.ietf.org/doc/html/rfc6120#section-4.3 }}. *)
-let negotiate (domain : string) ((stream, push) : Portal.t) : features Lwt.t =
- let* _id = Portal.header domain (stream, push)
- in let+ features = Xml.get stream >|= parse_features
+let negotiate (domain : string) (portal : Portal.t) : features Lwt.t =
+ let* _id = Portal.header domain portal
+ in let+ features = Xml.get portal.stream >|= parse_features
in features
diff --git a/portal/portal.mli b/portal/portal.mli
index d57a839..1fe90ef 100644
--- a/portal/portal.mli
+++ b/portal/portal.mli
@@ -2,10 +2,13 @@ open Markup
exception MalformedStanza of location * Error.t
-type t = (signal, async) stream * ((signal, sync) stream option -> unit)
-
type socket
+type t = {
+ stream : (signal, async) stream;
+ push : (signal, sync) stream option -> unit;
+ }
+
(** This is the XML namespace of the underlying element stream.
You can rely on it on your code, as an escape hatch, but you should probably not,
diff --git a/portal/tcp/portal.ml b/portal/tcp/portal.ml
index 3477429..931cf93 100644
--- a/portal/tcp/portal.ml
+++ b/portal/tcp/portal.ml
@@ -2,15 +2,18 @@ open Lwt.Syntax
open Lwt_unix
open Markup
-type t = (signal, async) stream * ((signal, sync) stream option -> unit)
-
type socket = file_descr
+type t = {
+ stream : (signal, async) stream;
+ push : (signal, sync) stream option -> unit;
+ }
+
let xmlns = "http://etherx.jabber.org/streams"
exception MalformedStanza of Markup.location * Markup.Error.t
-let header ?from domain ((stream, push) : t) =
+let header ?from domain ({stream; push} : t) =
let stanza =
let attributes =
[(("", "to"), domain); (("", "version"), "1.0");
@@ -48,7 +51,7 @@ let header ?from domain ((stream, push) : t) =
| None -> Lwt.fail_with "Invalid stream opening server-side."
-let close (_, push) = [`End_element] |> Markup.of_list |> Option.some |> push
+let close {push; _} = [`End_element] |> Markup.of_list |> Option.some |> push
(** [xmpp_port domain] is the port where [domain]'s XMPP server is hosted.
@@ -99,4 +102,4 @@ let connect (domain : string) : t Lwt.t =
in Lwt.async (fun () ->
let* _ = lwt_stream xml_stream |> Markup_lwt.write_xml |> iter send
in Lwt_unix.close tcp_socket);
- stream, push
+ {stream; push}
diff --git a/portal/ws/portal.ml b/portal/ws/portal.ml
index b2d21e1..ee4b636 100644
--- a/portal/ws/portal.ml
+++ b/portal/ws/portal.ml
@@ -5,10 +5,13 @@ open Markup
let jss = Js.string
let sjs = Js.to_string
-type t = (signal, async) stream * ((signal, sync) stream option -> unit)
-
type socket = WebSockets.webSocket Js.t
+type t = {
+ stream : (signal, async) stream;
+ push : (signal, sync) stream option -> unit;
+ }
+
let xmlns = "urn:ietf:params:xml:ns:xmpp-framing"
(* sic. XEP-0156: "host-meta files MUST be fetched only over HTTPS". I don't make the
@@ -18,7 +21,7 @@ let well_known_of (domain : string) = "https://" ^ domain ^ "/.well-known/host-m
(** [open_stanza domain] is an <open /> stanza for [domain].
If [from] is specified, the <open /> stanza has the from parameter. *)
-let header ?from domain (stream, push) =
+let header ?from domain {stream; push} =
let stanza =
let attributes =
let open Option in
@@ -46,7 +49,7 @@ let header ?from domain (stream, push) =
| Some id -> Lwt.return id
| None -> Lwt.fail_with "Invalid stream opening server-side."
-let close (_, p) =
+let close {push=p; _} =
{|<close xmlns="|} ^ xmlns ^ {|" />|} |> string |> parse_xml |> signals |> Option.some |> p
exception MalformedStanza of Markup.location * Markup.Error.t
@@ -150,4 +153,4 @@ let connect domain =
|> map (fun x -> write_xml x |> to_string)
|> to_lwt_stream
|> Lwt_stream.iter (fun s -> ws_push (Some s)));
- stream, push
+ {stream; push}
diff --git a/test/hello.ml b/test/hello.ml
index 1659787..9b58de1 100644
--- a/test/hello.ml
+++ b/test/hello.ml
@@ -2,15 +2,15 @@ open! Lwt.Syntax
open! Lwt.Infix
open! Flesh
-let program (stream, push) config (features : Stream.features) =
- let+ _auth = Sasl.authenticate (stream, push) config features.mechanisms
+let program (p : Portal.t) config (features : Stream.features) =
+ let+ _auth = Sasl.authenticate p config features.mechanisms
in begin match _auth with
| Error (NotAuthorized, Some (_, text)) -> print_endline ("Not authorized: " ^ text)
| Error (MalformedRequest, Some (_, text)) -> print_endline ("Malformed request: " ^ text)
| Error _ -> print_endline "Error!"
| Ok _ -> print_endline "Success!"
end;
- Portal.close (stream, push)
+ Portal.close p
let main =
let config : Sasl.auth_config = {
@@ -19,12 +19,12 @@ let main =
preferred_mechanisms = [Sasl.PLAIN]
}
in let domain = (List.nth (String.split_on_char '@' config.jid) 1) in
- let* stream, push = Portal.connect domain in
- let* features = Stream.negotiate domain (stream, push) in
+ let* portal = Portal.connect domain in
+ let* features = Stream.negotiate domain portal in
Lwt.catch
- (fun () -> program (stream, push) config features >|= (fun () -> push None))
+ (fun () -> program portal config features >|= (fun () -> portal.push None))
(fun exn ->
- push None;
+ portal.push None;
(* I suspect JavaScript's [wrap_callback] swallows the Exceptions thrown by
OCaml, so... The next best thing is probably printing something. *)
print_endline