protocol-rack 0.1.5 → 0.2.1

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
  SHA256:
3
- metadata.gz: '05358d653d700368d3ca27a586f60aab5e3ba12ed2b23562deb92620e913b889'
4
- data.tar.gz: 23961dcd7822636d774cf70b2200e258f25f4c82a0991a076a183c6381972a50
3
+ metadata.gz: c5cd531684b517c9695d07dfaa9f4301e3e77fcf52389b471f1f89aaa2227227
4
+ data.tar.gz: aa8f85b68326ca7f646d4c9e15bbdf0f6165bb969fad7345e933a8232e5263fb
5
5
  SHA512:
6
- metadata.gz: 25eae3570334a81ff7cefaa6ee128d4cc3cb89550cb738aca6224b91fb01cd44c91b7b6f55428e985a38c3363187fd92bb9fb7a06a71f705ec21eb4e929d71ba
7
- data.tar.gz: a412da0e9a0d8f765502a23e4aa6873116da0f4e978198eb115ef25efc8ae111177d563946d7a79cb9235f0b550315a4b5787534a01f5cefcb413ffb34b43861
6
+ metadata.gz: 27afe33758a33782b67f9f569e65a828304296c63f21f892b9f27413c71c7021fceb2e57e02c21ce3f7e9f9abcac444626d64aaf73743d7be3b4119cea4c7893
7
+ data.tar.gz: 72089305ac61d33065352316385def71c940d1578c7739df08a4ea27704b494576d8830703b462c078ebb0e5a1f61a39be381e2a34496868c1057d8281f511f9
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'console'
24
7
 
@@ -103,17 +86,21 @@ module Protocol
103
86
 
104
87
  status, headers, body = @app.call(env)
105
88
 
106
- return Response.wrap(status, headers, body, request)
89
+ headers, meta = self.wrap_headers(headers)
90
+
91
+ return Response.wrap(env, status, headers, meta, body, request)
107
92
  rescue => exception
108
93
  Console.logger.error(self) {exception}
109
94
 
110
95
  body&.close if body.respond_to?(:close)
111
-
96
+
97
+ env&.[](RACK_RESPONSE_FINISHED)&.each do |callback|
98
+ callback.call(env, status, headers, exception)
99
+ end
100
+
112
101
  return failure_response(exception)
113
102
  end
114
103
 
115
- private
116
-
117
104
  # Generate a suitable response for the given exception.
118
105
  # @parameter exception [Exception]
119
106
  # @returns [Protocol::HTTP::Response]
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'console'
24
7
 
@@ -50,6 +33,7 @@ module Protocol
50
33
  RACK_MULTITHREAD => false,
51
34
  RACK_MULTIPROCESS => true,
52
35
  RACK_RUN_ONCE => false,
36
+ RACK_IS_HIJACK => true,
53
37
 
54
38
  PROTOCOL_HTTP_REQUEST => request,
55
39
 
@@ -90,11 +74,57 @@ module Protocol
90
74
  return env
91
75
  end
92
76
 
77
+ # Build a rack `env` from the incoming request and apply it to the rack middleware.
78
+ #
79
+ # @parameter request [Protocol::HTTP::Request] The incoming request.
80
+ def call(request)
81
+ env = self.make_environment(request)
82
+
83
+ status, headers, body = @app.call(env)
84
+
85
+ headers, meta = self.wrap_headers(headers)
86
+
87
+ if hijack_body = meta[RACK_HIJACK]
88
+ body = hijack_body
89
+ end
90
+
91
+ return Response.wrap(env, status, headers, meta, body, request)
92
+ rescue => exception
93
+ Console.logger.error(self) {exception}
94
+
95
+ body&.close if body.respond_to?(:close)
96
+
97
+ return failure_response(exception)
98
+ end
99
+
100
+ # Process the rack response headers into into a {Protocol::HTTP::Headers} instance, along with any extra `rack.` metadata.
101
+ # @returns [Tuple(Protocol::HTTP::Headers, Hash)]
102
+ def wrap_headers(fields)
103
+ headers = ::Protocol::HTTP::Headers.new
104
+ meta = {}
105
+
106
+ fields.each do |key, value|
107
+ key = key.downcase
108
+
109
+ if key.start_with?('rack.')
110
+ meta[key] = value
111
+ else
112
+ value.split("\n").each do |value|
113
+ headers[key] = value
114
+ end
115
+ end
116
+ end
117
+
118
+ return headers, meta
119
+ end
120
+
93
121
  def self.make_response(env, response)
94
122
  # These interfaces should be largely compatible:
95
123
  headers = response.headers.to_h
124
+
96
125
  if protocol = response.protocol
97
126
  headers['rack.protocol'] = protocol
127
+ # headers['upgrade'] = protocol
98
128
  end
99
129
 
100
130
  if body = response.body and body.stream?
@@ -103,7 +133,11 @@ module Protocol
103
133
  body = []
104
134
  end
105
135
  end
106
-
136
+
137
+ headers.transform_values! do |value|
138
+ value.is_a?(Array) ? value.join("\n") : value
139
+ end
140
+
107
141
  [response.status, headers, body]
108
142
  end
109
143
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'console'
24
7
 
@@ -42,10 +25,13 @@ module Protocol
42
25
  RACK_INPUT => Input.new(request.body),
43
26
  RACK_ERRORS => $stderr,
44
27
  RACK_LOGGER => self.logger,
45
-
28
+
46
29
  # The request protocol, either from the upgrade header or the HTTP/2 pseudo header of the same name.
47
30
  RACK_PROTOCOL => request.protocol,
48
31
 
32
+ # The response finished callbacks:
33
+ RACK_RESPONSE_FINISHED => [],
34
+
49
35
  # The HTTP request method, such as “GET” or “POST”. This cannot ever be an empty string, and so is always required.
50
36
  CGI::REQUEST_METHOD => request.method,
51
37
 
@@ -56,7 +42,7 @@ module Protocol
56
42
  CGI::PATH_INFO => request_path,
57
43
  CGI::REQUEST_PATH => request_path,
58
44
  CGI::REQUEST_URI => request.path,
59
-
45
+
60
46
  # The portion of the request URL that follows the ?, if any. May be empty, but is always required!
61
47
  CGI::QUERY_STRING => query_string || '',
62
48
 
@@ -76,6 +62,29 @@ module Protocol
76
62
  return env
77
63
  end
78
64
 
65
+ # Process the rack response headers into into a {Protocol::HTTP::Headers} instance, along with any extra `rack.` metadata.
66
+ # @returns [Tuple(Protocol::HTTP::Headers, Hash)]
67
+ def wrap_headers(fields)
68
+ headers = ::Protocol::HTTP::Headers.new
69
+ meta = {}
70
+
71
+ fields.each do |key, value|
72
+ key = key.downcase
73
+
74
+ if key.start_with?('rack.')
75
+ meta[key] = value
76
+ elsif value.is_a?(Array)
77
+ value.each do |value|
78
+ headers[key] = value
79
+ end
80
+ else
81
+ headers[key] = value
82
+ end
83
+ end
84
+
85
+ return headers, meta
86
+ end
87
+
79
88
  def self.make_response(env, response)
80
89
  # These interfaces should be largely compatible:
81
90
  headers = response.headers.to_h
@@ -87,7 +96,7 @@ module Protocol
87
96
  # Force streaming response:
88
97
  body = body.method(:call)
89
98
  end
90
-
99
+
91
100
  [response.status, headers, body]
92
101
  end
93
102
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'rack'
24
7
 
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/body/readable'
24
7
  require 'protocol/http/body/file'
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/body/readable'
24
7
  require 'protocol/http/body/stream'
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/body/readable'
24
7
  require 'protocol/http/body/stream'
@@ -1,47 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require_relative 'body/streaming'
24
7
  require_relative 'body/enumerable'
8
+ require 'protocol/http/body/completable'
25
9
 
26
10
  module Protocol
27
11
  module Rack
28
12
  module Body
29
13
  CONTENT_LENGTH = 'content-length'
30
14
 
31
- def self.wrap(status, headers, body, input = nil)
15
+ def self.wrap(env, status, headers, body, input = nil)
32
16
  # In no circumstance do we want this header propagating out:
33
17
  if length = headers.delete(CONTENT_LENGTH)
34
18
  # We don't really trust the user to provide the right length to the transport.
35
19
  length = Integer(length)
36
20
  end
37
-
21
+
38
22
  # If we have an Async::HTTP body, we return it directly:
39
23
  if body.is_a?(::Protocol::HTTP::Body::Readable)
40
- return body
24
+ # Ignore.
41
25
  elsif status == 200 and body.respond_to?(:to_path)
42
26
  begin
43
27
  # Don't mangle partial responses (206)
44
- return ::Protocol::HTTP::Body::File.open(body.to_path).tap do
28
+ body = ::Protocol::HTTP::Body::File.open(body.to_path).tap do
45
29
  body.close if body.respond_to?(:close) # Close the original body.
46
30
  end
47
31
  rescue Errno::ENOENT
@@ -52,6 +36,20 @@ module Protocol
52
36
  else
53
37
  body = Body::Streaming.new(body, input)
54
38
  end
39
+
40
+ if response_finished = env[RACK_RESPONSE_FINISHED] and response_finished.any?
41
+ body = ::Protocol::HTTP::Body::Completable.new(body, completion_callback(response_finished, env, status, headers))
42
+ end
43
+
44
+ return body
45
+ end
46
+
47
+ def self.completion_callback(response_finished, env, status, headers)
48
+ proc do |error|
49
+ response_finished.each do |callback|
50
+ callback.call(env, status, headers, error)
51
+ end
52
+ end
55
53
  end
56
54
  end
57
55
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  module Protocol
24
7
  module Rack
@@ -51,5 +34,6 @@ module Protocol
51
34
  RACK_INPUT = 'rack.input'
52
35
  RACK_URL_SCHEME = 'rack.url_scheme'
53
36
  RACK_PROTOCOL = 'rack.protocol'
37
+ RACK_RESPONSE_FINISHED = 'rack.response_finished'
54
38
  end
55
39
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'async/io/buffer'
24
7
  require 'protocol/http/body/stream'
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/request'
24
7
  require 'protocol/http/headers'
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require_relative 'body'
24
7
  require_relative 'constants'
@@ -51,43 +34,23 @@ module Protocol
51
34
  'upgrade',
52
35
  ]
53
36
 
54
- # Process the rack response headers into into a {Protocol::HTTP::Headers} instance, along with any extra `rack.` metadata.
55
- # @returns [Tuple(Protocol::HTTP::Headers, Hash)]
56
- def self.wrap_headers(fields)
57
- headers = ::Protocol::HTTP::Headers.new
58
- meta = {}
59
-
60
- fields.each do |key, value|
61
- key = key.downcase
62
-
63
- if key.start_with?('rack.')
64
- meta[key] = value
65
- elsif value.is_a?(Array)
66
- value.each do |value|
67
- headers[key] = value
68
- end
69
- else
70
- headers[key] = value
71
- end
72
- end
73
-
74
- return headers, meta
75
- end
76
-
77
37
  # Wrap a rack response.
78
38
  # @parameter status [Integer] The rack response status.
79
39
  # @parameter headers [Duck(:each)] The rack response headers.
80
40
  # @parameter body [Duck(:each, :close) | Nil] The rack response body.
81
41
  # @parameter request [Protocol::HTTP::Request] The original request.
82
- def self.wrap(status, headers, body, request = nil)
83
- headers, meta = wrap_headers(headers)
84
-
42
+ def self.wrap(env, status, headers, meta, body, request = nil)
85
43
  ignored = headers.extract(HOP_HEADERS)
44
+
86
45
  unless ignored.empty?
87
46
  Console.logger.warn(self, "Ignoring protocol-level headers: #{ignored.inspect}")
88
47
  end
89
48
 
90
- body = Body.wrap(status, headers, body, request&.body)
49
+ if hijack_body = meta['rack.hijack']
50
+ body = hijack_body
51
+ end
52
+
53
+ body = Body.wrap(env, status, headers, body, request&.body)
91
54
 
92
55
  if request&.head?
93
56
  # I thought about doing this in Output.wrap, but decided the semantics are too tricky. Specifically, the various ways a rack response body can be wrapped, and the need to invoke #close at the right point.
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require 'protocol/http/body/rewindable'
24
7
  require 'protocol/http/middleware'
@@ -76,4 +59,4 @@ module Protocol
76
59
  end
77
60
  end
78
61
  end
79
- end
62
+ end
@@ -1,27 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2022, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  module Protocol
24
7
  module Rack
25
- VERSION = "0.1.5"
8
+ VERSION = "0.2.1"
26
9
  end
27
10
  end
data/lib/protocol/rack.rb CHANGED
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
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.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
22
5
 
23
6
  require_relative 'rack/version'
24
7
  require_relative 'rack/adapter'
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2022, by Samuel Williams.
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,77 @@
1
+ # Protocol::Rack
2
+
3
+ Provides abstractions for working with the Rack specification on top of [`Protocol::HTTP`](https://github.com/socketry/protocol-http). This would, in theory, allow you to run any `Protocol::HTTP` compatible application on top any rack-compatible server.
4
+
5
+ [![Development Status](https://github.com/socketry/protocol-rack/workflows/Test/badge.svg)](https://github.com/socketry/protocol-rack/actions?workflow=Test)
6
+
7
+ ## Features
8
+
9
+ - Supports Rack v2 and Rack v3 application adapters.
10
+ - Supports Rack environment to `Protocol::HTTP::Request` adapter.
11
+
12
+ ## Usage
13
+
14
+ ### Application Adapter
15
+
16
+ Given a rack application, you can adapt it for use on `async-http`:
17
+
18
+ ``` ruby
19
+ require 'async'
20
+ require 'async/http/server'
21
+ require 'async/http/client'
22
+ require 'async/http/endpoint'
23
+ require 'protocol/rack/adapter'
24
+
25
+ app = proc{|env| [200, {}, ["Hello World"]]}
26
+ middleware = Protocol::Rack::Adapter.new(app)
27
+
28
+ Async do
29
+ endpoint = Async::HTTP::Endpoint.parse("http://localhost:9292")
30
+
31
+ server_task = Async(transient: true) do
32
+ server = Async::HTTP::Server.new(middleware, endpoint)
33
+ server.run
34
+ end
35
+
36
+ client = Async::HTTP::Client.new(endpoint)
37
+ puts client.get("/").read
38
+ # "Hello World"
39
+ end
40
+ ```
41
+
42
+ ### Server Adapter
43
+
44
+ While not tested, in theory any Rack compatible server can host `Protocol::HTTP` compatible middlewares.
45
+
46
+ ``` ruby
47
+ require 'protocol/http/middleware'
48
+ require 'protocol/rack'
49
+
50
+ # Your native application:
51
+ middleware = Protocol::HTTP::Middleware::HelloWorld
52
+
53
+ run proc{|env|
54
+ # Convert the rack request to a compatible rich request object:
55
+ request = Protocol::Rack::Request[env]
56
+
57
+ # Call your application
58
+ response = middleware.call(request)
59
+
60
+ Protocol::Rack::Adapter.make_response(env, response)
61
+ }
62
+ ```
63
+
64
+ ## Contributing
65
+
66
+ We welcome contributions to this project.
67
+
68
+ 1. Fork it.
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
71
+ 4. Push to the branch (`git push origin my-new-feature`).
72
+ 5. Create new Pull Request.
73
+
74
+ ## See Also
75
+
76
+ - [protocol-http](https://github.com/socketry/protocol-http) — General abstractions for HTTP client/server implementations.
77
+ - [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client and server, supporting multiple HTTP protocols & TLS, which can host the Rack application adapters (and is used by this gem for testing).
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
39
  -----END CERTIFICATE-----
40
- date: 2022-08-22 00:00:00.000000000 Z
40
+ date: 2022-08-27 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: protocol-http
@@ -67,6 +67,90 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: async-http
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.59'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.59'
84
+ - !ruby/object:Gem::Dependency
85
+ name: bake-test
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: bake-test-external
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: covered
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: sus
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: 0.11.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 0.11.0
140
+ - !ruby/object:Gem::Dependency
141
+ name: sus-fixtures-async-http
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: 0.1.1
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: 0.1.1
70
154
  description:
71
155
  email:
72
156
  executables: []
@@ -88,6 +172,8 @@ files:
88
172
  - lib/protocol/rack/response.rb
89
173
  - lib/protocol/rack/rewindable.rb
90
174
  - lib/protocol/rack/version.rb
175
+ - license.md
176
+ - readme.md
91
177
  homepage: https://github.com/socketry/protocol-rack
92
178
  licenses:
93
179
  - MIT
metadata.gz.sig CHANGED
Binary file