websocket(3)



websocket(3tcl)           websocket client and server          websocket(3tcl)

______________________________________________________________________________

NAME
       websocket - Tcl implementation of the websocket protocol

SYNOPSIS
       package require Tcl  8.4

       package require http  2.7

       package require logger

       package require sha1

       package require base64

       package require websocket  ?1.3.1?

       ::websocket::open url handler ?options?

       ::websocket::send sock type ?msg? ?final?

       ::websocket::server sock

       ::websocket::live sock path cb ?proto?

       ::websocket::test srvSock cliSock path ?hdrs? ?qry?

       ::websocket::upgrade sock

       ::websocket::takeover sock handler ?server?

       ::websocket::conninfo sock what

       ::websocket::find ?host? ?port?

       ::websocket::configure sock args

       ::websocket::loglevel ?loglvl?

       ::websocket::close sock ?code? ?reason?

______________________________________________________________________________

DESCRIPTION
       NOTE: THIS DOCUMENTATION IS WORK IN PROGRESS...

       The  websocket  library  is  a pure Tcl implementation of the WebSocket
       specification covering the needs of both clients and servers.  Websock-
       ets  provide  a  way  to upgrade a regular HTTP connection into a long-
       lived and continuous binary or text communication  between  the  client
       and  the  server.  The library offers a high-level interface to receive
       and send data as specified in RFC 6455 (v. 13 of the protocol), reliev-
       ing callers from all necessary protocol framing and reassembly.  It im-
       plements the ping facility specified by  the  standard,  together  with
       levers  to control it.  Pings are server-driven and ensure the liveness
       of the connection across home (NAT) networks.  The library has a number
       of  introspection  facilities to inquire about the current state of the
       connection, but also to receive notifications  of  incoming  pings,  if
       necessary.  Finally, the library contains a number of helper procedures
       to facilitate the upgrading handshaking in existing web servers.

       Central to the library is the procedure websocket::takeover  that  will
       take over a regular socket and treat it as a WebSocket, thus performing
       all necessary protocol framing, packetisation and reassembly in servers
       and  clients.   The procedure also takes a handler, a command that will
       be called back each time a (possibly reassembled) packet from  the  re-
       mote  end is ready for delivery at the original caller.  While exported
       by the package, the command websocket::takeover is seldom called in ap-
       plications, since the package provides other commands that are specifi-
       cally tuned for the needs of clients and servers.

       Typically, clients will open a connection to a remote server by provid-
       ing  a  WebSocket  URL  (ws: or wss: schemes) and the handler described
       above to the command websocket::open. The opening procedure is a  wrap-
       per around the latest http::geturl implementations: it arranges to keep
       the socket created within the http library opened for reuse,  but  con-
       fiscates it from its (internal) map of known sockets for its own use.

       Servers will start by registering themselves through the command ::web-
       socket::server and a number of handlers for  paths  using  the  command
       ::websocket::live.   Then  for  each  incoming  client connection, they
       should test the incoming request to detect if it is an upgrade  request
       using  ::websocket::test  and  perform the final handshake to place the
       socket connection under the control of the websocket  library  and  its
       central procedure using ::websocket::upgrade.

       Apart  from  these main commands, the package provides a number of com-
       mands for introspection and basic operations on the websockets that  it
       has  under its control.  As WebSockets connections are long-lived, most
       remaining communication with the library will be by way  of  callbacks,
       i.e.  commands  that are triggered whenever important events within the
       library have occur, but mostly whenever data has  been  received  on  a
       WebSocket.

CALLBACKS
       A  number  of commands of the library take a handler handler command as
       an argument, a command which will be  called  back  upon  reception  of
       data,  but  also upon important events within the library or events re-
       sulting from control messages sent by the remote end.  For  each  call-
       back being performed, the following arguments will be appended:

       sock   The  identifier  of  the  WebSocket,  as returned for example by
              ::websocket::open

       type   A textual type describing the event or message content,  can  be
              one of the following

              text   Complete text message

              binary Complete binary message

              ping   Incoming ping message

              connect
                     Notification of successful connection to server

              disconnect
                     Disconnection from remote end

              close  Pending closure of connection

       msg    Will contain the data of the message, whenever this is relevant,
              i.e. when the type is text, binary or ping and whenever there is
              data available.

API
       ::websocket::open url handler ?options?
              This  command is used in clients to open a WebSocket to a remote
              websocket-enabled HTTP server.  The URL provided as an  argument
              in  url  should start with ws: or wss:, which are the WebSockets
              counterpart of http: and https:. The handler is a  command  that
              will  be  called  back  on  data reception or whenever important
              events  occur  during  the  life  of  the   websocket.    ::web-
              socket::open will return a socket which serves as both the iden-
              tifier of the websocket and of the physical low-level socket  to
              the  server.   This socket can be used in a number of other com-
              mands for introspection or for controlling the behaviour of  the
              library.   Being essentially a wrapper around the ::http::geturl
              command, this command provides mostly the same set  of  dash-led
              options  than  ::http::geturl.  Documented below are the options
              that differ from ::http::geturl and which are  specific  to  the
              WebSocket library.

              -headers
                     This  option is supported, knowing that a number of head-
                     ers will be automatically added internally in the library
                     in  order  to  be  able to handshake the upgrading of the
                     socket from a regular HTTP socket to a WebSocket with the
                     server.

              -validate
                     This  option is not supported as it has no real point for
                     WebSockets.

              -handler
                     This option is used internally by the  websocket  library
                     and cannot be used.

              -command
                     This  option  is used internally by the websocket library
                     and cannot be used.

              -protocol
                     This option specifies a list of application protocols  to
                     handshake with the server.  This protocols might help the
                     server triggering application specific features.

              -timeout
                     This option is supported, but will implemented as part of
                     the library to enable a number of finalising cleanups.

       ::websocket::send sock type ?msg? ?final?
              This  command  will  send a fragment or a control message to the
              remote end of the WebSocket identified by sock.  The type of the
              message  specified in type can either be an integer according to
              the specification or (preferrably) one of the following case in-
              sensitive  strings:  "text", "binary" or "ping".  The content of
              the message to send to the remote end is contained  in  msg  and
              message  fragmentation is made possible by the setting the argu-
              ment final to non-true, knowing that the type of  each  fragment
              has  then  to  be  the  same.  The command returns the number of
              bytes that were effectively sent, or -1 on errors.  Serious  er-
              rors,  such  as when sock does not identify a known WebSocket or
              when the connection is not stable yet will generate errors  that
              must be catched.

       ::websocket::server sock
              This  command  registers the (accept) socket sock as the identi-
              fier fo an HTTP server that  is  capable  of  doing  WebSockets.
              Paths  onto  which  this server will listen for incoming connec-
              tions should be declared using ::websocket::live.

       ::websocket::live sock path cb ?proto?
              This procedure registers callbacks that will be performed  on  a
              WebSocket  compliant  server registered with ::websocket::server
              whenever a client connects to  a  matching  path  and  protocol.
              sock  is  the listening socket of the websocket compliant server
              declared using ::websocket::server.  path is a  glob-style  path
              to match in client request, whenever this will occur.  cb is the
              command to callback (see Callbacks).  proto is a glob-style pro-
              tocol name matcher.

       ::websocket::test srvSock cliSock path ?hdrs? ?qry?
              This  procedure  will  test  if  the connection from an incoming
              client on socket cliSock and on the path path is the opening  of
              a  WebSocket stream within a known server srvSock.  The incoming
              request is not upgraded at once, instead a  (temporary)  context
              for the incoming connection is created.  This allows server code
              to perform a number of actions, if necessary,  before  the  Web-
              Socket  stream  connection  goes  live.   The  text  is  made by
              analysing the content of the headers hdrs which should contain a
              dictionary  list of the HTTP headers of the incoming client con-
              nection.  The command will return 1 if this is an incoming  Web-
              Socket upgrade request and 0 otherwise.

       ::websocket::upgrade sock
              Upgrade   the  socket  sock  that  had  been  deemed  by  ::web-
              socket::test to be a WebSocket connection request to a true Web-
              Socket as recognised by this library. As a result, the necessary
              connection handshake will be sent to the client, and the command
              will  arrange  for relevant callbacks to be made during the life
              of the WebSocket, notably using the specifications described  by
              ::websocket::live.

       ::websocket::takeover sock handler ?server?
              Take  over  the existing opened socket sock to implement sending
              and receiving WebSocket framing on top of the socket.  The  pro-
              cedure arranges for handler to be called back whenever messages,
              control messages or other important internal events are received
              or  occured.   server  defaults  to  0 and can be set to 1 (or a
              boolean that evaluates to true) to specify that this is  a  Web-
              Socket  within a server.  Apart from specificities in the proto-
              col, servers should ping their clients at regular  intervals  in
              order to keep the connection opened at all time.  When server is
              set to true, the library will arrange to send these pings  auto-
              matically.

       ::websocket::conninfo sock what
              Provides  callers with some introspection facilities in order to
              get some semi-internal information about an  existing  websocket
              connection.  Depending  on  the  value of the what argument, the
              procedure returns the following piece of information:

              peername
                     Name (preferred) or IP of remote end.

              sockname
                     or name Name or IP of local end.

              closed 1 if the connection is closed, 0 otherwise

              client 1 if the connection is a client websocket, 0 otherwise

              server 1 if the connection is a server websocket, 0 otherwise

              type   server if the connection is a  server  websocket,  client
                     otherwise.

              handler
                     The handler command associated to the websocket

              state  The state of the websocket, which can be one of:

                     CONNECTING
                            Connection to remote end is in progress.

                     CONNECTED
                            Connection is connected to remote end.

                     CLOSED Connection is closed.

       ::websocket::find ?host? ?port?
              Look  among  existing  websocket  connections  for the ones that
              match the hostname and port number filters passed as parameters.
              This lookup takes the remote end into account and the host argu-
              ment is matched both against the hostname  (whenever  available)
              and  the  IP  address of the remote end.  Both the host and port
              arguments are glob-style string matching filters and default  to
              *, i.e. will match any host and/or port number.

       ::websocket::configure sock args
              This  command takes a number of dash-led options (and their val-
              ues) to configure the behaviour of an existing websocket connec-
              tion.   The  recognised  options  are the following (they can be
              shortened to the lowest common denominator):

              -keepalive
                     is the number of seconds between each keepalive pings be-
                     ing sent along the connection.  A zero or negative number
                     will effectively  turn  off  the  feature.   In  servers,
                     -keepalive  defaults  to  30  seconds, and in clients, no
                     pings are initiated.

              -ping  is the text that is  used  during  the  automated  pings.
                     This  text  defaults  to  the empty string, leading to an
                     empty ping.

       ::websocket::loglevel ?loglvl?
              Set or query the log level of the library, which defaults to er-
              ror.   Logging is built on top of the logger module, and the li-
              brary makes use of the following levels:  debug,  info,  notice,
              warn  and  error.   When called with no argument, this procedure
              will simply return the  current  log  level.   Otherwise  loglvl
              should contain the desired log level.

       ::websocket::close sock ?code? ?reason?
              Gracefully  close  a  websocket  that was directly or indirectly
              passed to ::websocket::takeover.  The procedure will  optionally
              send the code and describing reason as part of the closure hand-
              shake.  Good defaults are provided, so that reasons for a number
              of  known codes will be sent back. Only the first 125 characters
              of a reason string will be kept and sent as part  of  the  hand-
              shake. The known codes are:

              1000   Normal closure (the default code when none provided).

              1001   Endpoint going away

              1002   Protocol Error

              1003   Received incompatible data type

              1006   Abnormal closure

              1007   Received data not consistent with type

              1008   Policy violation

              1009   Received message too big

              1010   Missing extension

              1011   Unexpected condition

              1015   TLS handshake error

EXAMPLES
       The following example opens a websocket connection to the echo service,
       waits 400ms to ensure that the connection  is  really  established  and
       sends  a single textual message which should be echoed back by the echo
       service.  A real example would probably use  the  connect  callback  to
       know  when connection to the remote server has been establish and would
       only send data at that time.

              package require websocket
              ::websocket::loglevel debug

              proc handler { sock type msg } {
                  switch -glob -nocase -- $type {
                co* {
                    puts "Connected on $sock"
                }
                te* {
                    puts "RECEIVED: $msg"
                }
                cl* -
                dis* {
                }
                  }

              }

              proc test { sock } {
                  puts "[::websocket::conninfo $sock type] from [::websocket::conninfo $sock sockname] to [::websocket::conninfo $sock peername]"

                  ::websocket::send $sock text "Testing, testing..."
              }

              set sock [::websocket::open ws://echo.websocket.org/ handler]
              after 400 test $sock
              vwait forever

TLS SECURITY CONSIDERATIONS
       This package uses the TLS package to handle the security for https urls
       and other socket connections.

       Policy  decisions like the set of protocols to support and what ciphers
       to use are not the responsibility of TLS, nor of  this  package  itself
       however.   Such  decisions are the responsibility of whichever applica-
       tion is using the package, and are likely  influenced  by  the  set  of
       servers the application will talk to as well.

       For  example,  in light of the recent POODLE attack [http://googleonli-
       nesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
       ssl-30.html] discovered by Google many servers will disable support for
       the SSLv3 protocol.  To handle this change the applications  using  TLS
       must  be  patched,  and not this package, nor TLS itself.  Such a patch
       may be as simple as generally activating tls1 support, as shown in  the
       example below.

                  package require tls
                  tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

                  ... your own application code ...

BUGS, IDEAS, FEEDBACK
       This  document,  and the package it describes, will undoubtedly contain
       bugs and other problems.  Please report such in the category  websocket
       of  the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].  Please
       also report any ideas for enhancements you may have for either  package
       and/or documentation.

       When proposing code changes, please provide unified diffs, i.e the out-
       put of diff -u.

       Note further that  attachments  are  strongly  preferred  over  inlined
       patches.  Attachments  can  be  made  by  going to the Edit form of the
       ticket immediately after its creation, and  then  using  the  left-most
       button in the secondary navigation bar.

SEE ALSO
       http

KEYWORDS
       http, internet, net, rfc 6455

CATEGORY
       Networking

tcllib                               1.3.1                     websocket(3tcl)

Man(1) output converted with man2html
list of all man pages