async-websocket 0.19.0 → 0.26.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/websocket/adapters/http.rb +19 -28
- data/lib/async/websocket/adapters/rack.rb +13 -36
- data/lib/async/websocket/adapters/rails.rb +8 -29
- data/lib/async/websocket/client.rb +49 -30
- data/lib/async/websocket/connect_request.rb +18 -38
- data/lib/async/websocket/connect_response.rb +5 -21
- data/lib/async/websocket/connection.rb +11 -51
- data/lib/async/websocket/error.rb +10 -19
- data/lib/async/websocket/request.rb +12 -21
- data/lib/async/websocket/response.rb +6 -21
- data/lib/async/websocket/server.rb +9 -45
- data/lib/async/websocket/upgrade_request.rb +15 -36
- data/lib/async/websocket/upgrade_response.rb +14 -30
- data/lib/async/websocket/version.rb +5 -20
- data/lib/async/websocket.rb +4 -19
- data/license.md +32 -0
- data/readme.md +31 -0
- data.tar.gz.sig +0 -0
- metadata +57 -84
- metadata.gz.sig +0 -0
- data/lib/async/websocket/proxy.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee54a400cc9103d9fb64852edc368fed4c0f288d5e78b72656375a3dfb4c28ed
|
4
|
+
data.tar.gz: f58fdc2b051e0ae052b6b4ee1e68b0f31c70fc720d30733365669f719a178adc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9a06b567caeb24653854e41f0a483ea8fd0408da607bea334a558d2d508f7b13e60563e5dfb987978b8ce18797af01470c807e91887e621c5a5bb2a653b8dd0
|
7
|
+
data.tar.gz: '033085a398cfa0cf26fd972bcb035a46a07385a9d34949f07339357afe66620629d33082038f56930909dd3462627763512fc79a9120e3236fb7bda9aba190e7'
|
checksums.yaml.gz.sig
ADDED
Binary file
|
@@ -1,28 +1,14 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2021, by Aurora Nockert.
|
22
6
|
|
23
7
|
require_relative '../connection'
|
24
8
|
require_relative '../response'
|
25
9
|
|
10
|
+
require 'protocol/websocket/extensions'
|
11
|
+
|
26
12
|
module Async
|
27
13
|
module WebSocket
|
28
14
|
module Adapters
|
@@ -30,22 +16,27 @@ module Async
|
|
30
16
|
include ::Protocol::WebSocket::Headers
|
31
17
|
|
32
18
|
def self.websocket?(request)
|
33
|
-
Array(request.protocol).
|
19
|
+
Array(request.protocol).any? { |e| e.casecmp?(PROTOCOL) }
|
34
20
|
end
|
35
21
|
|
36
|
-
def self.open(request, headers: [], protocols: [], handler: Connection, **options, &block)
|
37
|
-
if
|
22
|
+
def self.open(request, headers: [], protocols: [], handler: Connection, extensions: ::Protocol::WebSocket::Extensions::Server.default, **options, &block)
|
23
|
+
if websocket?(request)
|
24
|
+
headers = Protocol::HTTP::Headers[headers]
|
25
|
+
|
38
26
|
# Select websocket sub-protocol:
|
39
27
|
if requested_protocol = request.headers[SEC_WEBSOCKET_PROTOCOL]
|
40
28
|
protocol = (requested_protocol & protocols).first
|
41
29
|
end
|
42
30
|
|
31
|
+
if extensions and extension_headers = request.headers[SEC_WEBSOCKET_EXTENSIONS]
|
32
|
+
extensions.accept(extension_headers) do |header|
|
33
|
+
headers.add(SEC_WEBSOCKET_EXTENSIONS, header.join(";"))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
43
37
|
response = Response.for(request, headers, protocol: protocol, **options) do |stream|
|
44
|
-
# Once we get to this point, we no longer need to hold on to the response:
|
45
|
-
response = nil
|
46
|
-
|
47
38
|
framer = Protocol::WebSocket::Framer.new(stream)
|
48
|
-
connection = handler.call(framer, protocol)
|
39
|
+
connection = handler.call(framer, protocol, extensions)
|
49
40
|
|
50
41
|
yield connection
|
51
42
|
|
@@ -1,26 +1,11 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2022, by Samuel Williams.
|
22
5
|
|
23
6
|
require_relative 'http'
|
7
|
+
require 'protocol/rack/request'
|
8
|
+
require 'protocol/rack/adapter'
|
24
9
|
|
25
10
|
module Async
|
26
11
|
module WebSocket
|
@@ -29,24 +14,16 @@ module Async
|
|
29
14
|
include ::Protocol::WebSocket::Headers
|
30
15
|
|
31
16
|
def self.websocket?(env)
|
32
|
-
|
17
|
+
HTTP.websocket?(
|
18
|
+
::Protocol::Rack::Request[env]
|
19
|
+
)
|
33
20
|
end
|
34
21
|
|
35
22
|
def self.open(env, **options, &block)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
headers = response.headers
|
41
|
-
|
42
|
-
if protocol = response.protocol
|
43
|
-
headers = Protocol::HTTP::Headers::Merged.new(headers, [
|
44
|
-
['rack.protocol', protocol]
|
45
|
-
])
|
46
|
-
end
|
47
|
-
|
48
|
-
return [response.status, headers.to_h, response.body]
|
49
|
-
end
|
23
|
+
request = ::Protocol::Rack::Request[env]
|
24
|
+
|
25
|
+
if response = HTTP.open(request, **options, &block)
|
26
|
+
return Protocol::Rack::Adapter.make_response(env, response)
|
50
27
|
end
|
51
28
|
end
|
52
29
|
end
|
@@ -1,24 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2023, by Emily Love Mills.
|
22
6
|
|
23
7
|
require_relative 'rack'
|
24
8
|
|
@@ -28,15 +12,10 @@ module Async
|
|
28
12
|
module Rails
|
29
13
|
def self.open(request, **options, &block)
|
30
14
|
if response = Rack.open(request.env, **options, &block)
|
31
|
-
response
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# Close the response to prevent Rails from... trying to render a view?
|
36
|
-
return ::ActionDispatch::Response.new(response[0], response[1], nil).tap(&:close)
|
15
|
+
::Rack::Response[*response]
|
16
|
+
else
|
17
|
+
::ActionDispatch::Response.new(404)
|
37
18
|
end
|
38
|
-
|
39
|
-
return ::ActionDispatch::Response.new(404, [], [])
|
40
19
|
end
|
41
20
|
end
|
42
21
|
end
|
@@ -1,33 +1,22 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2015-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2019, by Bryan Powell.
|
6
|
+
# Copyright, 2019, by Janko Marohnić.
|
7
|
+
# Copyright, 2023, by Thomas Morgan.
|
22
8
|
|
23
9
|
require_relative 'request'
|
24
10
|
require_relative 'connection'
|
25
11
|
|
26
12
|
require 'protocol/websocket/headers'
|
13
|
+
require 'protocol/websocket/extensions'
|
27
14
|
require 'protocol/http/middleware'
|
28
15
|
|
29
16
|
require 'async/http/client'
|
30
17
|
|
18
|
+
require 'delegate'
|
19
|
+
|
31
20
|
module Async
|
32
21
|
module WebSocket
|
33
22
|
# This is a basic synchronous websocket client:
|
@@ -47,13 +36,29 @@ module Async
|
|
47
36
|
end
|
48
37
|
end
|
49
38
|
|
39
|
+
class ClientCloseDecorator < SimpleDelegator
|
40
|
+
def initialize(client, connection)
|
41
|
+
@client = client
|
42
|
+
super(connection)
|
43
|
+
end
|
44
|
+
|
45
|
+
def close(...)
|
46
|
+
super(...)
|
47
|
+
|
48
|
+
if @client
|
49
|
+
@client.close
|
50
|
+
@client = nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
50
55
|
# @return [Connection] an open websocket connection to the given endpoint.
|
51
|
-
def self.connect(endpoint, *
|
52
|
-
client = self.open(endpoint, *
|
56
|
+
def self.connect(endpoint, *arguments, **options, &block)
|
57
|
+
client = self.open(endpoint, *arguments)
|
53
58
|
connection = client.connect(endpoint.authority, endpoint.path, **options)
|
54
|
-
|
55
|
-
return connection unless block_given?
|
56
|
-
|
59
|
+
|
60
|
+
return ClientCloseDecorator.new(client, connection) unless block_given?
|
61
|
+
|
57
62
|
begin
|
58
63
|
yield connection
|
59
64
|
ensure
|
@@ -86,9 +91,14 @@ module Async
|
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
89
|
-
def connect(authority, path, headers: nil, handler: Connection, **options, &block)
|
94
|
+
def connect(authority, path, scheme: @delegate.scheme, headers: nil, handler: Connection, extensions: ::Protocol::WebSocket::Extensions::Client.default, **options, &block)
|
90
95
|
headers = ::Protocol::HTTP::Headers[headers]
|
91
|
-
|
96
|
+
|
97
|
+
extensions&.offer do |extension|
|
98
|
+
headers.add(SEC_WEBSOCKET_EXTENSIONS, extension.join("; "))
|
99
|
+
end
|
100
|
+
|
101
|
+
request = Request.new(scheme, authority, path, headers, **options)
|
92
102
|
|
93
103
|
pool = @delegate.pool
|
94
104
|
connection = pool.acquire
|
@@ -96,17 +106,26 @@ module Async
|
|
96
106
|
response = request.call(connection)
|
97
107
|
|
98
108
|
unless response.stream?
|
109
|
+
response.close
|
110
|
+
|
99
111
|
raise ProtocolError, "Failed to negotiate connection: #{response.status}"
|
100
112
|
end
|
101
113
|
|
102
114
|
protocol = response.headers[SEC_WEBSOCKET_PROTOCOL]&.first
|
103
115
|
stream = response.stream
|
104
|
-
response = nil
|
105
116
|
|
106
117
|
framer = Framer.new(pool, connection, stream)
|
118
|
+
|
107
119
|
connection = nil
|
108
120
|
|
109
|
-
|
121
|
+
if extension_headers = response.headers[SEC_WEBSOCKET_EXTENSIONS]
|
122
|
+
extensions.accept(extension_headers)
|
123
|
+
end
|
124
|
+
|
125
|
+
response = nil
|
126
|
+
stream = nil
|
127
|
+
|
128
|
+
return handler.call(framer, protocol, extensions, **@options, &block)
|
110
129
|
ensure
|
111
130
|
pool.release(connection) if connection
|
112
131
|
end
|
@@ -1,34 +1,19 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2023, by Thomas Morgan.
|
22
6
|
|
23
7
|
require 'protocol/http/request'
|
24
8
|
require 'protocol/http/headers'
|
25
9
|
require 'protocol/websocket/headers'
|
10
|
+
require 'protocol/http/body/readable'
|
26
11
|
|
27
|
-
require 'async/
|
12
|
+
require 'async/variable'
|
28
13
|
|
29
14
|
module Async
|
30
15
|
module WebSocket
|
31
|
-
# This is required for HTTP/
|
16
|
+
# This is required for HTTP/2 to establish a connection using the WebSocket protocol.
|
32
17
|
# See https://tools.ietf.org/html/rfc8441 for more details.
|
33
18
|
class ConnectRequest < ::Protocol::HTTP::Request
|
34
19
|
include ::Protocol::WebSocket::Headers
|
@@ -36,13 +21,14 @@ module Async
|
|
36
21
|
class Wrapper
|
37
22
|
def initialize(stream, response)
|
38
23
|
@response = response
|
39
|
-
@body = @response.body
|
40
24
|
@stream = stream
|
41
25
|
end
|
42
26
|
|
43
|
-
|
27
|
+
def close
|
28
|
+
@response.close
|
29
|
+
end
|
44
30
|
|
45
|
-
attr_accessor :
|
31
|
+
attr_accessor :response
|
46
32
|
attr_accessor :stream
|
47
33
|
|
48
34
|
def stream?
|
@@ -56,30 +42,24 @@ module Async
|
|
56
42
|
def headers
|
57
43
|
@response.headers
|
58
44
|
end
|
59
|
-
|
60
|
-
def body?
|
61
|
-
true
|
62
|
-
end
|
63
|
-
|
64
|
-
def protocol
|
65
|
-
@response.protocol
|
66
|
-
end
|
67
45
|
end
|
68
46
|
|
69
|
-
class Hijack <
|
47
|
+
class Hijack < Protocol::HTTP::Body::Readable
|
70
48
|
def initialize(request)
|
71
49
|
@request = request
|
72
|
-
@stream =
|
50
|
+
@stream = Async::Variable.new
|
73
51
|
end
|
74
52
|
|
75
53
|
def stream?
|
76
54
|
true
|
77
55
|
end
|
78
56
|
|
79
|
-
|
57
|
+
def stream
|
58
|
+
@stream.value
|
59
|
+
end
|
80
60
|
|
81
61
|
def call(stream)
|
82
|
-
@stream
|
62
|
+
@stream.resolve(stream)
|
83
63
|
end
|
84
64
|
end
|
85
65
|
|
@@ -1,24 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
22
5
|
|
23
6
|
require 'protocol/http/response'
|
24
7
|
require 'async/http/body/hijack'
|
@@ -37,6 +20,7 @@ module Async
|
|
37
20
|
end
|
38
21
|
|
39
22
|
body = Async::HTTP::Body::Hijack.wrap(request, &block)
|
23
|
+
|
40
24
|
super(request.version, 200, headers, body)
|
41
25
|
end
|
42
26
|
end
|
@@ -1,22 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2018-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2019, by Janko Marohnić.
|
20
6
|
|
21
7
|
require 'protocol/websocket/connection'
|
22
8
|
require 'protocol/websocket/headers'
|
@@ -31,9 +17,11 @@ module Async
|
|
31
17
|
class Connection < ::Protocol::WebSocket::Connection
|
32
18
|
include ::Protocol::WebSocket::Headers
|
33
19
|
|
34
|
-
def self.call(framer, protocol = [], **options)
|
20
|
+
def self.call(framer, protocol = [], extensions = nil, **options)
|
35
21
|
instance = self.new(framer, Array(protocol).first, **options)
|
36
22
|
|
23
|
+
extensions&.apply(instance)
|
24
|
+
|
37
25
|
return instance unless block_given?
|
38
26
|
|
39
27
|
begin
|
@@ -43,45 +31,17 @@ module Async
|
|
43
31
|
end
|
44
32
|
end
|
45
33
|
|
46
|
-
def initialize(framer, protocol = nil,
|
34
|
+
def initialize(framer, protocol = nil, **options)
|
47
35
|
super(framer, **options)
|
48
36
|
|
49
37
|
@protocol = protocol
|
50
|
-
@response = response
|
51
38
|
end
|
52
39
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
if @response
|
57
|
-
@response.finish
|
58
|
-
@response = nil
|
59
|
-
end
|
40
|
+
def reusable?
|
41
|
+
false
|
60
42
|
end
|
61
43
|
|
62
44
|
attr :protocol
|
63
|
-
|
64
|
-
def read
|
65
|
-
if buffer = super
|
66
|
-
parse(buffer)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def write(object)
|
71
|
-
super(dump(object))
|
72
|
-
end
|
73
|
-
|
74
|
-
def parse(buffer)
|
75
|
-
JSON.parse(buffer, symbolize_names: true)
|
76
|
-
end
|
77
|
-
|
78
|
-
def dump(object)
|
79
|
-
JSON.dump(object)
|
80
|
-
end
|
81
|
-
|
82
|
-
def call
|
83
|
-
self.close
|
84
|
-
end
|
85
45
|
end
|
86
46
|
end
|
87
47
|
end
|
@@ -1,22 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
20
5
|
|
21
6
|
require 'protocol/websocket/error'
|
22
7
|
|
@@ -24,5 +9,11 @@ module Async
|
|
24
9
|
module WebSocket
|
25
10
|
class ProtocolError < ::Protocol::WebSocket::ProtocolError
|
26
11
|
end
|
12
|
+
|
13
|
+
class Error < ::Protocol::WebSocket::Error
|
14
|
+
end
|
15
|
+
|
16
|
+
class UnsupportedVersionError < Error
|
17
|
+
end
|
27
18
|
end
|
28
19
|
end
|
@@ -1,25 +1,11 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative 'connect_request'
|
22
7
|
require_relative 'upgrade_request'
|
8
|
+
require_relative 'error'
|
23
9
|
|
24
10
|
module Async
|
25
11
|
module WebSocket
|
@@ -41,6 +27,10 @@ module Async
|
|
41
27
|
@body = nil
|
42
28
|
end
|
43
29
|
|
30
|
+
def protocol
|
31
|
+
PROTOCOL
|
32
|
+
end
|
33
|
+
|
44
34
|
attr_accessor :scheme
|
45
35
|
attr_accessor :authority
|
46
36
|
attr_accessor :path
|
@@ -56,7 +46,7 @@ module Async
|
|
56
46
|
return ConnectRequest.new(self, **@options).call(connection)
|
57
47
|
end
|
58
48
|
|
59
|
-
raise
|
49
|
+
raise UnsupportedVersionError, "Unsupported HTTP version: #{connection.version}!"
|
60
50
|
end
|
61
51
|
|
62
52
|
def idempotent?
|
@@ -64,7 +54,8 @@ module Async
|
|
64
54
|
end
|
65
55
|
|
66
56
|
def to_s
|
67
|
-
"
|
57
|
+
uri = "#{@scheme}://#{@authority}#{@path}"
|
58
|
+
"\#<#{self.class} uri=#{uri.inspect}>"
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|
@@ -1,22 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative 'upgrade_response'
|
22
7
|
require_relative 'connect_response'
|
@@ -30,11 +15,11 @@ module Async
|
|
30
15
|
def self.for(request, headers = nil, **options, &body)
|
31
16
|
if request.version =~ /http\/1/i
|
32
17
|
return UpgradeResponse.new(request, headers, **options, &body)
|
33
|
-
elsif request.version =~ /
|
18
|
+
elsif request.version =~ /http\/2/i
|
34
19
|
return ConnectResponse.new(request, headers, **options, &body)
|
35
20
|
end
|
36
21
|
|
37
|
-
raise
|
22
|
+
raise UnsupportedVersionError, "Unsupported HTTP version: #{request.version}!"
|
38
23
|
end
|
39
24
|
end
|
40
25
|
end
|
@@ -1,22 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2018-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2019, by destructobeam.
|
20
6
|
|
21
7
|
require_relative 'connection'
|
22
8
|
require_relative 'response'
|
@@ -28,37 +14,15 @@ module Async
|
|
28
14
|
class Server < ::Protocol::HTTP::Middleware
|
29
15
|
include ::Protocol::WebSocket::Headers
|
30
16
|
|
31
|
-
def initialize(delegate,
|
17
|
+
def initialize(delegate, **options, &block)
|
32
18
|
super(delegate)
|
33
19
|
|
34
|
-
@
|
35
|
-
@
|
36
|
-
end
|
37
|
-
|
38
|
-
def select_protocol(request)
|
39
|
-
if requested_protocol = request.headers[SEC_WEBSOCKET_PROTOCOL]
|
40
|
-
return (requested_protocol & @protocols).first
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def response(request)
|
20
|
+
@options = options
|
21
|
+
@block = block
|
45
22
|
end
|
46
23
|
|
47
24
|
def call(request)
|
48
|
-
|
49
|
-
# Select websocket sub-protocol:
|
50
|
-
protocol = select_protocol(request)
|
51
|
-
|
52
|
-
# request.headers = nil
|
53
|
-
|
54
|
-
Response.for(request, headers, protocol: protocol, **options) do |stream|
|
55
|
-
framer = Protocol::WebSocket::Framer.new(stream)
|
56
|
-
|
57
|
-
yield handler.call(framer, protocol)
|
58
|
-
end
|
59
|
-
else
|
60
|
-
super
|
61
|
-
end
|
25
|
+
Async::WebSocket::Adapters::HTTP.open(request, **@options, &@block) or super
|
62
26
|
end
|
63
27
|
end
|
64
28
|
end
|
@@ -1,24 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2023, by Thomas Morgan.
|
22
6
|
|
23
7
|
require 'protocol/http/middleware'
|
24
8
|
require 'protocol/http/request'
|
@@ -33,19 +17,25 @@ require_relative 'error'
|
|
33
17
|
module Async
|
34
18
|
module WebSocket
|
35
19
|
# This is required for HTTP/1.x to upgrade the connection to the WebSocket protocol.
|
20
|
+
# See https://tools.ietf.org/html/rfc6455
|
36
21
|
class UpgradeRequest < ::Protocol::HTTP::Request
|
37
22
|
include ::Protocol::WebSocket::Headers
|
38
23
|
|
39
24
|
class Wrapper
|
40
|
-
def initialize(response)
|
25
|
+
def initialize(response, verified:)
|
41
26
|
@response = response
|
42
27
|
@stream = nil
|
28
|
+
@verified = verified
|
29
|
+
end
|
30
|
+
|
31
|
+
def close
|
32
|
+
@response.close
|
43
33
|
end
|
44
34
|
|
45
35
|
attr_accessor :response
|
46
36
|
|
47
37
|
def stream?
|
48
|
-
@response.status == 101
|
38
|
+
@response.status == 101 && @verified
|
49
39
|
end
|
50
40
|
|
51
41
|
def status
|
@@ -56,18 +46,6 @@ module Async
|
|
56
46
|
@response.headers
|
57
47
|
end
|
58
48
|
|
59
|
-
def body?
|
60
|
-
false
|
61
|
-
end
|
62
|
-
|
63
|
-
def body
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
|
67
|
-
def protocol
|
68
|
-
@response.protocol
|
69
|
-
end
|
70
|
-
|
71
49
|
def stream
|
72
50
|
@stream ||= @response.hijack!
|
73
51
|
end
|
@@ -98,8 +76,9 @@ module Async
|
|
98
76
|
raise ProtocolError, "Invalid accept digest, expected #{expected_accept_digest.inspect}, got #{accept_digest.inspect}!"
|
99
77
|
end
|
100
78
|
end
|
79
|
+
verified = accept_digest && Array(response.protocol) == %w(websocket) && response.headers['connection']&.include?('upgrade')
|
101
80
|
|
102
|
-
return Wrapper.new(response)
|
81
|
+
return Wrapper.new(response, verified: verified)
|
103
82
|
end
|
104
83
|
end
|
105
84
|
end
|
@@ -1,24 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
+
# Copyright, 2023, by Thomas Morgan.
|
22
6
|
|
23
7
|
require 'async/http/body/hijack'
|
24
8
|
require 'protocol/http/response'
|
@@ -35,17 +19,17 @@ module Async
|
|
35
19
|
|
36
20
|
if accept_nounce = request.headers[SEC_WEBSOCKET_KEY]&.first
|
37
21
|
headers.add(SEC_WEBSOCKET_ACCEPT, Nounce.accept_digest(accept_nounce))
|
38
|
-
|
22
|
+
|
23
|
+
if protocol
|
24
|
+
headers.add(SEC_WEBSOCKET_PROTOCOL, protocol)
|
25
|
+
end
|
26
|
+
|
27
|
+
body = Async::HTTP::Body::Hijack.wrap(request, &block)
|
28
|
+
|
29
|
+
super(request.version, 101, headers, body, PROTOCOL)
|
39
30
|
else
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
if protocol
|
44
|
-
headers.add(SEC_WEBSOCKET_PROTOCOL, protocol)
|
31
|
+
super(request.version, 400, headers)
|
45
32
|
end
|
46
|
-
|
47
|
-
body = Async::HTTP::Body::Hijack.wrap(request, &block)
|
48
|
-
super(request.version, status, headers, body, PROTOCOL)
|
49
33
|
end
|
50
34
|
end
|
51
35
|
end
|
@@ -1,25 +1,10 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2018-2023, by Samuel Williams.
|
20
5
|
|
21
6
|
module Async
|
22
7
|
module WebSocket
|
23
|
-
VERSION = "0.
|
8
|
+
VERSION = "0.26.0"
|
24
9
|
end
|
25
10
|
end
|
data/lib/async/websocket.rb
CHANGED
@@ -1,22 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2015-2023, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative 'websocket/version'
|
22
7
|
require_relative 'websocket/server'
|
data/license.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2015-2023, by Samuel Williams.
|
4
|
+
Copyright, 2019, by Bryan Powell.
|
5
|
+
Copyright, 2019, by destructobeam.
|
6
|
+
Copyright, 2019, by Michel Boaventura.
|
7
|
+
Copyright, 2019, by Janko Marohnić.
|
8
|
+
Copyright, 2020-2021, by Olle Jonsson.
|
9
|
+
Copyright, 2020, by Juan Antonio Martín Lucas.
|
10
|
+
Copyright, 2021, by Gleb Sinyavskiy.
|
11
|
+
Copyright, 2021, by Aurora Nockert.
|
12
|
+
Copyright, 2023, by Peter Runich.
|
13
|
+
Copyright, 2023, by Thomas Morgan.
|
14
|
+
Copyright, 2023, by Emily Love Mills.
|
15
|
+
|
16
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
17
|
+
of this software and associated documentation files (the "Software"), to deal
|
18
|
+
in the Software without restriction, including without limitation the rights
|
19
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
20
|
+
copies of the Software, and to permit persons to whom the Software is
|
21
|
+
furnished to do so, subject to the following conditions:
|
22
|
+
|
23
|
+
The above copyright notice and this permission notice shall be included in all
|
24
|
+
copies or substantial portions of the Software.
|
25
|
+
|
26
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
27
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
28
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
29
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
30
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
31
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
32
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Async::WebSocket
|
2
|
+
|
3
|
+
An asynchronous websocket client/server implementation for [HTTP/1](https://tools.ietf.org/html/rfc6455) and [HTTP/2](https://tools.ietf.org/html/rfc8441).
|
4
|
+
|
5
|
+
[](https://github.com/socketry/async-websocket/actions?workflow=Test)
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Please see the [project documentation](https://socketry.github.io/async-websocket/) for more details.
|
10
|
+
|
11
|
+
- [Getting Started](https://socketry.github.io/async-websocket/guides/getting-started/index) - This guide shows you how to implement a basic client and server.
|
12
|
+
|
13
|
+
- [Rails Integration](https://socketry.github.io/async-websocket/guides/rails-integration/index) - This guide explains how to use `async-websocket` with `falcon`.
|
14
|
+
|
15
|
+
## Contributing
|
16
|
+
|
17
|
+
We welcome contributions to this project.
|
18
|
+
|
19
|
+
1. Fork it.
|
20
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
21
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
22
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
23
|
+
5. Create new Pull Request.
|
24
|
+
|
25
|
+
### Developer Certificate of Origin
|
26
|
+
|
27
|
+
This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
|
28
|
+
|
29
|
+
### Contributor Covenant
|
30
|
+
|
31
|
+
This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,54 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-websocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
+
- destructobeam
|
9
|
+
- Olle Jonsson
|
10
|
+
- Thomas Morgan
|
11
|
+
- Aurora Nockert
|
12
|
+
- Bryan Powell
|
13
|
+
- Emily Love Mills
|
14
|
+
- Gleb Sinyavskiy
|
15
|
+
- Janko Marohnić
|
16
|
+
- Juan Antonio Martín Lucas
|
17
|
+
- Michel Boaventura
|
18
|
+
- Peter Runich
|
8
19
|
autorequire:
|
9
20
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
|
21
|
+
cert_chain:
|
22
|
+
- |
|
23
|
+
-----BEGIN CERTIFICATE-----
|
24
|
+
MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
|
25
|
+
ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
|
26
|
+
CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
|
27
|
+
MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
|
28
|
+
MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
|
29
|
+
bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
30
|
+
igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
|
31
|
+
9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
|
32
|
+
sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
|
33
|
+
e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
|
34
|
+
XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
|
35
|
+
RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
|
36
|
+
tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
|
37
|
+
zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
|
38
|
+
xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
39
|
+
BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
|
40
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
|
41
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
|
42
|
+
cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
|
43
|
+
xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
|
44
|
+
c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
|
45
|
+
8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
|
46
|
+
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
47
|
+
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
48
|
+
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
49
|
+
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
50
|
+
-----END CERTIFICATE-----
|
51
|
+
date: 2023-12-09 00:00:00.000000000 Z
|
12
52
|
dependencies:
|
13
53
|
- !ruby/object:Gem::Dependency
|
14
54
|
name: async-http
|
@@ -39,103 +79,33 @@ dependencies:
|
|
39
79
|
- !ruby/object:Gem::Version
|
40
80
|
version: '1.23'
|
41
81
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: protocol-
|
82
|
+
name: protocol-rack
|
43
83
|
requirement: !ruby/object:Gem::Requirement
|
44
84
|
requirements:
|
45
85
|
- - "~>"
|
46
86
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
87
|
+
version: '0.1'
|
48
88
|
type: :runtime
|
49
89
|
prerelease: false
|
50
90
|
version_requirements: !ruby/object:Gem::Requirement
|
51
91
|
requirements:
|
52
92
|
- - "~>"
|
53
93
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: async-rspec
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bundler
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: covered
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: falcon
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0.34'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0.34'
|
94
|
+
version: '0.1'
|
111
95
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rspec
|
96
|
+
name: protocol-websocket
|
127
97
|
requirement: !ruby/object:Gem::Requirement
|
128
98
|
requirements:
|
129
99
|
- - "~>"
|
130
100
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
132
|
-
type: :
|
101
|
+
version: '0.11'
|
102
|
+
type: :runtime
|
133
103
|
prerelease: false
|
134
104
|
version_requirements: !ruby/object:Gem::Requirement
|
135
105
|
requirements:
|
136
106
|
- - "~>"
|
137
107
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
108
|
+
version: '0.11'
|
139
109
|
description:
|
140
110
|
email:
|
141
111
|
executables: []
|
@@ -151,17 +121,20 @@ files:
|
|
151
121
|
- lib/async/websocket/connect_response.rb
|
152
122
|
- lib/async/websocket/connection.rb
|
153
123
|
- lib/async/websocket/error.rb
|
154
|
-
- lib/async/websocket/proxy.rb
|
155
124
|
- lib/async/websocket/request.rb
|
156
125
|
- lib/async/websocket/response.rb
|
157
126
|
- lib/async/websocket/server.rb
|
158
127
|
- lib/async/websocket/upgrade_request.rb
|
159
128
|
- lib/async/websocket/upgrade_response.rb
|
160
129
|
- lib/async/websocket/version.rb
|
130
|
+
- license.md
|
131
|
+
- readme.md
|
161
132
|
homepage: https://github.com/socketry/async-websocket
|
162
133
|
licenses:
|
163
134
|
- MIT
|
164
|
-
metadata:
|
135
|
+
metadata:
|
136
|
+
documentation_uri: https://socketry.github.io/async-websocket/
|
137
|
+
funding_uri: https://github.com/sponsors/ioquatix
|
165
138
|
post_install_message:
|
166
139
|
rdoc_options: []
|
167
140
|
require_paths:
|
@@ -170,14 +143,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
143
|
requirements:
|
171
144
|
- - ">="
|
172
145
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
146
|
+
version: '3.0'
|
174
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
148
|
requirements:
|
176
149
|
- - ">="
|
177
150
|
- !ruby/object:Gem::Version
|
178
151
|
version: '0'
|
179
152
|
requirements: []
|
180
|
-
rubygems_version: 3.
|
153
|
+
rubygems_version: 3.4.22
|
181
154
|
signing_key:
|
182
155
|
specification_version: 4
|
183
156
|
summary: An async websocket library on top of websocket-driver.
|
metadata.gz.sig
ADDED
Binary file
|
File without changes
|