1websocket(n) websocket client and server websocket(n)
2
3
4
5______________________________________________________________________________
6
8 websocket - Tcl implementation of the websocket protocol
9
11 package require Tcl 8.4
12
13 package require http 2.7
14
15 package require logger
16
17 package require sha1
18
19 package require base64
20
21 package require websocket ?1.3.1?
22
23 ::websocket::open url handler ?options?
24
25 ::websocket::send sock type ?msg? ?final?
26
27 ::websocket::server sock
28
29 ::websocket::live sock path cb ?proto?
30
31 ::websocket::test srvSock cliSock path ?hdrs? ?qry?
32
33 ::websocket::upgrade sock
34
35 ::websocket::takeover sock handler ?server?
36
37 ::websocket::conninfo sock what
38
39 ::websocket::find ?host? ?port?
40
41 ::websocket::configure sock args
42
43 ::websocket::loglevel ?loglvl?
44
45 ::websocket::close sock ?code? ?reason?
46
47______________________________________________________________________________
48
50 NOTE: THIS DOCUMENTATION IS WORK IN PROGRESS...
51
52 The websocket library is a pure Tcl implementation of the WebSocket
53 specification covering the needs of both clients and servers. Websock‐
54 ets provide a way to upgrade a regular HTTP connection into a long-
55 lived and continuous binary or text communication between the client
56 and the server. The library offers a high-level interface to receive
57 and send data as specified in RFC 6455 (v. 13 of the protocol), reliev‐
58 ing callers from all necessary protocol framing and reassembly. It
59 implements the ping facility specified by the standard, together with
60 levers to control it. Pings are server-driven and ensure the liveness
61 of the connection across home (NAT) networks. The library has a number
62 of introspection facilities to inquire about the current state of the
63 connection, but also to receive notifications of incoming pings, if
64 necessary. Finally, the library contains a number of helper procedures
65 to facilitate the upgrading handshaking in existing web servers.
66
67 Central to the library is the procedure websocket::takeover that will
68 take over a regular socket and treat it as a WebSocket, thus performing
69 all necessary protocol framing, packetisation and reassembly in servers
70 and clients. The procedure also takes a handler, a command that will
71 be called back each time a (possibly reassembled) packet from the
72 remote end is ready for delivery at the original caller. While
73 exported by the package, the command websocket::takeover is seldom
74 called in applications, since the package provides other commands that
75 are specifically tuned for the needs of clients and servers.
76
77 Typically, clients will open a connection to a remote server by provid‐
78 ing a WebSocket URL (ws: or wss: schemes) and the handler described
79 above to the command websocket::open. The opening procedure is a wrap‐
80 per around the latest http::geturl implementations: it arranges to keep
81 the socket created within the http library opened for reuse, but con‐
82 fiscates it from its (internal) map of known sockets for its own use.
83
84 Servers will start by registering themselves through the command ::web‐
85 socket::server and a number of handlers for paths using the command
86 ::websocket::live. Then for each incoming client connection, they
87 should test the incoming request to detect if it is an upgrade request
88 using ::websocket::test and perform the final handshake to place the
89 socket connection under the control of the websocket library and its
90 central procedure using ::websocket::upgrade.
91
92 Apart from these main commands, the package provides a number of com‐
93 mands for introspection and basic operations on the websockets that it
94 has under its control. As WebSockets connections are long-lived, most
95 remaining communication with the library will be by way of callbacks,
96 i.e. commands that are triggered whenever important events within the
97 library have occur, but mostly whenever data has been received on a
98 WebSocket.
99
101 A number of commands of the library take a handler handler command as
102 an argument, a command which will be called back upon reception of
103 data, but also upon important events within the library or events
104 resulting from control messages sent by the remote end. For each call‐
105 back being performed, the following arguments will be appended:
106
107 sock The identifier of the WebSocket, as returned for example by
108 ::websocket::open
109
110 type A textual type describing the event or message content, can be
111 one of the following
112
113 text Complete text message
114
115 binary Complete binary message
116
117 ping Incoming ping message
118
119 connect
120 Notification of successful connection to server
121
122 disconnect
123 Disconnection from remote end
124
125 close Pending closure of connection
126
127 msg Will contain the data of the message, whenever this is relevant,
128 i.e. when the type is text, binary or ping and whenever there is
129 data available.
130
132 ::websocket::open url handler ?options?
133 This command is used in clients to open a WebSocket to a remote
134 websocket-enabled HTTP server. The URL provided as an argument
135 in url should start with ws: or wss:, which are the WebSockets
136 counterpart of http: and https:. The handler is a command that
137 will be called back on data reception or whenever important
138 events occur during the life of the websocket. ::web‐
139 socket::open will return a socket which serves as both the iden‐
140 tifier of the websocket and of the physical low-level socket to
141 the server. This socket can be used in a number of other com‐
142 mands for introspection or for controlling the behaviour of the
143 library. Being essentially a wrapper around the ::http::geturl
144 command, this command provides mostly the same set of dash-led
145 options than ::http::geturl. Documented below are the options
146 that differ from ::http::geturl and which are specific to the
147 WebSocket library.
148
149 -headers
150 This option is supported, knowing that a number of head‐
151 ers will be automatically added internally in the library
152 in order to be able to handshake the upgrading of the
153 socket from a regular HTTP socket to a WebSocket with the
154 server.
155
156 -validate
157 This option is not supported as it has no real point for
158 WebSockets.
159
160 -handler
161 This option is used internally by the websocket library
162 and cannot be used.
163
164 -command
165 This option is used internally by the websocket library
166 and cannot be used.
167
168 -protocol
169 This option specifies a list of application protocols to
170 handshake with the server. This protocols might help the
171 server triggering application specific features.
172
173 -timeout
174 This option is supported, but will implemented as part of
175 the library to enable a number of finalising cleanups.
176
177 ::websocket::send sock type ?msg? ?final?
178 This command will send a fragment or a control message to the
179 remote end of the WebSocket identified by sock. The type of the
180 message specified in type can either be an integer according to
181 the specification or (preferrably) one of the following case
182 insensitive strings: "text", "binary" or "ping". The content of
183 the message to send to the remote end is contained in msg and
184 message fragmentation is made possible by the setting the argu‐
185 ment final to non-true, knowing that the type of each fragment
186 has then to be the same. The command returns the number of
187 bytes that were effectively sent, or -1 on errors. Serious
188 errors, such as when sock does not identify a known WebSocket or
189 when the connection is not stable yet will generate errors that
190 must be catched.
191
192 ::websocket::server sock
193 This command registers the (accept) socket sock as the identi‐
194 fier fo an HTTP server that is capable of doing WebSockets.
195 Paths onto which this server will listen for incoming connec‐
196 tions should be declared using ::websocket::live.
197
198 ::websocket::live sock path cb ?proto?
199 This procedure registers callbacks that will be performed on a
200 WebSocket compliant server registered with ::websocket::server]
201 whenever a client connects to a matching path and protocol.
202 sock is the listening socket of the websocket compliant server
203 declared using ::websocket::server. path is a glob-style path
204 to match in client request, whenever this will occur. cb is the
205 command to callback (see Callbacks). proto is a glob-style pro‐
206 tocol name matcher.
207
208 ::websocket::test srvSock cliSock path ?hdrs? ?qry?
209 This procedure will test if the connection from an incoming
210 client on socket cliSock and on the path path is the opening of
211 a WebSocket stream within a known server srvSock. The incoming
212 request is not upgraded at once, instead a (temporary) context
213 for the incoming connection is created. This allows server code
214 to perform a number of actions, if necessary, before the Web‐
215 Socket stream connection goes live. The text is made by
216 analysing the content of the headers hdrs which should contain a
217 dictionary list of the HTTP headers of the incoming client con‐
218 nection. The command will return 1 if this is an incoming Web‐
219 Socket upgrade request and 0 otherwise.
220
221 ::websocket::upgrade sock
222 Upgrade the socket sock that had been deemed by ::web‐
223 socket::test to be a WebSocket connection request to a true Web‐
224 Socket as recognised by this library. As a result, the necessary
225 connection handshake will be sent to the client, and the command
226 will arrange for relevant callbacks to be made during the life
227 of the WebSocket, notably using the specifications described by
228 ::websocket::live.
229
230 ::websocket::takeover sock handler ?server?
231 Take over the existing opened socket sock to implement sending
232 and receiving WebSocket framing on top of the socket. The pro‐
233 cedure arranges for handler to be called back whenever messages,
234 control messages or other important internal events are received
235 or occured. server defaults to 0 and can be set to 1 (or a
236 boolean that evaluates to true) to specify that this is a Web‐
237 Socket within a server. Apart from specificities in the proto‐
238 col, servers should ping their clients at regular intervals in
239 order to keep the connection opened at all time. When server is
240 set to true, the library will arrange to send these pings auto‐
241 matically.
242
243 ::websocket::conninfo sock what
244 Provides callers with some introspection facilities in order to
245 get some semi-internal information about an existing websocket
246 connection. Depending on the value of the what argument, the
247 procedure returns the following piece of information:
248
249 peername
250 Name (preferred) or IP of remote end.
251
252 sockname
253 or name Name or IP of local end.
254
255 closed 1 if the connection is closed, 0 otherwise
256
257 client 1 if the connection is a client websocket, 0 otherwise
258
259 server 1 if the connection is a server websocket, 0 otherwise
260
261 type server if the connection is a server websocket, client
262 otherwise.
263
264 handler
265 The handler command associated to the websocket
266
267 state The state of the websocket, which can be one of:
268
269 CONNECTING
270 Connection to remote end is in progress.
271
272 CONNECTED
273 Connection is connected to remote end.
274
275 CLOSED Connection is closed.
276
277 ::websocket::find ?host? ?port?
278 Look among existing websocket connections for the ones that
279 match the hostname and port number filters passed as parameters.
280 This lookup takes the remote end into account and the host argu‐
281 ment is matched both against the hostname (whenever available)
282 and the IP address of the remote end. Both the host and port
283 arguments are glob-style string matching filters and default to
284 *, i.e. will match any host and/or port number.
285
286 ::websocket::configure sock args
287 This command takes a number of dash-led options (and their val‐
288 ues) to configure the behaviour of an existing websocket connec‐
289 tion. The recognised options are the following (they can be
290 shortened to the lowest common denominator):
291
292 -keepalive
293 is the number of seconds between each keepalive pings
294 being sent along the connection. A zero or negative num‐
295 ber will effectively turn off the feature. In servers,
296 -keepalive defaults to 30 seconds, and in clients, no
297 pings are initiated.
298
299 -ping is the text that is used during the automated pings.
300 This text defaults to the empty string, leading to an
301 empty ping.
302
303 ::websocket::loglevel ?loglvl?
304 Set or query the log level of the library, which defaults to
305 error. Logging is built on top of the logger module, and the
306 library makes use of the following levels: debug, info, notice,
307 warn and error. When called with no argument, this procedure
308 will simply return the current log level. Otherwise loglvl
309 should contain the desired log level.
310
311 ::websocket::close sock ?code? ?reason?
312 Gracefully close a websocket that was directly or indirectly
313 passed to ::websocket::takeover. The procedure will optionally
314 send the code and describing reason as part of the closure hand‐
315 shake. Good defaults are provided, so that reasons for a number
316 of known codes will be sent back. Only the first 125 characters
317 of a reason string will be kept and sent as part of the hand‐
318 shake. The known codes are:
319
320 1000 Normal closure (the default code when none provided).
321
322 1001 Endpoint going away
323
324 1002 Protocol Error
325
326 1003 Received incompatible data type
327
328 1006 Abnormal closure
329
330 1007 Received data not consistent with type
331
332 1008 Policy violation
333
334 1009 Received message too big
335
336 1010 Missing extension
337
338 1011 Unexpected condition
339
340 1015 TLS handshake error
341
343 The following example opens a websocket connection to the echo service,
344 waits 400ms to ensure that the connection is really established and
345 sends a single textual message which should be echoed back by the echo
346 service. A real example would probably use the connect callback to
347 know when connection to the remote server has been establish and would
348 only send data at that time.
349
350
351 package require websocket
352 ::websocket::loglevel debug
353
354 proc handler { sock type msg } {
355 switch -glob -nocase -- $type {
356 co* {
357 puts "Connected on $sock"
358 }
359 te* {
360 puts "RECEIVED: $msg"
361 }
362 cl* -
363 dis* {
364 }
365 }
366
367 }
368
369 proc test { sock } {
370 puts "[::websocket::conninfo $sock type] from [::websocket::conninfo $sock sockname] to [::websocket::conninfo $sock peername]"
371
372 ::websocket::send $sock text "Testing, testing..."
373 }
374
375 set sock [::websocket::open ws://echo.websocket.org/ handler]
376 after 400 test $sock
377 vwait forever
378
379
381 This package uses the TLS package to handle the security for https urls
382 and other socket connections.
383
384 Policy decisions like the set of protocols to support and what ciphers
385 to use are not the responsibility of TLS, nor of this package itself
386 however. Such decisions are the responsibility of whichever applica‐
387 tion is using the package, and are likely influenced by the set of
388 servers the application will talk to as well.
389
390 For example, in light of the recent POODLE attack [http://googleonli‐
391 nesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
392 ssl-30.html] discovered by Google many servers will disable support for
393 the SSLv3 protocol. To handle this change the applications using TLS
394 must be patched, and not this package, nor TLS itself. Such a patch
395 may be as simple as generally activating tls1 support, as shown in the
396 example below.
397
398
399 package require tls
400 tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol
401
402 ... your own application code ...
403
404
406 This document, and the package it describes, will undoubtedly contain
407 bugs and other problems. Please report such in the category websocket
408 of the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. Please
409 also report any ideas for enhancements you may have for either package
410 and/or documentation.
411
412 When proposing code changes, please provide unified diffs, i.e the out‐
413 put of diff -u.
414
415 Note further that attachments are strongly preferred over inlined
416 patches. Attachments can be made by going to the Edit form of the
417 ticket immediately after its creation, and then using the left-most
418 button in the secondary navigation bar.
419
421 http
422
424 http, internet, net, rfc 6455
425
427 Networking
428
429
430
431tcllib 1.3.1 websocket(n)