webtube 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>.