faye-websocket 0.10.6 → 0.11.1

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
- SHA1:
3
- metadata.gz: 5b6bf17084f08c82f3d0d7ac138e98ddd2a0f059
4
- data.tar.gz: 8b86e6161c6c6822f46675a8ac7644ad64257be8
2
+ SHA256:
3
+ metadata.gz: 5d911cb9311b3ebcba587cea651bc49cf4ba29db10ef7b3c0b9bb7440571e39e
4
+ data.tar.gz: 81a0a87fd328f88730e84033ad795b28d969d12dfd7bcdd6c5f93e12b865bf44
5
5
  SHA512:
6
- metadata.gz: 41099891f06201e60913915da0bec5f3420b2ebaf955a80d5c17cf7d3cab53feac35e0a7376ad301880eb5245f9e7412304c4a448abdbb4a942c535d46c780a8
7
- data.tar.gz: 66350cd838a0a77e20285130c28bcbe2a197d7179c729866ec5d38d78c8635c212c57670ca2496e0d292f1279825d21624b4a341a1e64df7a8fa83f1d6ab8f60
6
+ metadata.gz: 7c4bc1540dcb37c6c7ed508ae0d459878fef3b66009acd26555ee63b3a7013ba262cffb6fe82120385a002e12847e5c3c33ec3c44cb7ba1e7be7e7f730b1ab05
7
+ data.tar.gz: 953bdb31da0463fbda511ca4b1276ce88a5e2e9273d52c34e4b13eb018d4dec41c1dbd678c8ebcad700a4230e26dc9576d89753fbebd743e743e1bdb48da394c
data/CHANGELOG.md CHANGED
@@ -1,157 +1,189 @@
1
+ ### 0.11.1 / 2021-05-24
2
+
3
+ - Prevent the client hanging if `close()` is called when already closing
4
+
5
+ ### 0.11.0 / 2020-07-31
6
+
7
+ - Implement TLS certificate verification and enable it by default on client
8
+ connections
9
+ - Add a `:tls` option to the client with sub-fields `:root_cert_file` and
10
+ `:verify_peer` for configuring TLS verification
11
+
12
+ ### 0.10.9 / 2019-06-13
13
+
14
+ - Use the EventMachine API rather than `IO#write` to write data; this uses the
15
+ event loop and avoids getting blocked by slow clients
16
+
17
+ ### 0.10.8 / 2019-06-10
18
+
19
+ - In the case of a close timeout, don't block on waiting for writing to the
20
+ socket to complete
21
+ - Fix a race condition that caused a timeout not to be cancelled immediately
22
+ when the WebSocket is closed
23
+ - Change license from MIT to Apache 2.0
24
+
25
+ ### 0.10.7 / 2017-02-22
26
+
27
+ - Emit an error if `EventMachine::Connection#unbind` is called with an error
28
+
1
29
  ### 0.10.6 / 2017-01-22
2
30
 
3
- * Forcibly close the I/O stream after a timeout if the peer does not respond
31
+ - Forcibly close the I/O stream after a timeout if the peer does not respond
4
32
  after calling `close()`
5
33
 
6
34
  ### 0.10.5 / 2016-11-12
7
35
 
8
- * Set the SNI hostname when making secure requests
36
+ - Set the SNI hostname when making secure requests
9
37
 
10
38
  ### 0.10.4 / 2016-05-20
11
39
 
12
- * Amend warnings issued when running with -W2
40
+ - Amend warnings issued when running with -W2
13
41
 
14
42
  ### 0.10.3 / 2016-02-24
15
43
 
16
- * Use `PATH_INFO` and `QUERY_STRING` rather than the non-standard `REQUEST_URI` from the Rack env
44
+ - Use `PATH_INFO` and `QUERY_STRING` rather than the non-standard `REQUEST_URI`
45
+ from the Rack env
17
46
 
18
47
  ### 0.10.2 / 2015-11-26
19
48
 
20
- * Fix the `headers` and `status` methods on `Client`, which were broken in the
49
+ - Fix the `headers` and `status` methods on `Client`, which were broken in the
21
50
  last release
22
51
 
23
52
  ### 0.10.1 / 2015-11-06
24
53
 
25
- * Make sure errors can be safely emitted if creating the driver fails
26
- * Prevent a race condition when binding `EM.attach` to the socket
54
+ - Make sure errors can be safely emitted if creating the driver fails
55
+ - Prevent a race condition when binding `EM.attach` to the socket
27
56
 
28
57
  ### 0.10.0 / 2015-07-08
29
58
 
30
- * Add the standard `code` and `reason` parameters to the `close` method
59
+ - Add the standard `code` and `reason` parameters to the `close` method
31
60
 
32
61
  ### 0.9.2 / 2014-12-21
33
62
 
34
- * Only emit `error` once, and don't emit it after `close`
63
+ - Only emit `error` once, and don't emit it after `close`
35
64
 
36
65
  ### 0.9.1 / 2014-12-18
37
66
 
38
- * Check that all options to the WebSocket constructor are recognized
67
+ - Check that all options to the WebSocket constructor are recognized
39
68
 
40
69
  ### 0.9.0 / 2014-12-13
41
70
 
42
- * Allow protocol extensions to be passed into websocket-extensions
71
+ - Allow protocol extensions to be passed into websocket-extensions
43
72
 
44
73
  ### 0.8.0 / 2014-11-08
45
74
 
46
- * Support connections via HTTP proxies
75
+ - Support connections via HTTP proxies
47
76
 
48
77
  ### 0.7.5 / 2014-10-04
49
78
 
50
- * Allow sockets to be closed when they are in any state other than `CLOSED`
79
+ - Allow sockets to be closed when they are in any state other than `CLOSED`
51
80
 
52
81
  ### 0.7.4 / 2014-07-06
53
82
 
54
- * Stop using `define_method` to implement `Event` properties, since it blows the method cache
55
- * Stop setup errors masking URI errors in `Client#initialize`
56
- * Make the Goliath adapter compatible with goliath-1.0.4.
83
+ - Stop using `define_method` to implement `Event` properties, since it blows the
84
+ method cache
85
+ - Stop setup errors masking URI errors in `Client#initialize`
86
+ - Make the Goliath adapter compatible with goliath-1.0.4.
57
87
 
58
88
  ### 0.7.3 / 2014-04-24
59
89
 
60
- * Remove an unneeded method override in the `WebSocket` class
90
+ - Remove an unneeded method override in the `WebSocket` class
61
91
 
62
92
  ### 0.7.2 / 2013-12-29
63
93
 
64
- * Fix WebSocket detection in cases where the web server does not produce an `env`
94
+ - Fix WebSocket detection in cases where the web server does not produce an
95
+ `env`
65
96
 
66
97
  ### 0.7.1 / 2013-12-03
67
98
 
68
- * Support the `max_length` websocket-driver option
69
- * Expose a `message` property on `error` events
99
+ - Support the `max_length` websocket-driver option
100
+ - Expose a `message` property on `error` events
70
101
 
71
102
  ### 0.7.0 / 2013-09-09
72
103
 
73
- * Allow the server to send custom headers with EventSource responses
104
+ - Allow the server to send custom headers with EventSource responses
74
105
 
75
106
  ### 0.6.3 / 2013-08-04
76
107
 
77
- * Stop implicitly depending on Rack 1.4
108
+ - Stop implicitly depending on Rack 1.4
78
109
 
79
110
  ### 0.6.2 / 2013-07-05
80
111
 
81
- * Catch errors thrown by EventMachine and emit `error` and `close` events
112
+ - Catch errors thrown by EventMachine and emit `error` and `close` events
82
113
 
83
114
  ### 0.6.1 / 2013-05-12
84
115
 
85
- * Release a gem without log and pid files in it
116
+ - Release a gem without log and pid files in it
86
117
 
87
118
  ### 0.6.0 / 2013-05-12
88
119
 
89
- * Add support for custom headers
120
+ - Add support for custom headers
90
121
 
91
122
  ### 0.5.0 / 2013-05-05
92
123
 
93
- * Extract the protocol handlers into the `websocket-driver` library
94
- * Support the `rack.hijack` API
95
- * Add support for Rainbows 4.5 and Puma
96
- * Officially support JRuby and Rubinius
124
+ - Extract the protocol handlers into the `websocket-driver` library
125
+ - Support the `rack.hijack` API
126
+ - Add support for Rainbows 4.5 and Puma
127
+ - Officially support JRuby and Rubinius
97
128
 
98
129
  ### 0.4.7 / 2013-02-14
99
130
 
100
- * Emit the `close` event if TCP is closed before CLOSE frame is acked
101
- * Treat the `Upgrade: websocket` header case-insensitively because of IE10
102
- * Do not suppress headers in the Thin and Rainbows adapters unless the status is `101`
131
+ - Emit the `close` event if TCP is closed before CLOSE frame is acked
132
+ - Treat the `Upgrade: websocket` header case-insensitively because of IE10
133
+ - Do not suppress headers in the Thin and Rainbows adapters unless the status is
134
+ `101`
103
135
 
104
136
  ### 0.4.6 / 2012-07-09
105
137
 
106
- * Add `Connection: close` to EventSource response
138
+ - Add `Connection: close` to EventSource response
107
139
 
108
140
  ### 0.4.5 / 2012-04-06
109
141
 
110
- * Add WebSocket error code `1011`.
111
- * Handle URLs with no path correctly by sending `GET /`
142
+ - Add WebSocket error code `1011`.
143
+ - Handle URLs with no path correctly by sending `GET /`
112
144
 
113
145
  ### 0.4.4 / 2012-03-16
114
146
 
115
- * Fix installation on JRuby with a platform-specific gem
147
+ - Fix installation on JRuby with a platform-specific gem
116
148
 
117
149
  ### 0.4.3 / 2012-03-12
118
150
 
119
- * Make `extconf.rb` a no-op on JRuby
151
+ - Make `extconf.rb` a no-op on JRuby
120
152
 
121
153
  ### 0.4.2 / 2012-03-09
122
154
 
123
- * Port masking-function C extension to Java for JRuby
155
+ - Port masking-function C extension to Java for JRuby
124
156
 
125
157
  ### 0.4.1 / 2012-02-26
126
158
 
127
- * Treat anything other than an `Array` as a string when calling `send()`
128
- * Fix error loading UTF-8 validation code on Ruby 1.9 with `-Ku` flag
159
+ - Treat anything other than an `Array` as a string when calling `send()`
160
+ - Fix error loading UTF-8 validation code on Ruby 1.9 with `-Ku` flag
129
161
 
130
162
  ### 0.4.0 / 2012-02-13
131
163
 
132
- * Add `ping()` method to server-side `WebSocket` and `EventSource`
133
- * Buffer `send()` calls until the draft-76 handshake is complete
164
+ - Add `ping()` method to server-side `WebSocket` and `EventSource`
165
+ - Buffer `send()` calls until the draft-76 handshake is complete
134
166
 
135
167
  ### 0.3.0 / 2012-01-13
136
168
 
137
- * Add support for `EventSource` connections
138
- * Support the Thin, Rainbows and Goliath web servers
169
+ - Add support for `EventSource` connections
170
+ - Support the Thin, Rainbows and Goliath web servers
139
171
 
140
172
  ### 0.2.0 / 2011-12-21
141
173
 
142
- * Add support for `Sec-WebSocket-Protocol` negotiation
143
- * Support `hixie-76` close frames and 75/76 ignored segments
144
- * Improve performance of HyBi parsing/framing functions
145
- * Write masking function in C
174
+ - Add support for `Sec-WebSocket-Protocol` negotiation
175
+ - Support `hixie-76` close frames and 75/76 ignored segments
176
+ - Improve performance of HyBi parsing/framing functions
177
+ - Write masking function in C
146
178
 
147
179
  ### 0.1.2 / 2011-12-05
148
180
 
149
- * Make `hixie-76` sockets work through HAProxy
181
+ - Make `hixie-76` sockets work through HAProxy
150
182
 
151
183
  ### 0.1.1 / 2011-11-30
152
184
 
153
- * Fix `add_event_listener()` interface methods
185
+ - Fix `add_event_listener()` interface methods
154
186
 
155
187
  ### 0.1.0 / 2011-11-27
156
188
 
157
- * Initial release, based on WebSocket components from Faye
189
+ - Initial release, based on WebSocket components from Faye
data/LICENSE.md ADDED
@@ -0,0 +1,12 @@
1
+ Copyright 2010-2021 James Coglan
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4
+ this file except in compliance with the License. You may obtain a copy of the
5
+ License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software distributed
10
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
12
+ specific language governing permissions and limitations under the License.
data/README.md CHANGED
@@ -1,10 +1,5 @@
1
1
  # faye-websocket
2
2
 
3
- * Travis CI build: [![Build
4
- status](https://secure.travis-ci.org/faye/faye-websocket-ruby.svg)](http://travis-ci.org/faye/faye-websocket-ruby)
5
- * Autobahn tests: [server](http://faye.jcoglan.com/autobahn/servers/),
6
- [client](http://faye.jcoglan.com/autobahn/clients/)
7
-
8
3
  This is a general-purpose WebSocket implementation extracted from the
9
4
  [Faye](http://faye.jcoglan.com) project. It provides classes for easily building
10
5
  WebSocket servers and clients in Ruby. It does not provide a server itself, but
@@ -22,11 +17,11 @@ access via proxies than WebSockets.
22
17
  The following web servers are supported. Other servers that implement the
23
18
  `rack.hijack` API should also work.
24
19
 
25
- * [Goliath](http://postrank-labs.github.com/goliath/)
26
- * [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4
27
- * [Puma](http://puma.io/) >= 2.0
28
- * [Rainbows](http://rainbows.bogomips.org/)
29
- * [Thin](http://code.macournoyer.com/thin/)
20
+ - [Goliath](http://postrank-labs.github.com/goliath/)
21
+ - [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4
22
+ - [Puma](http://puma.io/) >= 2.0
23
+ - [Rainbows](http://rainbows.bogomips.org/)
24
+ - [Thin](http://code.macournoyer.com/thin/)
30
25
 
31
26
 
32
27
  ## Installation
@@ -65,7 +60,7 @@ App = lambda do |env|
65
60
 
66
61
  else
67
62
  # Normal HTTP request
68
- [200, {'Content-Type' => 'text/plain'}, ['Hello']]
63
+ [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
69
64
  end
70
65
  end
71
66
  ```
@@ -133,7 +128,7 @@ including any authorization information and custom headers you require:
133
128
  ws = Faye::WebSocket::Client.new('ws://www.example.com/', [], {
134
129
  :proxy => {
135
130
  :origin => 'http://username:password@proxy.example.com',
136
- :headers => {'User-Agent' => 'ruby'}
131
+ :headers => { 'User-Agent' => 'ruby' }
137
132
  }
138
133
  })
139
134
  ```
@@ -190,45 +185,78 @@ ws = Faye::WebSocket::Client.new(url, protocols, options)
190
185
  `protocols` as an array of subprotocols as described above, or `nil`. `options`
191
186
  is an optional hash containing any of these keys:
192
187
 
193
- * `:extensions` - an array of
188
+ - `:extensions` - an array of
194
189
  [websocket-extensions](https://github.com/faye/websocket-extensions-ruby)
195
190
  compatible extensions, as described above
196
- * `:headers` - a hash containing key-value pairs representing HTTP headers to be
191
+ - `:headers` - a hash containing key-value pairs representing HTTP headers to be
197
192
  sent during the handshake process
198
- * `:max_length` - the maximum allowed size of incoming message frames, in bytes.
193
+ - `:max_length` - the maximum allowed size of incoming message frames, in bytes.
199
194
  The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
200
- * `:ping` - an integer that sets how often the WebSocket should send ping
195
+ - `:ping` - an integer that sets how often the WebSocket should send ping
201
196
  frames, measured in seconds
202
- * `:tls` - a hash containing key-value pairs for specifying TLS parameters.
197
+ - `:tls` - a hash containing key-value pairs for specifying TLS parameters.
203
198
  These are passed along to EventMachine and you can find
204
199
  [more details here](http://rubydoc.info/gems/eventmachine/EventMachine%2FConnection%3Astart_tls)
205
200
 
201
+ ### Secure sockets
202
+
203
+ Starting with version 0.11.0, `Faye::WebSocket::Client` will verify the server
204
+ certificate for `wss` connections. This is not the default behaviour for
205
+ EventMachine's TLS interface, and so our defaults for the `:tls` option are a
206
+ little different.
207
+
208
+ First, `:verify_peer` is enabled by default. Our implementation checks that the
209
+ chain of certificates sent by the server is trusted by your root certificates,
210
+ and that the final certificate's hostname matches the hostname in the request
211
+ URL.
212
+
213
+ By default, we use your system's root certificate store by invoking
214
+ `OpenSSL::X509::Store#set_default_paths`. If you want to use a different set of
215
+ root certificates, you can pass them via the `:root_cert_file` option, which
216
+ takes a path or an array of paths to the certificates you want to use.
217
+
218
+ ```ruby
219
+ ws = Faye::WebSocket::Client.new('wss://example.com/', [], :tls => {
220
+ :root_cert_file => ['path/to/certificate.pem']
221
+ })
222
+ ```
223
+
224
+ If you want to switch off certificate verification altogether, then set
225
+ `:verify_peer` to `false`.
226
+
227
+ ```ruby
228
+ ws = Faye::WebSocket::Client.new('wss://example.com/', [], :tls => {
229
+ :verify_peer => false
230
+ })
231
+ ```
232
+
206
233
  ## WebSocket API
207
234
 
208
235
  Both the server- and client-side `WebSocket` objects support the following API:
209
236
 
210
- * <b>`on(:open) { |event| }`</b> fires when the socket connection is
211
- established. Event has no attributes.
212
- * <b>`on(:message) { |event| }`</b> fires when the socket receives a message.
213
- Event has one attribute, <b>`data`</b>, which is either a `String` (for text
214
- frames) or an `Array` of byte-sized integers (for binary frames).
215
- * <b>`on(:error) { |event| }`</b> fires when there is a protocol error due to
216
- bad data sent by the other peer. This event is purely informational, you do
217
- not need to implement error recovery.
218
- * <b>`on(:close) { |event| }`</b> fires when either the client or the server
219
- closes the connection. Event has two optional attributes, <b>`code`</b> and
220
- <b>`reason`</b>, that expose the status code and message sent by the peer that
237
+ - **`on(:open) { |event| }`** fires when the socket connection is established.
238
+ Event has no attributes.
239
+ - **`on(:message) { |event| }`** fires when the socket receives a message. Event
240
+ has one attribute, **`data`**, which is either a `String` (for text frames) or
241
+ an `Array` of unsigned integers, i.e. integers in the range `0..255` (for
242
+ binary frames).
243
+ - **`on(:error) { |event| }`** fires when there is a protocol error due to bad
244
+ data sent by the other peer. This event is purely informational, you do not
245
+ need to implement error recovery.
246
+ - **`on(:close) { |event| }`** fires when either the client or the server closes
247
+ the connection. Event has two optional attributes, **`code`** and
248
+ **`reason`**, that expose the status code and message sent by the peer that
221
249
  closed the connection.
222
- * <b>`send(message)`</b> accepts either a `String` or an `Array` of byte-sized
250
+ - **`send(message)`** accepts either a `String` or an `Array` of byte-sized
223
251
  integers and sends a text or binary message over the connection to the other
224
252
  peer; binary data must be encoded as an `Array`.
225
- * <b>`ping(message, &callback)`</b> sends a ping frame with an optional message
226
- and fires the callback when a matching pong is received.
227
- * <b>`close(code, reason)`</b> closes the connection, sending the given status
228
- code and reason text, both of which are optional.
229
- * <b>`version`</b> is a string containing the version of the `WebSocket`
230
- protocol the connection is using.
231
- * <b>`protocol`</b> is a string (which may be empty) identifying the subprotocol
253
+ - **`ping(message, &callback)`** sends a ping frame with an optional message and
254
+ fires the callback when a matching pong is received.
255
+ - **`close(code, reason)`** closes the connection, sending the given status code
256
+ and reason text, both of which are optional.
257
+ - **`version`** is a string containing the version of the `WebSocket` protocol
258
+ the connection is using.
259
+ - **`protocol`** is a string (which may be empty) identifying the subprotocol
232
260
  the socket is using.
233
261
 
234
262
 
@@ -261,7 +289,7 @@ App = lambda do |env|
261
289
 
262
290
  else
263
291
  # Normal HTTP request
264
- [200, {'Content-Type' => 'text/plain'}, ['Hello']]
292
+ [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
265
293
  end
266
294
  end
267
295
  ```
@@ -276,29 +304,29 @@ es.send('Breaking News!', :event => 'notification', :id => '99')
276
304
 
277
305
  The `EventSource` object exposes the following properties:
278
306
 
279
- * <b>`url`</b> is a string containing the URL the client used to create the
307
+ - **`url`** is a string containing the URL the client used to create the
280
308
  EventSource.
281
- * <b>`last_event_id`</b> is a string containing the last event ID received by
282
- the client. You can use this when the client reconnects after a dropped
283
- connection to determine which messages need resending.
309
+ - **`last_event_id`** is a string containing the last event ID received by the
310
+ client. You can use this when the client reconnects after a dropped connection
311
+ to determine which messages need resending.
284
312
 
285
313
  When you initialize an EventSource with `Faye::EventSource.new`, you can pass
286
314
  configuration options after the `env` parameter. Available options are:
287
315
 
288
- * <b>`:headers`</b> is a hash containing custom headers to be set on the
316
+ - **`:headers`** is a hash containing custom headers to be set on the
289
317
  EventSource response.
290
- * <b>`:retry`</b> is a number that tells the client how long (in seconds) it
291
- should wait after a dropped connection before attempting to reconnect.
292
- * <b>`:ping`</b> is a number that tells the server how often (in seconds) to
293
- send 'ping' packets to the client to keep the connection open, to defeat
294
- timeouts set by proxies. The client will ignore these messages.
318
+ - **`:retry`** is a number that tells the client how long (in seconds) it should
319
+ wait after a dropped connection before attempting to reconnect.
320
+ - **`:ping`** is a number that tells the server how often (in seconds) to send
321
+ 'ping' packets to the client to keep the connection open, to defeat timeouts
322
+ set by proxies. The client will ignore these messages.
295
323
 
296
324
  For example, this creates a connection that allows access from any origin, pings
297
325
  every 15 seconds and is retryable every 10 seconds if the connection is broken:
298
326
 
299
327
  ```ruby
300
328
  es = Faye::EventSource.new(es,
301
- :headers => {'Access-Control-Allow-Origin' => '*'},
329
+ :headers => { 'Access-Control-Allow-Origin' => '*' },
302
330
  :ping => 15,
303
331
  :retry => 10
304
332
  )
@@ -487,27 +515,3 @@ class EchoServer < Goliath::API
487
515
  end
488
516
  end
489
517
  ```
490
-
491
-
492
- ## License
493
-
494
- (The MIT License)
495
-
496
- Copyright (c) 2010-2017 James Coglan
497
-
498
- Permission is hereby granted, free of charge, to any person obtaining a copy of
499
- this software and associated documentation files (the 'Software'), to deal in
500
- the Software without restriction, including without limitation the rights to
501
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
502
- the Software, and to permit persons to whom the Software is furnished to do so,
503
- subject to the following conditions:
504
-
505
- The above copyright notice and this permission notice shall be included in all
506
- copies or substantial portions of the Software.
507
-
508
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
509
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
510
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
511
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
512
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
513
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.