aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2022-12-05 17:22:09 +0100
committerLoïc Hoguin <[email protected]>2022-12-05 17:22:09 +0100
commit172800967c2d53251d7cb1015e3c957c5b065bb1 (patch)
tree1ce8a3d138b1ca7894ddd965c186b313aa0aaee4 /doc
parentc98c045affe053ba37e062e2754f32dcd65a0b30 (diff)
downloadgun-172800967c2d53251d7cb1015e3c957c5b065bb1.tar.gz
gun-172800967c2d53251d7cb1015e3c957c5b065bb1.tar.bz2
gun-172800967c2d53251d7cb1015e3c957c5b065bb1.zip
Document Websocket subprotocol negotiation
Diffstat (limited to 'doc')
-rw-r--r--doc/src/manual/gun.asciidoc33
-rw-r--r--doc/src/manual/gun.ws_upgrade.asciidoc21
-rw-r--r--doc/src/manual/gun_app.asciidoc1
-rw-r--r--doc/src/manual/gun_ws_protocol.asciidoc108
4 files changed, 152 insertions, 11 deletions
diff --git a/doc/src/manual/gun.asciidoc b/doc/src/manual/gun.asciidoc
index 9ad3e8e..40559fb 100644
--- a/doc/src/manual/gun.asciidoc
+++ b/doc/src/manual/gun.asciidoc
@@ -525,12 +525,14 @@ detail.
[source,erlang]
----
ws_opts() :: #{
- closing_timeout => timeout(),
- compress => boolean(),
- flow => pos_integer(),
- keepalive => timeout(),
- protocols => [{binary(), module()}],
- silence_pings => boolean()
+ closing_timeout => timeout(),
+ compress => boolean(),
+ default_protocol => module(),
+ flow => pos_integer(),
+ keepalive => timeout(),
+ protocols => [{binary(), module()}],
+ silence_pings => boolean(),
+ user_opts => any()
}
----
@@ -550,6 +552,11 @@ Whether to enable permessage-deflate compression. This does
not guarantee that compression will be used as it is the
server that ultimately decides. Defaults to false.
+default_protocol (gun_ws_h)::
+
+Default protocol module when no Websocket subprotocol is
+negotiated.
+
flow - see below::
The initial flow control value for the Websocket connection.
@@ -563,8 +570,10 @@ protocols ([])::
A non-empty list enables Websocket protocol negotiation. The
list of protocols will be sent in the sec-websocket-protocol
-request header. The handler module interface is currently
-undocumented and must be set to `gun_ws_h`.
+request header. The given module must follow the
+link:man:gun_ws_protocol(3)[gun_ws_protocol(3)] interface.
+Gun comes with a default interface in `gun_ws_h` that may
+be reused for negotiated protocols.
silence_pings (true)::
@@ -572,10 +581,16 @@ Whether the ping and pong frames should be sent to the user.
In all cases Gun will automatically send a pong frame back
when receiving a ping.
-// @todo Document default_protocol and user_opts.
+user_opts - see below::
+
+Additional options that are not in use by Gun unless a custom
+Websocket subprotocol is configured and negotiated.
+By default no user option is defined.
== Changelog
+* *2.0*: The `default_protocol` and `user_opts` Websocket
+ options were added.
* *2.0*: The `stream_ref()` type was added.
* *2.0*: The option `cookie_store` was added. It can be used
to configure a cookie store that Gun will use
diff --git a/doc/src/manual/gun.ws_upgrade.asciidoc b/doc/src/manual/gun.ws_upgrade.asciidoc
index b553f3b..c6e3850 100644
--- a/doc/src/manual/gun.ws_upgrade.asciidoc
+++ b/doc/src/manual/gun.ws_upgrade.asciidoc
@@ -20,7 +20,7 @@ ws_upgrade(ConnPid, Path, Headers, WsOpts)
ConnPid :: pid()
Path :: iodata()
Headers :: gun:req_headers()
-WsOpts :: gun:ws_opts
+WsOpts :: gun:ws_opts()
StreamRef :: gun:stream_ref()
----
@@ -39,6 +39,11 @@ Gun does not currently support Websocket over HTTP/2.
By default Gun will take the Websocket options from
the connection's `ws_opts`.
+Websocket subprotocol negotiation is enabled when
+the `protocols` option is given. It takes a subprotocol
+name and a module implementing the
+link:man:gun_ws_protocol(3)[gun_ws_protocol(3)] behavior.
+
== Arguments
ConnPid::
@@ -92,9 +97,21 @@ StreamRef = gun:ws_upgrade(ConnPid, "/ws", [], #{
}).
----
+.Upgrade to Websocket with protocol negotiation
+[source,erlang]
+----
+StreamRef = gun:ws_upgrade(ConnPid, "/ws", [], #{
+ protocols => [
+ {<<"mqtt">>, gun_ws_mqtt_h},
+ {<<"v12.stomp">>, gun_ws_stomp_h}
+ ]
+}).
+----
+
== See also
link:man:gun(3)[gun(3)],
link:man:gun:ws_send(3)[gun:ws_send(3)],
link:man:gun_upgrade(3)[gun_upgrade(3)],
-link:man:gun_ws(3)[gun_ws(3)]
+link:man:gun_ws(3)[gun_ws(3)],
+link:man:gun_ws_protocol(3)[gun_ws_protocol(3)]
diff --git a/doc/src/manual/gun_app.asciidoc b/doc/src/manual/gun_app.asciidoc
index 168d0e9..ca05594 100644
--- a/doc/src/manual/gun_app.asciidoc
+++ b/doc/src/manual/gun_app.asciidoc
@@ -19,6 +19,7 @@ to the server and reconnects automatically when necessary.
* link:man:gun_cookies(3)[gun_cookies(3)] - Cookie store engine
* link:man:gun_cookies_list(3)[gun_cookies_list(3)] - Cookie store backend: in-memory, per connection
* link:man:gun_event(3)[gun_event(3)] - Events
+* link:man:gun_ws_protocol(3)[gun_ws_protocol(3)] - Websocket subprotocols
== Dependencies
diff --git a/doc/src/manual/gun_ws_protocol.asciidoc b/doc/src/manual/gun_ws_protocol.asciidoc
new file mode 100644
index 0000000..417ba94
--- /dev/null
+++ b/doc/src/manual/gun_ws_protocol.asciidoc
@@ -0,0 +1,108 @@
+= gun_ws_protocol(3)
+
+== Name
+
+gun_ws_protocol - Websocket subprotocols
+
+== Description
+
+The `gun_ws_protocol` module provides the callback interface
+and types for implementing Websocket subprotocols.
+
+== Callbacks
+
+Websocket subprotocols implement the following interface.
+
+=== init
+
+[source,erlang]
+----
+init(ReplyTo, StreamRef, Headers, Opts) -> {ok, State}
+
+ReplyTo :: pid()
+StreamRef :: reference()
+Headers :: cow_http:headers()
+Opts :: gun:ws_opts()
+State :: protocol_state()
+----
+
+Initialize the Websocket protocol.
+
+ReplyTo::
+
+The pid of the process that owns the stream and to
+which messages will be sent to.
+
+StreamRef::
+
+The reference for the stream. Must be sent in messages
+to distinguish between different streams.
+
+Headers::
+
+Headers that were sent in the response establishing
+the Websocket connection.
+
+Opts::
+
+Websocket options. Custom options can be provided in
+the `user_opts` key.
+
+State::
+
+State for the protocol.
+
+=== handle
+
+[source,erlang]
+----
+handle(Frame, State) -> {ok, FlowDec, State}
+
+Frame :: cow_ws:frame()
+State :: protocol_state()
+FlowDec :: non_neg_integer()
+----
+
+Handle a Websocket frame.
+
+This callback may receive fragmented frames depending
+on the protocol and may need to rebuild the full
+frame to process it.
+
+Frame::
+
+Websocket frame.
+
+State::
+
+State for the protocol.
+
+FlowDec::
+
+How many messages were sent. Used to update the flow
+control state when the feature is enabled.
+
+== Types
+
+=== protocol_state()
+
+[source,erlang]
+----
+protocol_state() :: any()
+----
+
+State for the protocol.
+
+As this part of the implementation of the protocol
+the type may differ between different Websocket
+protocol modules.
+
+== Changelog
+
+* *2.0*: Module introduced.
+
+== See also
+
+link:man:gun(7)[gun(7)],
+link:man:gun(3)[gun(3)],
+link:man:gun:ws_upgrade(3)[gun:ws_upgrade(3)]