webtube 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc9f83d60d21848e0017e45fd15b6371bef6241a
4
- data.tar.gz: 8978bc791cb5bd81235e6f2adcf4049e24a8b5af
3
+ metadata.gz: 8b448e7b4b7219de788008716f089c4582312203
4
+ data.tar.gz: 17b42da8e523eebaf496404bf0ec43c4d2f22264
5
5
  SHA512:
6
- metadata.gz: 18a58ff5db543ef382ca535269133057018dbaad88715f7f81c1815e145df03c2a336ac246898e855737c404749fd88ceb682d04cdd313608959e8a2af8cc1cd
7
- data.tar.gz: 9cdb8b9c3c435493e4d649f5ba9e517cae4a34d80950064a3d4fb8a6cbef8b791bb003db76181e23cd70f37c4581320ccec59b2bcebf4fbba2c6995a15295068
6
+ metadata.gz: b8412f80b2f0590b876658b695dbc23a4932c66e433efc30636275d32a499e53c5d0fa3f6f45df0d4dd56db5fc3fff537da255e229a8215df54552124203611a
7
+ data.tar.gz: ab3e133faf0b9957832e4bad28937e7bac16158aa6b31a9a3b3f29ea7d5b66ec1e2b8e8dafd717837a435ee3600775fe59165d3d5aa65d59d6152e17d82f0df2
data/README CHANGED
@@ -1,11 +1,11 @@
1
- This is Webtube, a Ruby implementation of the WebSocket protocol defined in
2
- RFC 6455.
1
+ This is Webtube, a Ruby implementation of the WebSocket protocol
2
+ defined in RFC 6455.
3
3
 
4
4
 
5
5
  == Sample client
6
6
 
7
- (Also see [[wsc]], a basic command line utility for talking to WebSocket
8
- servers and included with the Webtube distribution.)
7
+ (Also see [[wsc]], a basic command line utility for talking to
8
+ WebSocket servers and included with the Webtube distribution.)
9
9
 
10
10
  require 'webtube'
11
11
 
@@ -25,14 +25,15 @@ servers and included with the Webtube distribution.)
25
25
 
26
26
  == Sample server
27
27
 
28
- (This code is also available as a separate file; see [[sample-server.rb]].)
28
+ (This code is also available as a separate file; see
29
+ [[sample-server.rb]].)
29
30
 
30
31
  #! /usr/bin/ruby
31
32
 
32
- # A sample WEBrick server using the Webtube API. It listens on port 8888 and
33
- # provides two services: [[/diag]], which logs all the events from
34
- # [[Webtube#run]] and remains silent towards the client (although note that
35
- # the Webtube library pongs the pings), and [[/echo]], which echos.
33
+ # A sample WEBrick server using the Webtube API. It listens
34
+ # on port 8888 and provides two services: [[/diag]], which
35
+ # logs all the events from [[Webtube#run]] and remains silent
36
+ # towards the client, and [[/echo]], which echos.
36
37
 
37
38
  require 'webrick'
38
39
  require 'webtube/webrick'
@@ -78,17 +79,24 @@ servers and included with the Webtube distribution.)
78
79
 
79
80
  == WebSocketCat's commands
80
81
 
81
- Webtube comes with [[wsc]], a command line utility for talking to WebSocket
82
- server. A session might look like this:
82
+ Webtube comes with [[wsc]], a command line utility for talking
83
+ to WebSocket server. A session might look like this:
83
84
 
84
85
  $ wsc ws://echo.websocket.org/
85
86
  Connecting to ws://echo.websocket.org/ ...
86
- | 101 Web Socket Protocol Handshake
87
- | connection: Upgrade
88
- | date: Fri, 10 Oct 2014 12:43:49 GMT
89
- | sec-websocket-accept: Uk2zpTKu2TaQtJ2esybCgeB89qk=
90
- | server: Kaazing Gateway
91
- | upgrade: websocket
87
+ > GET / HTTP/1.1
88
+ > Host: echo.websocket.org
89
+ > Upgrade: websocket
90
+ > Connection: upgrade
91
+ > Sec-websocket-key: HSJFpBo1mtbAS3h/7593Cw==
92
+ > Sec-websocket-version: 13
93
+
94
+ < 101 Web Socket Protocol Handshake
95
+ < connection: Upgrade
96
+ < date: Thu, 26 Apr 2018 19:25:11 GMT
97
+ < sec-websocket-accept: CN9MPzM4nmqeRGsR0YFDsipOXzQ=
98
+ < server: Kaazing Gateway
99
+ < upgrade: websocket
92
100
 
93
101
  *** open
94
102
  Hello, server!
@@ -99,155 +107,231 @@ server. A session might look like this:
99
107
  /close 1001
100
108
  *** close
101
109
 
102
- Prefixed with [[|]] is the HTTP response header from the server, with [[<<<]]
103
- are incoming text messages (non-text messages are prefixed with [[<N<]] where N
104
- is the message opcode), and with [[***]] are miscellaneous other events. Lines
105
- entered by user are sent to the server as text messages. The user can invoke
106
- some special commands using the slash prefix:
110
+ Prefixed with [[>]] is the HTTP request to initiate a WebSocket
111
+ connection, with [[<]] is the HTTP response header from the
112
+ server, with [[<<<]] are incoming text messages (non-text
113
+ messages are prefixed with [[<N<]] where N is the message
114
+ opcode), and with [[***]] are miscellaneous other events. Lines
115
+ entered by user are sent to the server as text messages. The
116
+ user can invoke some special commands using the slash prefix:
107
117
 
108
118
  - [[/ping [message]]] sends a ping frame to the server.
109
119
 
110
- - [[/close [status [explanation]]]] sends a close frame to the server. The
111
- status code is specified as an unsigned decimal number.
120
+ - [[/close [status [explanation]]]] sends a close frame to the
121
+ server. The status code is specified as an unsigned decimal
122
+ number.
112
123
 
113
- - [[/N [payload]]] sends a message or control frame of opcode [[N]], given as a
114
- single hex digit, to the server. Per protocol specification, [[/1]] is text
115
- message, [[/2]] is binary message, [[/8]] is close, [[/9]] is ping, [[/A]] is
116
- pong. Other opcodes can have application-specific meaning. Note that the
117
- specification requires kicking clients (or servers) who send messages so
118
- cryptic that the server (or client) can't understand them.
124
+ - [[/N [payload]]] sends a message or control frame of opcode
125
+ [[N]], given as a single hex digit, to the server. Per
126
+ protocol specification, [[/1]] is text message, [[/2]] is
127
+ binary message, [[/8]] is close, [[/9]] is ping, [[/A]] is
128
+ pong. Other opcodes can have application-specific meaning.
129
+ Note that the specification requires kicking clients (or
130
+ servers) who send messages so cryptic that the server (or
131
+ client) can't understand them.
119
132
 
120
133
  - [[/help]] shows online help.
121
134
 
122
- If you need to start a text message with a slash, you can double it for escape,
123
- or you can use the explicit [[/1]] command. EOF from stdin is equivalent to
124
- [[/close 1000]].
135
+ If you need to start a text message with a slash, you can double
136
+ it for escape, or you can use the explicit [[/1]] command. EOF
137
+ from stdin is equivalent to [[/close 1000]].
125
138
 
126
139
 
127
140
  == API overview
128
141
 
129
142
  === The [[Webtube]] class
130
143
 
131
- (Direct) instances of the [[Webtube]] class are hashed and [[eql?]]-compared by
132
- identity, thus behaving in an intuitive manner when used as keys of a [[Hash]]
133
- or elements of a [[Set]].
144
+ (Direct) instances of the [[Webtube]] class are hashed and
145
+ [[eql?]]-compared by identity, thus behaving in an intuitive
146
+ manner when used as keys of a [[Hash]] or elements of a [[Set]].
134
147
 
135
- In addition to the methods described below, each [[Webtube]] instance will have
136
- the readable and writable attributes [[header]], [[session]], and [[context]].
137
- [[Webtube]] does not care about them; they are intended to facilitate user code
138
- associating contextual or environmental data with the [[Webtube]].
148
+ In addition to the methods described below, each [[Webtube]]
149
+ instance will have the readable and writable attributes
150
+ [[header]], [[session]], and [[context]]. [[Webtube]] does not
151
+ care about them; they are intended to facilitate user code
152
+ associating contextual or environmental data with the
153
+ [[Webtube]].
139
154
 
140
155
  The [[Webtube]]-[[WEBrick]] integration (in particular,
141
- [[WEBrick::HTTPServer#accept_webtube]]) sets the [[header]] attribtue of newly
142
- created [[Webtube]] instances to the [[WEBrick::HTTPRequest]] used to establish
143
- the WebSocket connection; this may facilitate extracting HTTP header fields,
144
- URL query parameters or cookies from the request at a later time. (Note that
145
- because the upgrade request is necessary delivered using the HTTP [[GET]]
146
- method, the HTTP file upload protocol, which requires [[POST]] is not available
147
- for WebSocket connections. Also note that the WebDAV extensions are mutually
148
- incompatible with the WebSocket protocol, within the bounds of a single HTTP
149
- request, for the same reason.)
156
+ [[WEBrick::HTTPServer#accept_webtube]]) sets the [[header]]
157
+ attribute of newly created [[Webtube]] instances to the
158
+ [[WEBrick::HTTPRequest]] used to establish the WebSocket
159
+ connection; this may facilitate extracting HTTP header fields,
160
+ URL query parameters or cookies from the request at a later
161
+ time. (Note that because the upgrade request is necessary
162
+ delivered using the HTTP [[GET]] method, the HTTP file upload
163
+ protocol, which requires [[POST]] is not available for WebSocket
164
+ connections. Also note that the WebDAV extensions are mutually
165
+ incompatible with the WebSocket protocol, within the bounds of a
166
+ single HTTP request, for the same reason.)
150
167
 
151
168
 
152
169
  ==== [[Webtube::connect]]: connect to a remote server
153
170
 
154
- A WebSocket connection to a remote server can be set up by calling
155
- [[Webtube::connect]]. The calling interface goes like this:
171
+ A WebSocket connection to a remote server can be set up by
172
+ calling [[Webtube::connect]]. The calling interface goes like
173
+ this:
156
174
 
157
175
  Webtube::connect(url,
158
- header_fields: {},
159
- ssl_verify_mode: nil,
160
- on_http_response: nil,
161
176
  allow_rsv_bits: 0,
162
- allow_opcodes: [Webtube::OPCODE_TEXT, Webtube::OPCODE_BINARY],
163
- close_socket: true)
164
-
165
- - [[url]] is a [[String]] representing the target of the connection in the URL
166
- form, using either the [[ws:]] or [[wss:]] protocol prefix. A convenient
167
- public server for basic testing is available on [[ws://echo.websocket.org/]].
168
-
169
- - [[header_fields]] is a [[Hash]] for specifying HTTP header fields for the
170
- request. [[Webtube]] will consider entries specified here to have a priority
171
- over automatically created header fields even for the fields defined by the
172
- WebSocket standard such as [[Upgrade]] and [[Sec-WebSocket-Key]]; this should
173
- be used cautiously.
174
-
175
- - [[ssl_verify_mode]], if not [[nil]] and if the connection is encrypted, will
176
- override OpenSSL's default mode of verifying the certificate at the beginning
177
- of the SSL or TLS session. Supported values are
178
- [[OpenSSL::SSL::VERIFY_PEER]] (the default, and the recommended value) and
179
- [[OpenSSL::SSL::VERIFY_NONE]] (to be used with great caution). If the [[url]]
180
- parameter has an [[ws:]] prefix, so the connection is not to be encrypted,
181
- [[ssl_verify_mode]] has no effect.
177
+ allow_opcodes: [Webtube::OPCODE_TEXT],
178
+ http_header: {},
179
+ ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER,
180
+ ssl_cert_store: nil,
181
+ tcp_connect_timeout: nil,
182
+ tcp_nodelay: true,
183
+ close_socket: true,
184
+ on_http_request: nil,
185
+ on_http_response: nil,
186
+ on_ssl_handshake: nil,
187
+ on_tcp_connect: nil)
188
+
189
+ Only [[url]] is mandatory, and in most contexts, setting [[url]]
190
+ and [[allow_opcodes]] is enough. [[http_header]] is notable as
191
+ a way to pass HTTP cookies along with the WebSocket connection
192
+ request.
193
+
194
+ - [[url]] is a [[String]] representing the target of the
195
+ connection in the URL form, using either the [[ws:]] or
196
+ [[wss:]] protocol prefix. A convenient public server for
197
+ basic testing is available on [[ws://echo.websocket.org/]].
198
+
199
+ - [[http_header]] is a [[Hash]] for specifying HTTP header
200
+ fields for the request. [[Webtube]] will consider entries
201
+ specified here to have a priority over automatically created
202
+ header fields even for the fields defined by the WebSocket
203
+ standard such as [[Upgrade]] and [[Sec-WebSocket-Key]];
204
+ caution should be exercised when using this feature.
205
+
206
+ - [[ssl_verify_mode]] will specify OpenSSL's mode of verifying
207
+ the certificate at the end of the SSL handshake. Supported
208
+ values are [[OpenSSL::SSL::VERIFY_PEER]] (the default, and the
209
+ recommended value) and [[OpenSSL::SSL::VERIFY_NONE]] (to be
210
+ used with great caution). Not applicable if the connection is
211
+ not encrypted (that is, the [[url]] parameter has a [[ws:]]
212
+ rather than [[wss:]] prefix).
213
+
214
+ - [[ssl_cert_store]], if given, should be a prepared
215
+ [[OpenSSL::X509::Store]] instance containing the trusted root
216
+ certificates. If not given, the system's defaults are used.
217
+ Not applicable if the connection is not encrypted (that is,
218
+ the [[url]] parameter has a [[ws:]] rather than [[wss:]]
219
+ prefix).
220
+
221
+ - [[tcp_connect_timeout]], if given, specifies the number of
222
+ seconds allotted for establishing the TCP connection. The
223
+ [[Net::OpenTimeout]] exception will be raised if the TCP
224
+ handshake can not be completed within the given time.
225
+
226
+ - [[tcp_nodelay]] specifies whether the [[TCP_NODELAY]] socket
227
+ option should be turned on, requesting that the Nagle's
228
+ algorithm not be used. The default is [[true]], which may
229
+ slightly reduce latency at the expense of bulk throughput.
230
+ Turning [[tcp_nodelay]] off will re-enable the Nagle's
231
+ algorithm, which may slightly improve bulk throughput at the
232
+ expense of latency.
233
+
234
+ - [[on_http_request]], if supplied, will be called with the
235
+ HTTP-level request to initiate a WebSocket connection, as a
236
+ [[String]]. This allows the client code, for an example, to
237
+ display the request to the user.
182
238
 
183
239
  - [[on_http_response]], if supplied, will be called with the
184
- [[Net::HTTPResponse]] instance representing the server's HTTP-level response
185
- to the request to initiate a WebSocket connection. This allows the client
186
- code, for an example, to display the response header fields to the user.
187
-
188
- The following fields will be passed on to [[Webtube::new]] intact:
189
-
190
- - [[allow_rsv_bits]] is an [[Integer]], a bitmap of the reserved bits (4 for
191
- RSV1, 2 for RSV2, 1 for RSV3) that, when appearing on inbound frames, should
192
- be considered 'known'. The WebSocket protocol specification mandates failing
193
- the connection if a frame with unknown reserved bits should arrive, and
194
- [[Webtube]] complies. Note that the current version of [[Webtube]] does not
195
- offer a convenient way for the client code to access the reserved bits of data
196
- messages, only of control frames.
197
-
198
- - [[allow_opcodes]] specifies the opcodes of messages and control frames that
199
- should be considered 'known'. The WebSocket protocol specification mandates
200
- failing the connection if a frame with an unknown opcode should arrive, and
201
- [[Webtube]] complies. The [[Webtube]] instance will store this object and use
202
- its [[include?]] method for the test, thus allowing either [[Array]], [[Set]]
203
- or [[Range]] instances to work. The opcodes subject to this kind of filtering
204
- are the data message opcodes 1-7 and the control frame opcodes 8-15; note,
205
- however, that the control frame opcodes 8 ([[OPCODE_CLOSE]]), 9
206
- ([[OPCODE_PING]]), and 10 ([[OPCODE_PONG]]) are essential infrastructural
207
- opcodes defined by the standard, so [[Webtube]] will always consider them
208
- 'known'. However, control frames of these opcodes will be passed to the
209
- [[oncontrolframe]] event handler (if any) only if [[allow_opcodes]] approves
210
- such opcodes.
211
-
212
- - [[close_socket]] specifies whether the [[Webtube]] instance should close the
213
- [[Socket]] when the connection is terminated. The default is [[true]]; it
214
- may need to be set to [[false]] in order to suppress [[Webtube]]'s closure of
215
- its socket in contexts sockets are managed by other means, such as the WEBrick
216
- server.
217
-
218
- Upon success, [[Webtube::connect]] will return the [[Webtube]] instance
219
- representing the client endpoint. Upon WebSocket-level failure with lower
220
- layers intact, a [[Webtube::WebSocketUpgradeFailed]] exception will be thrown
221
- instead. This exception derives from [[StandardError]] as most run-time
222
- errors. In the the current version of [[Webtube]], the specific known
223
- subclasses are:
224
-
225
- - [[Webtube::WebSocketDeclined]] for when the server is not responding to the
226
- WebSocket connection initiation request affirmatively (which can, by design
227
- of the protocol, mean that the server wants to speak plain old HTTP);
228
-
229
- - [[Webtube::WebSocketVersionMismatch]] for when the server requests usage of a
230
- WebSocket protocol version that [[Webtube]] does not know. At the time of
231
- [[Webtube]]'s creation, only one WebSocket protocol version -- namely, 13 --
232
- has been defined (by RFC 6455]), but this may change in the future, and it is
233
- possible that a hypothetical future server will not be backwards compatible to
234
- the original WebSocket protocol.
235
-
236
- Other exceptions representing TCP-level, HTTP-level, or infrastructure failures
237
- can also occur.
240
+ header of the HTTP-level response to the request to initiate a
241
+ WebSocket connection, as a [[String]]. (In version 1.1.0, the
242
+ string is reconstituted from a parsed [[Net::HTTPResponse]],
243
+ and may differ from the actual response in details that
244
+ usually do not matter, such as capitalisation of header
245
+ fields' names. In a future version, the string may be a copy
246
+ of the actual response.) This allows the client code, for an
247
+ example, to display the response header to the user.
248
+
249
+ - [[on_ssl_handshake]], if supplied, will be called with the
250
+ [[OpenSSL::SSL::SSLSocket]] instance upon completion of the
251
+ SSL handshake. Not applicable if the connection is not
252
+ encrypted (that is, the [[url]] parameter has a [[ws:]] rather
253
+ than [[wss:]] prefix).
254
+
255
+ - [[on_tcp_connect]], if supplied, will be called with the
256
+ [[TCPSocket]] instance upon completion of the TCP handshake.
257
+
258
+
259
+ The following fields will be passed on to [[Webtube::new]]
260
+ intact:
261
+
262
+ - [[allow_rsv_bits]] is an [[Integer]], a bitmap of the reserved
263
+ bits (4 for RSV1, 2 for RSV2, 1 for RSV3) that, when appearing
264
+ on inbound frames, should be considered 'known'. The
265
+ WebSocket protocol specification mandates failing the
266
+ connection if a frame with unknown reserved bits should
267
+ arrive, and [[Webtube]] complies. Note that the current
268
+ version of [[Webtube]] does not offer a convenient way for the
269
+ client code to access the reserved bits of data messages, only
270
+ of control frames.
271
+
272
+ - [[allow_opcodes]] specifies the opcodes of messages and
273
+ control frames that should be considered 'known'. The
274
+ WebSocket protocol specification mandates failing the
275
+ connection if a frame with an unknown opcode should arrive,
276
+ and [[Webtube]] complies. The [[Webtube]] instance will store
277
+ this object and use its [[include?]] method for the test, thus
278
+ allowing either [[Array]], [[Set]] or [[Range]] instances to
279
+ work. The opcodes subject to this kind of filtering are the
280
+ data message opcodes 1-7 and the control frame opcodes 8-15;
281
+ note, however, that the control frame opcodes 8
282
+ ([[OPCODE_CLOSE]]), 9 ([[OPCODE_PING]]), and 10
283
+ ([[OPCODE_PONG]]) are essential infrastructural opcodes
284
+ defined by the standard, so [[Webtube]] will always consider
285
+ them 'known'. However, control frames of these opcodes will
286
+ be passed to the [[oncontrolframe]] event handler (if any)
287
+ only if [[allow_opcodes]] approves such opcodes.
288
+
289
+ - [[close_socket]] specifies whether the [[Webtube]] instance
290
+ should close the [[Socket]] when the connection is terminated.
291
+ The default is [[true]]; it may need to be set to [[false]] in
292
+ order to suppress [[Webtube]]'s closure of its socket in
293
+ contexts sockets are managed by other means, such as the
294
+ WEBrick server.
295
+
296
+ Upon success, [[Webtube::connect]] will return the [[Webtube]]
297
+ instance representing the client endpoint. Upon WebSocket-level
298
+ failure with lower layers intact, a
299
+ [[Webtube::WebSocketUpgradeFailed]] exception will be thrown
300
+ instead. This exception derives from [[StandardError]] as most
301
+ run-time errors. In the the current version of [[Webtube]], the
302
+ specific known subclasses are:
303
+
304
+ - [[Webtube::WebSocketDeclined]] for when the server is not
305
+ responding to the WebSocket connection initiation request
306
+ affirmatively (which can, by design of the protocol, mean that
307
+ the server wants to speak plain old HTTP);
308
+
309
+ - [[Webtube::WebSocketVersionMismatch]] for when the server
310
+ requests usage of a WebSocket protocol version that
311
+ [[Webtube]] does not know. At the time of [[Webtube]]'s
312
+ creation, only one WebSocket protocol version -- namely, 13 --
313
+ has been defined (by RFC 6455]), but this may change in the
314
+ future, and it is possible that a hypothetical future server
315
+ will not be backwards compatible to the original WebSocket
316
+ protocol.
317
+
318
+ Other exceptions representing TCP-level, HTTP-level, or
319
+ infrastructure failures can also occur.
238
320
 
239
321
 
240
322
  ==== [[Webtube::new]]: wrap a [[Socket]] into a [[Webtube]]
241
323
 
242
- An instance of [[Webtube]] represents an endpoint of a WebSocket connection.
243
- Because the protocol's core is symmetric, both ends can be represented by
244
- instances of the same class. Note that the constructor assumes the opening
245
- handshake and initial negotiation is complete. Code needing to connect to a
246
- remote WebSocket server should usually call [[Webtube::connect]] instead of
247
- invoking the constructor directly. Code needing to accept incoming WebSocket
248
- connections should usually call the server-specific glue code such as
249
- [[WEBrick::HTTPServer#accept_webtube]] (available after [[require
250
- 'webtube/webrick']]).
324
+ An instance of [[Webtube]] represents an endpoint of a WebSocket
325
+ connection. Because the protocol's core is symmetric, both ends
326
+ can be represented by instances of the same class. Note that
327
+ the constructor assumes the opening handshake and initial
328
+ negotiation is complete. Code needing to connect to a remote
329
+ WebSocket server should usually call [[Webtube::connect]]
330
+ instead of invoking the constructor directly. Code needing to
331
+ accept incoming WebSocket connections should usually call the
332
+ server-specific glue code such as
333
+ [[WEBrick::HTTPServer#accept_webtube]] (available after
334
+ [[require 'webtube/webrick']]).
251
335
 
252
336
  The constructor's calling interface goes like this:
253
337
 
@@ -256,292 +340,335 @@ The constructor's calling interface goes like this:
256
340
  allow_opcodes: [Webtube::OPCODE_TEXT],
257
341
  close_socket: true)
258
342
 
259
- - [[socket]] is the underlying [[Socket]] instance for sending and receiving
260
- data.
261
-
262
- - [[serverp]] is a Boolean indicating whether this socket represents the server
263
- (as contrary to the client) side of the connection. While the WebSocket
264
- protocol is largely symmetric, it requires a special masking procedure on
265
- frames transmitted by the client to the server, and prohibits it on frames
266
- transmitted by the server to the client. Along with masking itself, this is
267
- reflected in a header flag of each frame.
268
-
269
- - [[allow_rsv_bits]] is an [[Integer]], a bitmap of the reserved bits (4 for
270
- RSV1, 2 for RSV2, 1 for RSV3) that, when appearing on inbound frames, should
271
- be considered 'known'. The WebSocket protocol specification mandates failing
272
- the connection if a frame with unknown reserved bits should arrive, and
273
- [[Webtube]] complies. Note that the current version of [[Webtube]] does not
274
- offer a convenient way for the client code to access the reserved bits of data
275
- messages, only of control frames.
276
-
277
- - [[allow_opcodes]] specifies the opcodes of messages and control frames that
278
- should be considered 'known'. The WebSocket protocol specification mandates
279
- failing the connection if a frame with an unknown opcode should arrive, and
280
- [[Webtube]] complies. The [[Webtube]] instance will store this object and use
281
- its [[include?]] method for the test, thus allowing either [[Array]], [[Set]]
282
- or [[Range]] instances to work. The opcodes subject to this kind of filtering
283
- are the data message opcodes 1-7 and the control frame opcodes 8-15; note,
284
- however, that the control frame opcodes 8 ([[OPCODE_CLOSE]]), 9
285
- ([[OPCODE_PING]]), and 10 ([[OPCODE_PONG]]) are essential infrastructural
286
- opcodes defined by the standard, so [[Webtube]] will always consider them
287
- 'known'. However, control frames of these opcodes will be passed to the
288
- [[oncontrolframe]] event handler (if any) only if [[allow_opcodes]] approves
289
- such opcodes.
290
-
291
- - [[close_socket]] specifies whether the [[Webtube]] instance should close the
292
- [[Socket]] when the connection is terminated. The default is [[true]]; it
293
- may need to be set to [[false]] in order to suppress [[Webtube]]'s closure of
294
- its socket in contexts sockets are managed by other means, such as the WEBrick
295
- server.
296
-
297
-
298
- ==== [[Webtube#run]]: the loop for incoming events
299
-
300
- run(listener)
301
-
302
- This method runs a loop to read all the messages and control frames coming in
303
- via this WebSocket, and hands events to the given [[listener]]. The listener
304
- can implement the following methods:
305
-
306
- - [[onopen(webtube)]] will be called as soon as the channel is set up.
307
-
308
- - [[onmessage(webtube, message_body, opcode)]] will be called with each
309
- arriving data message once it has been defragmented. The data will be passed
310
- to it as a [[String]], encoded in [[UTF-8]] for [[OPCODE_TEXT]] messages and
311
- in [[ASCII-8BIT]] for all the other message opcodes.
343
+ - [[socket]] is the underlying [[Socket]] instance for sending
344
+ and receiving data.
312
345
 
313
- - oncontrolframe(webtube, frame) will be called upon receipt of a control frame
314
- whose opcode is listed in the [[allow_opcodes]] parameter of this [[Webtube]]
315
- instance. The frame is repreented by an instance of [[Webtube::Frame]]. Note
316
- that [[Webtube]] handles connection closures ([[OPCODE_CLOSE]]) and ponging
317
- all the pings ([[OPCODE_PING]]) automatically.
318
-
319
- - [[onping(webtube, frame)]] will be called upon receipt of an [[OPCODE_PING]]
320
- frame. [[Webtube]] will take care of ponging all the pings, but the
321
- listener may want to process such an event for statistical information.
322
-
323
- - [[onpong(webtube, frame)]] will be called upon receipt of an [[OPCODE_PONG]]
346
+ - [[serverp]] is a Boolean indicating whether this socket
347
+ represents the server (as contrary to the client) side of the
348
+ connection. While the WebSocket protocol is largely
349
+ symmetric, it requires a special masking procedure on frames
350
+ transmitted by the client to the server, and prohibits it on
351
+ frames transmitted by the server to the client. Along with
352
+ masking itself, this is reflected in a header flag of each
324
353
  frame.
325
354
 
326
- - [[onclose(webtube)]] will be called upon closure of the connection, for any
327
- reason.
328
-
329
- - [[onannoyedclose(webtube, frame)]] will be called upon receipt of an
330
- [[OPCODE_CLOSE]] frame with an explicit status code other than 1000.
331
- This typically indicates that the other side is annoyed, so the listener
332
- may want to log the condition for debugging or further analysis.
333
- Normally, once the handler returns, [[Webtube]] will respond with a close
334
- frame of the same status code and close the connection, but the handler
335
- may call [[Webtube#close]] to request a closure with a different status
336
- code or without one.
337
-
338
- - [[onexception(webtube, exception)]] will be called if an unhandled
339
- [[Exception]] is raised during the [[Webtube]]'s lifecycle, including all of
340
- the listener event handlers. The handler may log the exception but should
341
- return normally so that the [[Webtube]] can issue a proper close frame for
342
- the other end and invoke the [[onclose]] handler, after which the exception
343
- will be raised again so the caller of [[Webtube#run]] will have a chance of
344
- handling the exception.
345
-
346
- Before calling any of the handlers, [[respond_to?]] will be used to check
347
- implementedness.
348
-
349
- If an exception occurs during processing, it may implement a specific
350
- status code to be passed to the other end via the [[OPCODE_CLOSE]] frame by
351
- implementing the [[websocket_close_status_code]] method returning the code
352
- as an integer. The default code, used if the exception does not specify
353
- one, is 1011 'unexpected condition'. An exception may explicitly suppress
354
- sending any code by having [[websocket_close_status_code]] return [[nil]]
355
- instead of an integer.
356
-
357
- Note that [[Webtube#run]] will not return until the connection will have been
358
- closed. If the caller needs to get other work done in the connection's
359
- lifetime, it will need to either handle this work inside calls to the
360
- [[listener]] or set up separate [[Thread]]s for the [[Webtube#run]] and for the
361
- other work.
362
-
363
- [[Webtube#run]] will raise instances of [[Webtube::ProtocolError]] if events
364
- that the WebSocket protocol does not permit should happen. In the current
365
- version of [[Webtube]], the specific known subclasses are:
366
-
367
- - [[Webtube::BrokenFrame]] indicates that a complete frame could not be read
368
- from the underlying TCP connection. The [[partial_frame]] attribute holds as
369
- much data, as a [[String]] of [[ASCII-8BIT]] encoding, as was available.
370
-
371
- - [[Webtube::UnknownReservedBit]] indicates that a frame with an RSV bit not
372
- specifically permitted by the [[allow_rsv_bits]] parameter was received. The
373
- [[frame]] attribute holds the frame as a [[Webtube::Frame]] instance.
374
-
375
- - [[Webtube::UnknownOpcode]] indicates that a frame with an opcode not
376
- specifically permitted by the [[allow_opcodes]] parameter, or by the standard,
377
- was received. The [[frame]] attribute holds the frame as a [[Webtube::Frame]]
378
- instance. Note that if the opcode indicates a data message (as contrary to a
379
- control frame), the [[frame]] will hold only its first fragment, as WebSocket
380
- data messages are subject to fragmentation and the message's opcode is stored
381
- in the first fragment.
382
-
383
- - [[Webtube::UnmaskedFrameToServer]] indicates that a [[Webtube]] running in
384
- server mode received a frame without masking. As per the WebSocket standard,
385
- [[Webtube]] considers this a fatal protocol failure. The [[frame]] attribute
386
- holds the frame as a [[Webtube::Frame]] instance.
387
-
388
- - [[Webtube::MaskedFrameToClient]] indicates that a [[Webtube]] running in
389
- client mode received a frame with masking. As per the WebSocket standard,
390
- [[Webtube]] considers this a fatal protocol failure. The [[frame]] attribute
391
- holds the frame as a [[Webtube::Frame]] instance.
392
-
393
- - [[Webtube::MissingContinuationFrame]] indicates receipt of a new data message
394
- initial frame while the [[Webtube]] was expecting a continuation frame of a
395
- fragmented data message. Note that control frames are permitted to arrive
396
- interleaved with fragments of a data message.
397
-
398
- - [[Webtube::UnexpectedContinuationFrame]] indicates receipt of a data message
399
- continuation frame while the [[Webtube]] was not expecting one. The [[frame]]
400
- attribute holds the frame as a [[Webtube::Frame]] instance.
401
-
402
- - [[Webtube::BadlyEncodedText]] indicates receipt of a text message
403
- ([[OPCODE_TEXT]]) whose content is not a valid UTF-8 string. As per the
404
- WebSocket standard, [[Webtube]] considers this a fatal protocol failure. The
405
- [[data]] attribute holds the payload as a [[String]] instance of the
406
- [[ASCII-8BIT]] encoding.
355
+ - [[allow_rsv_bits]] is an [[Integer]], a bitmap of the reserved
356
+ bits (4 for RSV1, 2 for RSV2, 1 for RSV3) that, when appearing
357
+ on inbound frames, should be considered 'known'. The
358
+ WebSocket protocol specification mandates failing the
359
+ connection if a frame with unknown reserved bits should
360
+ arrive, and [[Webtube]] complies. Note that the current
361
+ version of [[Webtube]] does not offer a convenient way for the
362
+ client code to access the reserved bits of data messages, only
363
+ of control frames.
364
+
365
+ - [[allow_opcodes]] specifies the opcodes of messages and
366
+ control frames that should be considered 'known'. The
367
+ WebSocket protocol specification mandates failing the
368
+ connection if a frame with an unknown opcode should arrive,
369
+ and [[Webtube]] complies. The [[Webtube]] instance will store
370
+ this object and use its [[include?]] method for the test, thus
371
+ allowing either [[Array]], [[Set]] or [[Range]] instances to
372
+ work. The opcodes subject to this kind of filtering are the
373
+ data message opcodes 1-7 and the control frame opcodes 8-15;
374
+ note, however, that the control frame opcodes 8
375
+ ([[OPCODE_CLOSE]]), 9 ([[OPCODE_PING]]), and 10
376
+ ([[OPCODE_PONG]]) are essential infrastructural opcodes
377
+ defined by the standard, so [[Webtube]] will always consider
378
+ them 'known'. However, control frames of these opcodes will
379
+ be passed to the [[oncontrolframe]] event handler (if any)
380
+ only if [[allow_opcodes]] approves such opcodes.
381
+
382
+ - [[close_socket]] specifies whether the [[Webtube]] instance
383
+ should close the [[Socket]] when the connection is terminated.
384
+ The default is [[true]]; it may need to be set to [[false]] in
385
+ order to suppress [[Webtube]]'s closure of its socket in
386
+ contexts sockets are managed by other means, such as the
387
+ WEBrick server.
407
388
 
408
- - [[Webtube::FragmenedControlFrame]] indicates receipt of a control frame whose
409
- [[FIN]] flag is not set.
410
389
 
411
- Other exceptions representing TCP-level, HTTP-level, or infrastructure failures
412
- can also occur.
390
+ ==== [[Webtube#run]]: the loop for incoming events
413
391
 
392
+ run(listener)
414
393
 
415
- ==== [[Webtube#send_message]]: transmit a message or control frame
394
+ This method runs a loop to read all the messages and control
395
+ frames coming in via this WebSocket, and hands events to the
396
+ given [[listener]]. The listener can implement the following
397
+ methods:
398
+
399
+ - [[onopen(webtube)]] will be called as soon as the channel is
400
+ set up.
401
+
402
+ - [[onmessage(webtube, message_body, opcode)]] will be called
403
+ with each arriving data message once it has been defragmented.
404
+ The data will be passed to it as a [[String]], encoded in
405
+ [[UTF-8]] for [[OPCODE_TEXT]] messages and in [[ASCII-8BIT]]
406
+ for all the other message opcodes.
407
+
408
+ - [[oncontrolframe(webtube, frame)]] will be called upon receipt
409
+ of a control frame whose opcode is listed in the
410
+ [[allow_opcodes]] parameter of this [[Webtube]] instance. The
411
+ frame is repreented by an instance of [[Webtube::Frame]].
412
+ Note that [[Webtube]] handles connection closures
413
+ ([[OPCODE_CLOSE]]) and ponging all the pings ([[OPCODE_PING]])
414
+ automatically.
415
+
416
+ - [[onping(webtube, frame)]] will be called upon receipt of an
417
+ [[OPCODE_PING]] frame. [[Webtube]] will take care of ponging
418
+ all the pings, but the listener may want to process such an
419
+ event for statistical information.
420
+
421
+ - [[onpong(webtube, frame)]] will be called upon receipt of an
422
+ [[OPCODE_PONG]] frame.
423
+
424
+ - [[onclose(webtube)]] will be called upon closure of the
425
+ connection, for any reason.
426
+
427
+ - [[onannoyedclose(webtube, frame)]] will be called upon receipt
428
+ of an [[OPCODE_CLOSE]] frame with an explicit status code
429
+ other than 1000. This typically indicates that the other side
430
+ is annoyed, so the listener may want to log the condition for
431
+ debugging or further analysis. Normally, once the handler
432
+ returns, [[Webtube]] will respond with a close frame of the
433
+ same status code and close the connection, but the handler may
434
+ call [[Webtube#close]] to request a closure with a different
435
+ status code or without one.
436
+
437
+ - [[onexception(webtube, exception)]] will be called if an
438
+ unhandled [[Exception]] is raised during the [[Webtube]]'s
439
+ lifecycle, including all of the listener event handlers. The
440
+ handler may log the exception but should return normally so
441
+ that the [[Webtube]] can issue a proper close frame for the
442
+ other end and invoke the [[onclose]] handler, after which the
443
+ exception will be raised again so the caller of
444
+ [[Webtube#run]] will have a chance of handling the exception.
445
+
446
+ Before calling any of the handlers, [[respond_to?]] will be used
447
+ to check implementedness.
448
+
449
+ If an exception occurs during processing, it may implement a
450
+ specific status code to be passed to the other end via the
451
+ [[OPCODE_CLOSE]] frame by implementing the
452
+ [[websocket_close_status_code]] method returning the code as an
453
+ integer. The default code, used if the exception does not
454
+ specify one, is 1011 'unexpected condition'. An exception may
455
+ explicitly suppress sending any code by having
456
+ [[websocket_close_status_code]] return [[nil]] instead of an
457
+ integer.
458
+
459
+ Note that [[Webtube#run]] will not return until the connection
460
+ will have been closed. If the caller needs to get other work
461
+ done in the connection's lifetime, it will need to either handle
462
+ this work inside calls to the [[listener]] or set up separate
463
+ [[Thread]]s for the [[Webtube#run]] and for the other work.
464
+
465
+ [[Webtube#run]] will raise instances of
466
+ [[Webtube::ProtocolError]] if events that the WebSocket protocol
467
+ does not permit should happen. In the current version of
468
+ [[Webtube]], the specific known subclasses are:
469
+
470
+ - [[Webtube::BrokenFrame]] indicates that a complete frame could
471
+ not be read from the underlying TCP connection. The
472
+ [[partial_frame]] attribute holds as much data, as a
473
+ [[String]] of [[ASCII-8BIT]] encoding, as was available.
474
+
475
+ - [[Webtube::UnknownReservedBit]] indicates that a frame with an
476
+ RSV bit not specifically permitted by the [[allow_rsv_bits]]
477
+ parameter was received. The [[frame]] attribute holds the
478
+ frame as a [[Webtube::Frame]] instance.
479
+
480
+ - [[Webtube::UnknownOpcode]] indicates that a frame with an
481
+ opcode not specifically permitted by the [[allow_opcodes]]
482
+ parameter, or by the standard, was received. The [[frame]]
483
+ attribute holds the frame as a [[Webtube::Frame]] instance.
484
+ Note that if the opcode indicates a data message (as contrary
485
+ to a control frame), the [[frame]] will hold only its first
486
+ fragment, as WebSocket data messages are subject to
487
+ fragmentation and the message's opcode is stored in the first
488
+ fragment.
489
+
490
+ - [[Webtube::UnmaskedFrameToServer]] indicates that a
491
+ [[Webtube]] running in server mode received a frame without
492
+ masking. As per the WebSocket standard, [[Webtube]] considers
493
+ this a fatal protocol failure. The [[frame]] attribute holds
494
+ the frame as a [[Webtube::Frame]] instance.
495
+
496
+ - [[Webtube::MaskedFrameToClient]] indicates that a [[Webtube]]
497
+ running in client mode received a frame with masking. As per
498
+ the WebSocket standard, [[Webtube]] considers this a fatal
499
+ protocol failure. The [[frame]] attribute holds the frame as
500
+ a [[Webtube::Frame]] instance.
501
+
502
+ - [[Webtube::MissingContinuationFrame]] indicates receipt of a
503
+ new data message initial frame while the [[Webtube]] was
504
+ expecting a continuation frame of a fragmented data message.
505
+ Note that control frames are permitted to arrive interleaved
506
+ with fragments of a data message.
507
+
508
+ - [[Webtube::UnexpectedContinuationFrame]] indicates receipt of
509
+ a data message continuation frame while the [[Webtube]] was
510
+ not expecting one. The [[frame]] attribute holds the frame as
511
+ a [[Webtube::Frame]] instance.
512
+
513
+ - [[Webtube::BadlyEncodedText]] indicates receipt of a text
514
+ message ([[OPCODE_TEXT]]) whose content is not a valid UTF-8
515
+ string. As per the WebSocket standard, [[Webtube]] considers
516
+ this a fatal protocol failure. The [[data]] attribute holds
517
+ the payload as a [[String]] instance of the [[ASCII-8BIT]]
518
+ encoding.
519
+
520
+ - [[Webtube::FragmentedControlFrame]] indicates receipt of a
521
+ control frame whose [[FIN]] flag is not set.
522
+
523
+ Other exceptions representing TCP-level, HTTP-level, or
524
+ infrastructure failures can also occur.
525
+
526
+
527
+ ==== [[Webtube#send_message]]: send a message or control frame
416
528
 
417
529
  send_message(payload, opcode = Webtube::OPCODE_TEXT)
418
530
 
419
- This method transmits the given [[payload]], a [[String]], over this WebSocket
420
- connection to its other end using the given [[opcode]]. If [[opcode]] is
421
- [[Webtube::OPCODE_TEXT]] and [[payload]] is not encoded in [[UTF-8]], it will
422
- recode the payload to [[UTF-8]] first, as required by the WebSocket standard.
531
+ This method transmits the given [[payload]], a [[String]], over
532
+ this WebSocket connection to its other end using the given
533
+ [[opcode]]. If [[opcode]] is [[Webtube::OPCODE_TEXT]] and
534
+ [[payload]] is not encoded in [[UTF-8]], it will recode the
535
+ payload to [[UTF-8]] first, as required by the WebSocket
536
+ standard.
423
537
 
424
- It is safe to call [[send_message]] from multiple threads concurrently; each
425
- [[Webtube]] uses an internal lock to make sure that two data messages, despite
426
- possible fragmentation, will not be interleaved.
538
+ It is safe to call [[send_message]] from multiple threads
539
+ concurrently; each [[Webtube]] uses an internal lock to make
540
+ sure that two data messages, despite possible fragmentation,
541
+ will not be interleaved.
427
542
 
428
- An exception will be raised if [[send_message]] is called after closure of the
429
- [[Webtube]]. The exception's class and ancestry is currently not defined,
430
- except that it will derive, directly or indirectly, from [[StandardError]]. It
431
- may derive from [[RuntimeError]] but this is not guaranteed.
543
+ An exception will be raised if [[send_message]] is called after
544
+ closure of the [[Webtube]]. The exception's class and ancestry
545
+ is currently not defined, except that it will derive, directly
546
+ or indirectly, from [[StandardError]]. It may derive from
547
+ [[RuntimeError]] but this is not guaranteed.
432
548
 
433
549
 
434
550
  ==== [[Webtube#close]]: close a WebSocket connection
435
551
 
436
552
  close(status_code = 1000, explanation = "")
437
553
 
438
- This method transmits an [[OPCODE_CLOSE]] control frame of the specified
439
- [[status_code]] and [[explanation]], aborts a pending wait to receive frame (if
440
- any), and marks the [[Webtube]] dead, thus blocking further transmissions. If
441
- the [[close_socket]] parameter of the [[Webtube]] is set, it will also close
442
- the underlying socket.
554
+ This method transmits an [[OPCODE_CLOSE]] control frame of the
555
+ specified [[status_code]] and [[explanation]], aborts a pending
556
+ wait to receive frame (if any), and marks the [[Webtube]] dead,
557
+ thus blocking further transmissions. If the [[close_socket]]
558
+ parameter of the [[Webtube]] is set, it will also close the
559
+ underlying socket.
443
560
 
444
- The [[status_code]] can be explicitly set to [[nil]], thus causing the
445
- transmitted close frame to not contain a payload (that is, neither the status
446
- code nor the explanation). The default is 1000, indicating normal closure.
561
+ The [[status_code]] can be explicitly set to [[nil]], thus
562
+ causing the transmitted close frame to not contain a payload
563
+ (that is, neither the status code nor the explanation). The
564
+ default is 1000, indicating normal closure.
447
565
 
448
- If [[explanation]] is not encoded in UTF-8, it will be recoded, as required by
449
- the WebSocket protocol specification.
566
+ If [[explanation]] is not encoded in UTF-8, it will be recoded,
567
+ as required by the WebSocket protocol specification.
450
568
 
451
- Attempting to close a [[Webtube]] that has already been closed will cause an
452
- exception as attempting to transmit via a closed [[Webtube]]; see
453
- [[Webtube#send_message]].
569
+ Attempting to close a [[Webtube]] that has already been closed
570
+ will cause an exception as attempting to transmit via a closed
571
+ [[Webtube]]; see [[Webtube#send_message]].
454
572
 
455
573
 
456
574
  === The [[Webtube::Frame]] class
457
575
 
458
- Instances of this class represent individual WebSocket frames. They are
459
- exposed to user code via the [[oncontrolframe]], [[onping]], and [[onpong]]
460
- events and some exceptions inheriting from [[ProtocolError]].
576
+ Instances of this class represent individual WebSocket frames.
577
+ They are exposed to user code via the [[oncontrolframe]],
578
+ [[onping]], and [[onpong]] events and some exceptions inheriting
579
+ from [[ProtocolError]].
461
580
 
462
- There is currently no convenient interface for user code to build
463
- [[Webtube::Frame]] instances by hand, but manipulating some header fields may
464
- function as expected. (Manipulating the payload will usually not, due to this
465
- interfering with the length- and masking-related header fields.)
581
+ There is currently no convenient interface for user code to
582
+ build [[Webtube::Frame]] instances by hand, but manipulating
583
+ some header fields may function as expected. (Manipulating the
584
+ payload will usually not, due to this interfering with the
585
+ length- and masking-related header fields.)
466
586
 
467
587
  The following methods are user-serviceable:
468
588
 
469
- - [[Webtube::Frame#header]] returns the header as a [[String]] encoded in
470
- [[ASCII-8BIT]].
589
+ - [[Webtube::Frame#header]] returns the header as a [[String]]
590
+ encoded in [[ASCII-8BIT]].
471
591
 
472
- - [[Webtube::Frame#header=]] replaces the header. There is no validation; use
473
- with caution.
592
+ - [[Webtube::Frame#header=]] replaces the header. There is no
593
+ validation; use with caution.
474
594
 
475
- - [[Webtube::Frame#body]] returns the body as a [[String]] encoded in
476
- [[ASCII-8BIT]].
595
+ - [[Webtube::Frame#body]] returns the body as a [[String]]
596
+ encoded in [[ASCII-8BIT]].
477
597
 
478
- - [[Webtube::Frame#body=]] replaces the body. There is no validation or
479
- masking; use with extreme caution.
598
+ - [[Webtube::Frame#body=]] replaces the body. There is no
599
+ validation or masking; use with extreme caution.
480
600
 
481
- - [[Webtube::Frame#fin?]] extracts and returns (as [[Boolean]]) the [[FIN]]
482
- flag of this frame.
601
+ - [[Webtube::Frame#fin?]] extracts and returns (as [[Boolean]])
602
+ the [[FIN]] flag of this frame.
483
603
 
484
- - [[Webtube::Frame#fin=]] replaces the [[FIN]] flag of this frame.
604
+ - [[Webtube::Frame#fin=]] replaces the [[FIN]] flag of this
605
+ frame.
485
606
 
486
- - [[Webtube::Frame#rsv1]], [[Webtube::Frame#rsv2]], and [[Webtube::Frame#rsv3]]
487
- extract the RSV1, RSV2, and RSV3 flags of this frame, as [[Boolean]]
488
- instances, correspondingly.
607
+ - [[Webtube::Frame#rsv1]], [[Webtube::Frame#rsv2]], and
608
+ [[Webtube::Frame#rsv3]] extract the RSV1, RSV2, and RSV3 flags
609
+ of this frame, as [[Boolean]] instances, correspondingly.
489
610
 
490
- - [[Webtube::Frame#rsv]] extracts the RSV1, RSV2, and RSV3 bitfield as an
491
- integer in the range of [[0 .. 7]].
611
+ - [[Webtube::Frame#rsv]] extracts the RSV1, RSV2, and RSV3
612
+ bitfield as an integer in the range of [[0 .. 7]].
492
613
 
493
- - [[Webtube::Frame#opcode]] extracts the opcode of this frame as an integer in
494
- the range of [[0 .. 15]].
614
+ - [[Webtube::Frame#opcode]] extracts the opcode of this frame as
615
+ an integer in the range of [[0 .. 15]].
495
616
 
496
617
  - [[Webtube::Frame#opcode=]] replaces the opcode.
497
618
 
498
- - [[Webtube::Frame#control_frame?]] checks whether this frame is considered a
499
- control frame, defined as having an opcode of 8 or greater.
619
+ - [[Webtube::Frame#control_frame?]] checks whether this frame is
620
+ considered a control frame, defined as having an opcode of 8
621
+ or greater.
500
622
 
501
- - [[Webtube::Frame#masked?]] extracts the [[MSK]] flag of this frame.
623
+ - [[Webtube::Frame#masked?]] extracts the [[MSK]] flag of this
624
+ frame.
502
625
 
503
- - [[Webtube::Frame#payload_length]] extracts the payload length, in whichever
504
- of the three ways defined by the protocol specification it is encoded, from
505
- the frame's header.
626
+ - [[Webtube::Frame#payload_length]] extracts the payload length,
627
+ in whichever of the three ways defined by the protocol
628
+ specification it is encoded, from the frame's header.
506
629
 
507
- - [[Webtube::Frame#mask]] extracts the mask of this frame, as a 4-byte
508
- [[String]] encoded in [[ASCII-8BIT]], if the [[MSK]] flag is not set. If it
509
- is not set, this method returns [[nil]].
630
+ - [[Webtube::Frame#mask]] extracts the mask of this frame, as an
631
+ integer, if the [[MSK]] flag is set. If it is not set, this
632
+ method returns [[nil]].
510
633
 
511
- - [[Webtube::Frame#payload]] retrieves the payload of this frame, demasking the
512
- frame's body if necessary.
634
+ - [[Webtube::Frame#payload]] retrieves the payload of this
635
+ frame, demasking the frame's body if necessary.
513
636
 
514
- - [[Webtube::Frame::read_from_socket(socket)]] reads all the bytes of one
515
- WebSocket frame from the given [[IO]] instance (which must provide data of
516
- the plain [[ASCII-8BIT]] encoding, and emphatically not a multibyte encoding)
517
- and returns a [[Webtube::Frame]] instance representing the frame, or raises
518
- [[Webtube::BrokenFrame]] if the inbound traffic ends before the whole frame
519
- will have been read. Note that this will involve calling [[IO#read]] twice
520
- or thrice, and is therefore unsafe to be called in multithreaded code unless
521
- external locking or synchronisation measures are used. (This method is
522
- mainly intended for internal use by [[Webtube#run]], but it may be of use in
523
- other contexts, such as parsing stored sequences of WebSocket frames.)
637
+ - [[Webtube::Frame::read_from_socket(socket)]] reads all the
638
+ bytes of one WebSocket frame from the given [[IO]] instance
639
+ (which must provide data in the plain [[ASCII-8BIT]] encoding,
640
+ and emphatically not a multibyte encoding) and returns a
641
+ [[Webtube::Frame]] instance representing the frame, or raises
642
+ [[Webtube::BrokenFrame]] if the inbound traffic ends before
643
+ the whole frame will have been read. Note that this will
644
+ involve calling [[IO#read]] twice or thrice, and is therefore
645
+ unsafe to be called in multithreaded code unless external
646
+ locking or synchronisation measures are used. (This method is
647
+ mainly intended for internal use by [[Webtube#run]], but it
648
+ may be of use in other contexts, such as parsing stored
649
+ sequences of WebSocket frames.)
524
650
 
525
651
 
526
652
  === WEBrick integration
527
653
 
528
654
  These classes and methods are defined in the separately loadable
529
- [['webtube/webrick']]. Note that this file will, in addition to defining new
530
- classes and methods, replace the [[initialize]] and [[shutdown]] methods of the
531
- [[WEBrick::HTTPServer]] class to make sure all the [[Webtube]] instances
532
- associated with this server will be properly shut down upon the server's
533
- shutdown.
655
+ [['webtube/webrick']]. Note that this file will, in addition to
656
+ defining new classes and methods, replace the [[initialize]] and
657
+ [[shutdown]] methods of the [[WEBrick::HTTPServer]] class to
658
+ make sure all the [[Webtube]] instances associated with this
659
+ server will be properly shut down upon the server's shutdown.
534
660
 
535
661
 
536
662
  ==== [[WEBrick::HTTPRequest#websocket_upgrade_request?]]
537
663
 
538
- This method checks whether this HTTP request is a valid request to establish a
539
- WebSocket connection.
664
+ This method checks whether this HTTP request is a valid request
665
+ to establish a WebSocket connection.
540
666
 
541
667
 
542
668
  ==== [[WEBrick::HTTPServer#webtubes]]
543
669
 
544
- Retrieve the [[Webtube::Vital_Statistics]] instance for this server.
670
+ Retrieve the [[Webtube::Vital_Statistics]] instance for this
671
+ server.
545
672
 
546
673
  ==== [[WEBrick::HTTPServer#accept_webtube]]
547
674
 
@@ -550,230 +677,258 @@ Retrieve the [[Webtube::Vital_Statistics]] instance for this server.
550
677
  context: nil)
551
678
 
552
679
  Given a [[request]] and a [[response]] object, as prepared by a
553
- [[WEBrick::HTTPServer]] for processing in a portlet, this method attempts to
554
- accept the client's request to establish a WebSocket connection. The
555
- [[request]] must actually contain such a request; see
556
- [[websocket_upgrade_request?]].
557
-
558
- The attempt will fail in the theoretical case the client and the server can't
559
- agree on the protocol version to use. In such a case, [[accept_webtube]] will
560
- prepare a 426 'Upgrade required' response, explaining in plain text what the
561
- problem is and advertising, using the [[Sec-WebSocket-Version]] header field,
562
- the protocol version (specifically, 13) it is prepared to speak. When this
563
- happens, the WebSocket session will never be set up and no [[listener]] events
564
- will be called.
565
-
566
- Note that [[accept_webtube]] will manipulate [[response]] and return
567
- immediately. The actual WebSocket session will begin once WEBrick attempts to
568
- deliver the [[response]], and this will be signalled by the newly constructed
569
- [[Webtube]] instance delivering an [[onopen]] event to [[listener]].
570
-
571
- Also note that the loop to process incoming WebSocket frames will hog the
572
- whole thread; in order to deliver asynchronous messages over the
573
- WebSocket, [[Webtube#send_message]] needs to be called from another
574
- thread. (For synchronous messages, it can safely be called from the
575
- handlers inside [[listener]].)
680
+ [[WEBrick::HTTPServer]] for processing in a portlet, this method
681
+ attempts to accept the client's request to establish a WebSocket
682
+ connection. The [[request]] must actually contain such a
683
+ request; see [[websocket_upgrade_request?]].
684
+
685
+ The attempt will fail in the theoretical case the client and the
686
+ server can't agree on the protocol version to use. In such a
687
+ case, [[accept_webtube]] will prepare a 426 'Upgrade required'
688
+ response, explaining in plain text what the problem is and
689
+ advertising, using the [[Sec-WebSocket-Version]] header field,
690
+ the protocol version (specifically, 13) it is prepared to speak.
691
+ When this happens, the WebSocket session will never be set up
692
+ and no [[listener]] events will be called.
693
+
694
+ Note that [[accept_webtube]] will manipulate [[response]] and
695
+ return immediately. The actual WebSocket session will begin
696
+ once WEBrick attempts to deliver the [[response]], and this will
697
+ be signalled by the newly constructed [[Webtube]] instance
698
+ delivering an [[onopen]] event to [[listener]].
699
+
700
+ Also note that the loop to process incoming WebSocket frames
701
+ will hog the whole thread; in order to deliver asynchronous
702
+ messages over the WebSocket, [[Webtube#send_message]] needs to
703
+ be called from another thread. (For synchronous messages, it
704
+ can safely be called from the handlers inside [[listener]].)
576
705
 
577
706
  See [[Webtube#run]] for a list of the supported methods for the
578
707
  [[listener]].
579
708
 
580
- The [[session]] and [[context]] parameters, if given, will be stored in the
581
- [[Webtube]] instance as attributes. The [[Webtube]] itself will not care about
582
- them, but this mechanism may be of use for the user code. [[accept_webtube]]
583
- stores the [[request]] in the [[Webtube]] instance's [[header]] attribute; for
584
- this reason, it does not accept [[header]] as a parameter.
709
+ The [[session]] and [[context]] parameters, if given, will be
710
+ stored in the [[Webtube]] instance as attributes. The
711
+ [[Webtube]] itself will not care about them, but this mechanism
712
+ may be of use for the user code. [[accept_webtube]] stores the
713
+ [[request]] in the [[Webtube]] instance's [[header]] attribute;
714
+ for this reason, it does not accept [[header]] as a parameter.
585
715
 
586
716
  ==== [[WEBrick::HTTPServer#mount_webtube]]
587
717
 
588
718
  mount_webtube(dir, listener)
589
719
 
590
- This method mounts at the specified virtual directory a WEBrick portlet
591
- implementing a WebSocket-only service, using the given [[listener]] as its
592
- backend. (Note that there is only one listener for the whole service but each
593
- event passed to the listener will have a specific [[Webtube]] instance as its
594
- first parameter.)
720
+ This method mounts at the specified virtual directory a WEBrick
721
+ portlet implementing a WebSocket-only service, using the given
722
+ [[listener]] as its backend. (Note that there is only one
723
+ listener for the whole service but each event passed to the
724
+ listener will have a specific [[Webtube]] instance as its first
725
+ parameter.)
595
726
 
596
727
  The portlet itself is implemented by the class
597
- [[WEBrick::HTTPServlet::WebtubeHandler]]. The implementation details are
598
- deliberately left undocumented in the current version of [[Webtube]], and they
599
- may change radically in the future. For now, the class should be considered
600
- opaque.
728
+ [[WEBrick::HTTPServlet::WebtubeHandler]]. The implementation
729
+ details are deliberately left undocumented in the current
730
+ version of [[Webtube]], and they may change radically in the
731
+ future. For now, the class should be considered opaque.
601
732
 
602
733
 
603
734
  == Limitations and possible future work
604
735
 
605
- - The WebSocket specification permits interleaving control frames with
606
- fragments of a data message. The current [[Webtube]] implementation engages
607
- an internal lock serialising all calls of [[send_message]]. A future version
608
- may ignore this lock if [[send_message]] is called to transmit a control frame
609
- that fits into the [[PIPE_BUF]] limit and is thus not subject to the risk of
610
- the OS kernel's [[write()]] syscall handling it partially and causing a
611
- WebSocket frame structure breakage.
612
-
613
- - Such ignoring may, in a future version, be configurable on a per-opcode
614
- basis.
615
-
616
- - The WebSocket specification provides for handling the content of fragmented
617
- data messages even before the reception of the final frame. The current
618
- [[Webtube]] implementation sponges up all the fragments before triggering
619
- [[onmessage]].
620
-
621
- - Some approaches worth considering involve delivering fragments of data
622
- messages to the listener as they arrive or extracting parts -- such as text
623
- lines, sequences of complete UTF-8 code points, or fixed-length data blocks
624
- -- from the fragment sponge as soon as they can be wholly extracted.
625
-
626
- - The WebSocket specification provides for extensions defining semantics for
627
- the reserved bits of both data and control frames, and for extra header fields
628
- between the WebSocket header and the ultimate payload. [[Webtube]] only
629
- provides for handling reserved bits of incoming control frames but not data
630
- frames, and does not provide for a convenient way to transmit frames with
631
- reserved bits or extra header fields set.
632
-
633
- - In particular, work is currently underway to define a WebSocket protocol
634
- extension for transparent compression of frames and/or messages. At this
635
- time, there are multiple competing proposals, and IETF has not released a
636
- final specification, but a future version of [[Webtube]] may implement one
637
- or more such extension. The most promising one, at this time, seems
638
- [[permessage-deflate]].
639
-
640
- - The WebSocket specification provides for explicit negotiation of a
641
- subprotocol between the client and the server. While [[Webtube]] exposes the
642
- relevant HTTP header field ([[Sec-WebSocket-Protocol]]) to client-side user
643
- code, it does not provide any sort of direct support, and explicitly
644
- supporting subprotocols on the server side may be cumbersome. A future
645
- version of [[Webtube]] may provide a declarative way for configuring the
646
- subprotocol negotiation: more explicitly expose the subprotocol field on the
647
- client-side API, and providing parameters for declaring the supported
648
- subprotocols and their order of precedence, or alternatively a hook to a more
649
- complex subprotocol choie mechanism, on the server-side API.
650
-
651
- - On the server side, [[Webtube]] currently only actively integrates with
652
- WEBrick. A future version may also provide support for integration with
653
- Puma, Sinatra, and/or EventMachine.
654
-
655
- - A future version of [[Webtube]] may provide an interface for explicitly
656
- specifying the fragmentation strategy for outbound data messages instead of
657
- relying on a one-size-fits-all [[PIPE_BUF]] bases approach.
658
-
659
- - In particular, on systems exposing the results of Path MTU Discovery of
660
- connected TCP sockets to userspace code, a future version of [[Webtube]]
661
- may use these results to choose a message fragment size according to the
662
- path's MTU. (This will become nontrivial once compression and SSL get
736
+ - The WebSocket specification permits interleaving control
737
+ frames with fragments of a data message. The current
738
+ [[Webtube]] implementation engages an internal lock
739
+ serialising all calls of [[send_message]]. A future version
740
+ may ignore this lock if [[send_message]] is called to transmit
741
+ a control frame that fits into the [[PIPE_BUF]] limit and is
742
+ thus not subject to the risk of the OS kernel's [[write()]]
743
+ syscall handling it partially and causing a WebSocket frame
744
+ structure breakage.
745
+
746
+ - Such ignoring may, in a future version, be configurable on a
747
+ per-opcode basis.
748
+
749
+ - The WebSocket specification provides for handling the content
750
+ of fragmented data messages even before the reception of the
751
+ final frame. The current [[Webtube]] implementation sponges
752
+ up all the fragments before triggering [[onmessage]].
753
+
754
+ - Some approaches worth considering involve delivering
755
+ fragments of data messages to the listener as they arrive or
756
+ extracting parts -- such as text lines, sequences of
757
+ complete UTF-8 code points, or fixed-length data blocks --
758
+ from the fragment sponge as soon as they can be wholly
759
+ extracted.
760
+
761
+ - The WebSocket specification provides for extensions defining
762
+ semantics for the reserved bits of both data and control
763
+ frames, and for extra header fields between the WebSocket
764
+ header and the ultimate payload. [[Webtube]] only provides
765
+ for handling reserved bits of incoming control frames but not
766
+ data frames, and does not provide for a convenient way to
767
+ transmit frames with reserved bits or extra header fields set.
768
+
769
+ - In particular, work is currently underway to define a
770
+ WebSocket protocol extension for transparent compression of
771
+ frames and/or messages. At this time, there are multiple
772
+ competing proposals, and IETF has not released a final
773
+ specification, but a future version of [[Webtube]] may
774
+ implement one or more such extension. The most promising
775
+ one, at this time, seems [[permessage-deflate]].
776
+
777
+ - The WebSocket specification provides for explicit negotiation
778
+ of a subprotocol between the client and the server. While
779
+ [[Webtube]] exposes the relevant HTTP header field
780
+ ([[Sec-WebSocket-Protocol]]) to client-side user code, it does
781
+ not provide any sort of direct support, and explicitly
782
+ supporting subprotocols on the server side may be cumbersome.
783
+ A future version of [[Webtube]] may provide a declarative way
784
+ for configuring the subprotocol negotiation: more explicitly
785
+ expose the subprotocol field on the client-side API, and
786
+ providing parameters for declaring the supported subprotocols
787
+ and their order of precedence, or alternatively a hook to a
788
+ more complex subprotocol choie mechanism, on the server-side
789
+ API.
790
+
791
+ - On the server side, [[Webtube]] currently only actively
792
+ integrates with WEBrick. A future version may also provide
793
+ support for integration with Thin, Puma, Sinatra, and/or
794
+ EventMachine.
795
+
796
+ - A future version of [[Webtube]] may provide an interface for
797
+ explicitly specifying the fragmentation strategy for outbound
798
+ data messages instead of relying on a one-size-fits-all
799
+ [[PIPE_BUF]] based approach.
800
+
801
+ - In particular, on systems exposing the results of Path MTU
802
+ Discovery of connected TCP sockets to userspace code, a
803
+ future version of [[Webtube]] may use these results to
804
+ choose a message fragment size according to the path's MTU.
805
+ (This will become nontrivial once compression and SSL get
663
806
  involved.)
664
807
 
665
- - Currently, [[Webtube#run]] necessarily hogs its whole thread until the
666
- connection closes. A future version may, as an alternative, provide a more
667
- incremental approach. Some of the partially overlapping and partially
668
- alternative approaches worth considering include:
669
-
670
- - a [[receive_message]] method that would hang until a message arrives (buth
671
- how would it interact with control frames? Particularly, control frames
672
- not defined by the standard?);
673
-
674
- - an option for [[run]] to leave the loop after processing one incoming frame
675
- or message;
676
-
677
- - an option for [[run]] to leave the loop after passage of a given timeout;
678
-
679
- - a non-blocking [[has_data?]] method that would check whether the underlying
680
- [[Socket]] has at last one byte of data available;
681
-
682
- - a non-blocking [[has_frame?]] method that would check whether the
683
- underlying [[Socket]] has at least on complete WebSocket frame available
684
- (if not, this would require storing the partial frame in a slot of
685
- [[Webtube]] instead of a local variable of [[run]]).
686
-
687
- - The HTTP specification provides a mechanism for redirecting clients. It is
688
- not entirely clear how this should affect WebSocket clients, although there
689
- are some obvious approaches. A future version of [[Webtube::connect]] may
690
- implement one or more of them.
691
-
692
- - A future version of the client API for [[Webtube]] may support transparent
693
- automatic reconnection upon loss of connection while retaining the same
694
- instance, subject to restrictions for thrashing and persisting failure. This
695
- may need lead to defining new events for the listener.
696
-
697
- - A future version of [[Webtube]] may provide for a higher-level interface, for
698
- example, by transparently JSON-encoding and -decoding objects as they are
699
- transmitted and received.
700
-
701
- - A future version of [[Webtube]] may implement a 'queue of unhandled messages'
702
- inside the [[Webtube]] instance (or more likely, inside an instance of its
703
- subclass), define a mechanism (or several) for matching outbound and inbound
704
- messages, and provide for a synchronous method that would transmit a message
705
- and wait until receipt of a matching response, storing messages arriving in
706
- the intervening time for use by a future call of this method, or by
707
- concurrent calls of this method from other threads.
708
-
709
- - A future version of [[Webtube]] may define a hook for the caller to manually
710
- check the SSL certificate so as to facilitate secure SSL/TLS connections
711
- using self-signed certificates validated using a custom procedure instead of
808
+ - Currently, [[Webtube#run]] necessarily hogs its whole thread
809
+ until the connection closes. A future version may, as an
810
+ alternative, provide a more incremental approach. Some of the
811
+ partially overlapping and partially alternative approaches
812
+ worth considering include:
813
+
814
+ - a [[receive_message]] method that would hang until a message
815
+ arrives (buth how would it interact with control frames?
816
+ Particularly, control frames not defined by the standard?);
817
+
818
+ - an option for [[run]] to leave the loop after processing one
819
+ incoming frame or message;
820
+
821
+ - an option for [[run]] to leave the loop after passage of a
822
+ given timeout;
823
+
824
+ - a non-blocking [[has_data?]] method that would check whether
825
+ the underlying [[Socket]] has at last one byte of data
826
+ available;
827
+
828
+ - a non-blocking [[has_frame?]] method that would check
829
+ whether the underlying [[Socket]] has at least on complete
830
+ WebSocket frame available (if not, this would require
831
+ storing the partial frame in a slot of [[Webtube]] instead
832
+ of a local variable of [[run]]).
833
+
834
+ - The HTTP specification provides a mechanism for redirecting
835
+ clients. It is not entirely clear how this should affect
836
+ WebSocket clients, although there are some obvious approaches.
837
+ A future version of [[Webtube::connect]] may implement one or
838
+ more of them.
839
+
840
+ - A future version of the client API for [[Webtube]] may support
841
+ transparent automatic reconnection upon loss of connection
842
+ while retaining the same instance, subject to restrictions for
843
+ thrashing and persisting failure. This may need lead to
844
+ defining new events for the listener.
845
+
846
+ - A future version of [[Webtube]] may provide for a higher-level
847
+ interface, for example, by transparently JSON-encoding and
848
+ -decoding objects as they are transmitted and received.
849
+
850
+ - A future version of [[Webtube]] may implement a 'queue of
851
+ unhandled messages' inside the [[Webtube]] instance (or more
852
+ likely, inside an instance of its subclass), define a
853
+ mechanism (or several) for matching outbound and inbound
854
+ messages, and provide for a synchronous method that would
855
+ transmit a message and wait until receipt of a matching
856
+ response, storing messages arriving in the intervening time
857
+ for use by a future call of this method, or by concurrent
858
+ calls of this method from other threads.
859
+
860
+ - A future version of [[Webtube]] may define a hook for the
861
+ caller to manually check the SSL certificate so as to
862
+ facilitate secure SSL/TLS connections using self-signed
863
+ certificates validated using a custom procedure instead of
712
864
  relying to a 'trusted third party' CA.
713
865
 
714
- - Also, or alternatively, it may expose [[OpenSSL]]'s certificate
715
- verification hooks.
716
-
717
- - A future version of [[Webtube::connect]] may explicitly support using a
718
- client SSL certificate.
866
+ - Also, or alternatively, it may expose [[OpenSSL]]'s
867
+ certificate verification hooks.
719
868
 
720
- - A future version of [[Webtube::connect]] may expose the proxy configuration
721
- subsystem of [[Net::HTTP]].
869
+ - A future version of [[Webtube::connect]] may explicitly
870
+ support using a client SSL certificate.
722
871
 
723
- - The current implementation of [[Webtube#send_message]] uses a string (and
724
- thus, implicitly, [[RuntimeError]]), rather than an explicit subclass of
725
- [[Exception]], to report attempt to transmit data through a dead WebSocket.
726
- A future version of [[Webtube]] is likely to provide such an explicit
727
- subclass of defined ancestry. It is not currently clear whether this should
728
- inherit from [[Webtube::ProtocolError]]; arguments both ways are conceivable.
872
+ - A future version of [[Webtube::connect]] may provide support
873
+ for web proxies.
729
874
 
730
- - A future version of [[Webtube]] may offer a better differentiation between
731
- reasons of a WebSocket's closure.
875
+ - The current implementation of [[Webtube#send_message]] uses a
876
+ string (and thus, implicitly, [[RuntimeError]]), rather than
877
+ an explicit subclass of [[Exception]], to report attempt to
878
+ transmit data through a dead WebSocket. A future version of
879
+ [[Webtube]] is likely to provide such an explicit subclass of
880
+ defined ancestry. It is not currently clear whether this
881
+ should inherit from [[Webtube::ProtocolError]]; arguments both
882
+ ways are conceivable.
732
883
 
733
- - A future version of [[Webtube]] may perhaps define listener event(s) for
734
- outbound messages as well as inbound ones.
884
+ - A future version of [[Webtube]] may offer a better
885
+ differentiation between reasons of a WebSocket's closure.
735
886
 
736
- - A future version of [[Webtube]] may define parameters for setting the
737
- [[IP_TOS]] and [[IP_TTL]] socket options.
887
+ - A future version of [[Webtube]] may perhaps define listener
888
+ event(s) for outbound messages as well as inbound ones.
738
889
 
739
- - The WebSocket protocol specification has a strict rule against multiple
740
- WebSocket connections between the same pair of endpoints being simultaneously
741
- in the /connecting/ state. [[Webtube]] is currently not implementing or
742
- enforcing this. A future version may provide a serialisation mechanism.
890
+ - A future version of [[Webtube]] may define parameters for
891
+ setting the [[IP_TOS]] and [[IP_TTL]] socket options.
743
892
 
744
- - A future version of [[Webtube]] may provide an explicit mechanism for
745
- transmitting hand-crafted [[Frame]] instances.
893
+ - The WebSocket protocol specification has a strict rule against
894
+ multiple WebSocket connections between the same pair of
895
+ endpoints being simultaneously in the /connecting/ state.
896
+ [[Webtube]] is currently not implementing or enforcing this.
897
+ A future version may provide a serialisation mechanism.
746
898
 
747
- - This will probably need a better abstraction for frame masking.
899
+ - A future version of [[Webtube]] may provide an explicit
900
+ mechanism for transmitting hand-crafted [[Frame]] instances.
748
901
 
749
- - A future version of [[Webtube]] may provide a standalone WebSocket server
750
- implementing only the minimal needed amount of HTTP/1.1.
751
-
752
- - This will need a mechanism for [[Webtube]] to validate the [[Origin]]
753
- header field in the request. This is currently not implemented (but may be
754
- implemented in a future version.)
902
+ - This will probably need a better abstraction for frame
903
+ masking.
755
904
 
756
905
 
757
906
  == Copyright and licensing
758
907
 
759
- Webtube is copyright (c) 2014 by Andres Soolo and Knitten Development OÜ.
760
- Webtube is published as free software under the terms and conditions of the
761
- GNU General Public License version 3.
762
-
763
- It is the default policy of us at Knitten Development to release our free
764
- software under the GPL v3, which we believe provides a reasonable and
765
- well-considered, if somewhat conservative, balance between the interests and
766
- concerns of producers, consumers, and prosumers of free software. However, we
767
- realise that some users of our free software may be better served by other
768
- balances. For this reason, Knitten Development would like it be known that:
769
-
770
- - we are willing to consider, on a case-by-case basis, offering packages of our
771
- free software optionally also under certain other open source software
772
- licenses, as certified by the Open Source Initiative(tm), provided that this
773
- furthers the creation or advancement of specific free software projects that
774
- Knitten Development may find worthwile, at our discretion; and
775
-
776
- - we are available to negotiate standard non-exclusive commercial licenses for
777
- free software that we have released, in exchange for a reasonable fee.
778
-
779
- For any enquiries, please write to <licensing@knitten-dev.co.uk>.
908
+ Webtube is copyright (c) 2014-2018 by Andres Soolo and Knitten
909
+ Development OÜ. Webtube is published as free software under the
910
+ terms and conditions of the GNU General Public License version
911
+ 3.
912
+
913
+ It is the default policy of us at Knitten Development to release
914
+ our free software under the GPL v3, which we believe provides a
915
+ reasonable and well-considered, if somewhat conservative,
916
+ balance between the interests and concerns of producers,
917
+ consumers, and prosumers of free software. However, we realise
918
+ that some users of our free software may be better served by
919
+ other balances. For this reason, Knitten Development would like
920
+ it be known that:
921
+
922
+ - we are willing to consider, on a case-by-case basis, offering
923
+ packages of our free software optionally also under certain
924
+ other open source software licenses, as certified by the Open
925
+ Source Initiative(tm), provided that this furthers the
926
+ creation or advancement of specific free software projects
927
+ that Knitten Development may find worthwile, at our
928
+ discretion; and
929
+
930
+ - we are available to negotiate standard non-exclusive
931
+ commercial licenses for free software that we have released,
932
+ in exchange for a reasonable fee.
933
+
934
+ For any enquiries, please write to <dig@mirky.net>.