225 lines
8.7 KiB
Text
225 lines
8.7 KiB
Text
|
= nng_ws(7)
|
||
|
//
|
||
|
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||
|
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||
|
//
|
||
|
// This document is supplied under the terms of the MIT License, a
|
||
|
// copy of which should be located in the distribution where this
|
||
|
// file was obtained (LICENSE.txt). A copy of the license may also be
|
||
|
// found online at https://opensource.org/licenses/MIT.
|
||
|
//
|
||
|
|
||
|
== NAME
|
||
|
|
||
|
nng_ws - WebSocket transport
|
||
|
|
||
|
== SYNOPSIS
|
||
|
|
||
|
[source,c]
|
||
|
----
|
||
|
#include <nng/transport/websocket/ws.h>
|
||
|
|
||
|
int nng_ws_register(void);
|
||
|
int nng_wss_register(void);
|
||
|
----
|
||
|
|
||
|
== DESCRIPTION
|
||
|
|
||
|
(((WebSocket)))(((transport, _ws_ and _wss_)))
|
||
|
The ((_ws_ transport)) provides communication support between
|
||
|
peers across a TCP/IP network using
|
||
|
https://tools.ietf.org/html/rfc6455[WebSockets].
|
||
|
Both IPv4 and IPv6 are supported when the underlying platform also supports it.
|
||
|
|
||
|
The protocol details are documented in
|
||
|
http://nanomsg.org/rfcs/sp-websocket-v1.html[WebSocket Mapping for Scalability Protocols].
|
||
|
|
||
|
=== Registration
|
||
|
|
||
|
Depending upon how the library was built, it may be necessary to
|
||
|
register the transport by calling xref:nng_ws_register.3.adoc[`nng_ws_register()`].
|
||
|
|
||
|
If ((TLS)) support is enabled in the library, secure WebSockets (over TLS v1.2)
|
||
|
can be used as well, but the secure transport may have to be registered using
|
||
|
the xref:nng_wss_register.3.adoc[`nng_wss_register()`] function.
|
||
|
|
||
|
=== URI Format
|
||
|
|
||
|
(((URI, `ws://`)))
|
||
|
This transport uses URIs using the scheme `ws://`, followed by
|
||
|
an IP address or hostname, optionally followed by a colon and an
|
||
|
TCP port number, optionally followed by a path.
|
||
|
(If no port number is specified then port 80 is assumed.
|
||
|
If no path is specified then a path of `/` is assumed.)
|
||
|
For example, the URI `ws://localhost/app/pubsub` would use
|
||
|
port 80 on localhost, with the path `/app/pubsub`.
|
||
|
|
||
|
Secure WebSockets (((WebSockets, Secure)))(((URI, `wss://`)))
|
||
|
(if enabled) use the scheme `wss://`, and the default TCP port number of 443.
|
||
|
Otherwise the format is the same as for regular WebSockets.
|
||
|
|
||
|
A URI may be restricted to IPv6 using the scheme `ws6://` or `wss6://`, and may
|
||
|
be restricted to IPv4 using the scheme `ws4://` or `wss4://`.
|
||
|
|
||
|
NOTE: Specifying `ws6://` or `wss6://` may not prevent IPv4 hosts from being used with
|
||
|
IPv4-in-IPv6 addresses, particularly when using a wildcard hostname with
|
||
|
listeners.
|
||
|
The details of this varies across operating systems.
|
||
|
|
||
|
NOTE: The `ws4://` , `ws6://`, `wss4://` and `wss6://` schemes are specific to _NNG_,
|
||
|
and might not be understood by other implementations.
|
||
|
|
||
|
TIP: We recommend using either numeric IP addresses, or names that are
|
||
|
specific to either IPv4 or IPv6 to prevent confusion and surprises.
|
||
|
|
||
|
When specifying IPv6 addresses, the address must be enclosed in
|
||
|
square brackets (`[]`) to avoid confusion with the final colon
|
||
|
separating the port.
|
||
|
|
||
|
For example, the same path and port on the IPv6 loopback address (`::1`)
|
||
|
would be specified as `ws://[::1]/app/pubsub`.
|
||
|
|
||
|
NOTE: The value specified as the host, if any, will also be used
|
||
|
in the `Host:` ((HTTP header)) during HTTP negotiation.
|
||
|
|
||
|
To listen to all ports on the system, the host name may be elided from
|
||
|
the URL on the listener. This will wind up listening to all interfaces
|
||
|
on the system, with possible caveats for IPv4 and IPv6 depending on what
|
||
|
the underlying system supports. (On most modern systems it will map to the
|
||
|
special IPv6 address `::`, and both IPv4 and IPv6 connections will be
|
||
|
permitted, with IPv4 addresses mapped to IPv6 addresses.)
|
||
|
|
||
|
=== Socket Address
|
||
|
|
||
|
When using an xref:nng_sockaddr.5.adoc[`nng_sockaddr`] structure,
|
||
|
the actual structure is either of type
|
||
|
xref:nng_sockaddr_in.5.adoc[`nng_sockaddr_in`] (for IPv4) or
|
||
|
xref:nng_sockaddr_in6.5.adoc[`nng_sockaddr_in6`] (for IPv6).
|
||
|
|
||
|
=== Server Instances
|
||
|
|
||
|
This transport makes use of shared HTTP server (((HTTP, server)))
|
||
|
instances, permitting multiple
|
||
|
sockets or listeners to be configured with the same hostname and port.
|
||
|
When creating a new listener, it is registered with an existing HTTP server
|
||
|
instance if one can be found.
|
||
|
Note that the matching algorithm is somewhat simple,
|
||
|
using only a string based hostname or IP address and port to match.
|
||
|
Therefore it is recommended to use only IP addresses or the empty string as
|
||
|
the hostname in listener URLs.
|
||
|
|
||
|
Likewise, when sharing a server instance, it may not be possible to alter
|
||
|
TLS configuration if the server is already running, as there is only a single
|
||
|
TLS configuration context for the entire server instance.
|
||
|
|
||
|
All sharing of server instances is only typically possible within the same
|
||
|
process.
|
||
|
|
||
|
The server may also be used by other things (for example to serve static
|
||
|
content), in the same process.
|
||
|
|
||
|
=== Transport Options
|
||
|
|
||
|
The following transport options are available. Note that
|
||
|
setting these must be done before the transport is started.
|
||
|
|
||
|
NOTE: The TLS specific options (beginning with `NNG_OPT_TLS_`) are
|
||
|
only available for `wss://` endpoints.
|
||
|
|
||
|
((`NNG_OPT_WS_REQUEST_HEADERS`))::
|
||
|
|
||
|
(string) Concatenation of multiple lines terminated
|
||
|
by CRLF sequences, that can be used to add further headers to the
|
||
|
HTTP request sent when connecting.
|
||
|
This option can be set on dialers, and retrieved from pipes.
|
||
|
|
||
|
((`NNG_OPT_WS_RESPONSE_HEADERS`))::
|
||
|
|
||
|
(string) Concatenation of multiple lines terminated
|
||
|
by CRLF sequences, that can be used to add further headers to the
|
||
|
HTTP response sent when connecting.
|
||
|
This option can be set on listeners, and retrieved from pipes.
|
||
|
|
||
|
((`NNG_OPT_WS_RECV_TEXT`))::
|
||
|
|
||
|
(bool) Enable receiving of TEXT frames at the WebSocket layer.
|
||
|
This option should only be used with the low level
|
||
|
xref:nng_stream.5.adoc[`nng_stream`] API.
|
||
|
When set, the stream will accept in-bound TEXT frames as well as BINARY frames.
|
||
|
|
||
|
NOTE: The SP protocols (such as xref:nng_req.7.adoc[REQ]) require BINARY frames as they pass binary protocol data.
|
||
|
Hence this option should not be used with such protocols.
|
||
|
|
||
|
NOTE: RFC 6455 requires that TEXT frames be discarded and the connection closed if the frame does not contain valid UTF-8 data.
|
||
|
NNG does not perform any such validation.
|
||
|
Applications that need to be strictly conformant should check for this themselves.
|
||
|
|
||
|
((`NNG_OPT_WS_SEND_TEXT`))::
|
||
|
|
||
|
(bool) Enable sending of TEXT frames at the WebSocket layer.
|
||
|
This option should only be used with the low level
|
||
|
xref:nng_stream.5.adoc[`nng_stream`] API.
|
||
|
When set, the stream will send TEXT frames instead of BINARY frames.
|
||
|
|
||
|
NOTE: NNG does not check the frame data, and will attempt to send whatever the client requests.
|
||
|
Peers that are compliant with RFC 6455 will discard TEXT frames (and break the connection) if they do not contain valid UTF-8.
|
||
|
|
||
|
((`NNG_OPT_TLS_CONFIG`))::
|
||
|
|
||
|
(`nng_tls_config *`) The underlying TLS
|
||
|
configuration object for `wss://` endpoints.
|
||
|
A hold is placed on the underlying
|
||
|
configuration object before returning it.
|
||
|
The caller should release the object with
|
||
|
xref:nng_tls_config_free.3tls.adoc[`nng_tls_config_free()`] when it no
|
||
|
longer needs the TLS configuration.
|
||
|
|
||
|
TIP: Use this option when advanced TLS configuration is required.
|
||
|
|
||
|
((`NNG_OPT_TLS_CA_FILE`))::
|
||
|
(string) Write-only option naming a file containing certificates to
|
||
|
use for peer validation.
|
||
|
See xref:nng_tls_config_ca_file.3tls.adoc[`nng_tls_config_ca_file()`] for more
|
||
|
information.
|
||
|
|
||
|
((`NNG_OPT_TLS_CERT_KEY_FILE`))::
|
||
|
(string) Write-only option naming a file containing the local certificate and
|
||
|
associated private key.
|
||
|
The private key used must be unencrypted.
|
||
|
See xref:nng_tls_config_own_cert.3tls.adoc[`nng_tls_config_own_cert()`] for more
|
||
|
information.
|
||
|
|
||
|
((`NNG_OPT_TLS_AUTH_MODE`))::
|
||
|
(`int`) Write-only option used to configure the authentication mode used.
|
||
|
See xref:nng_tls_config_auth_mode.3tls.adoc[`nng_tls_config_auth_mode()`] for
|
||
|
more details.
|
||
|
|
||
|
`NNG_OPT_TLS_VERIFIED`::
|
||
|
(`bool`) Whether the remote peer has been properly verified using TLS
|
||
|
authentication.
|
||
|
May return incorrect results if peer authentication is disabled.
|
||
|
|
||
|
`NNG_OPT_TLS_PEER_CN`::
|
||
|
(string) This read-only option returns the common name of the peer certificate.
|
||
|
May return incorrect results if peer authentication is disabled.
|
||
|
|
||
|
`NNG_OPT_TLS_PEER_ALT_NAMES`::
|
||
|
(string list) returns string list with the subject alternative names of the
|
||
|
peer certificate. May return incorrect results if peer authentication
|
||
|
is disabled.
|
||
|
|
||
|
// We should also look at a hook mechanism for listeners. Probably this could
|
||
|
// look like NNG_OPT_WS_LISTEN_HOOK_FUNC which would take a function pointer
|
||
|
// along the lines of int hook(void *, char *req_headers, char **res_headers),
|
||
|
// and NNG_OPT_LISTEN_HOOK_ARG that passes the void * passed in as first arg.
|
||
|
// Alternatively we can uplevel the HTTP API and pass the actual HTTP objects.
|
||
|
|
||
|
== SEE ALSO
|
||
|
|
||
|
[.text-left]
|
||
|
xref:nng_tls_config_alloc.3tls.adoc[nng_tls_config_alloc(3tls)],
|
||
|
xref:nng_sockaddr.5.adoc[nng_sockaddr(5)],
|
||
|
xref:nng_sockaddr_in.5.adoc[nng_sockaddr_in(5)],
|
||
|
xref:nng_sockaddr_in6.5.adoc[nng_sockaddr_in6(5)],
|
||
|
xref:nng.7.adoc[nng(7)]
|