protocol-rack 0.1.5 → 0.2.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
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