protocol-rack 0.17.0 → 0.18.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/context/getting-started.md +55 -0
- data/context/index.yaml +16 -0
- data/context/request-response.md +253 -0
- data/lib/protocol/rack/adapter/generic.rb +34 -10
- data/lib/protocol/rack/adapter/rack2.rb +2 -11
- data/lib/protocol/rack/body.rb +15 -4
- data/lib/protocol/rack/version.rb +1 -1
- data/readme.md +9 -0
- data/releases.md +5 -0
- data.tar.gz.sig +0 -0
- metadata +4 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4fed6d6b2ffc0dc007d343e8f9414af4c61cd7c321cb289b6d218290977feb7f
|
|
4
|
+
data.tar.gz: d02dd7e216b58d3bbe94e5e99b4c71d689ad8de5cb7451a67a81bcd0ade5a55a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df29bd96d8542e75e146d0eec4d7813f7e037fdd84e68bd08ac1f6a4cfca66b3ec176dd3167e31eedb3ae849b44059c23b0fe57a4aea8b4a2c3f55c90755b36f
|
|
7
|
+
data.tar.gz: 6969ef3c4a7fb95083dd57697c5bcf0aee57ec1f9eee6f0b4233af56e4845513c21480cee2abc14daf320d5cf7c5c739b50448bc3d3c6023432292a6544d8876
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
This guide explains how to get started with `protocol-rack` and integrate Rack applications with `Protocol::HTTP` servers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add the gem to your project:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
$ bundle add protocol-rack
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
`protocol-rack` provides a bridge between two HTTP ecosystems:
|
|
16
|
+
|
|
17
|
+
- **Rack**: The standard Ruby web server interface used by frameworks like Rails, Sinatra, and Roda.
|
|
18
|
+
- **`Protocol::HTTP`**: A modern, asynchronous HTTP protocol implementation used by servers like Falcon and Async.
|
|
19
|
+
|
|
20
|
+
The library enables bidirectional integration:
|
|
21
|
+
|
|
22
|
+
- **Application Adapter**: Run existing Rack applications on `Protocol::HTTP` servers (like Falcon).
|
|
23
|
+
- **Server Adapter**: Run `Protocol::HTTP` applications on Rack-compatible servers (like Puma).
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
The most common use case is running a Rack application on an asynchronous `Protocol::HTTP` server like [falcon](https://github.com/socketry/falcon). This allows you to leverage the performance benefits of async I/O while using your existing Rack-based application code.
|
|
28
|
+
|
|
29
|
+
### Running a Rack Application
|
|
30
|
+
|
|
31
|
+
When you have an existing Rack application (like a Rails app, Sinatra app, or any app that follows the Rack specification), you can adapt it to run on `Protocol::HTTP` servers:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
require "async"
|
|
35
|
+
require "async/http/server"
|
|
36
|
+
require "async/http/endpoint"
|
|
37
|
+
require "protocol/rack/adapter"
|
|
38
|
+
|
|
39
|
+
# Your existing Rack application:
|
|
40
|
+
app = proc do |env|
|
|
41
|
+
[200, {"content-type" => "text/plain"}, ["Hello World"]]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Create an adapter:
|
|
45
|
+
middleware = Protocol::Rack::Adapter.new(app)
|
|
46
|
+
|
|
47
|
+
# Run on an async server:
|
|
48
|
+
Async do
|
|
49
|
+
endpoint = Async::HTTP::Endpoint.parse("http://localhost:9292")
|
|
50
|
+
server = Async::HTTP::Server.new(middleware, endpoint)
|
|
51
|
+
server.run
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The adapter automatically detects your Rack version (v2, v3, or v3.1+) and uses the appropriate implementation, ensuring compatibility without any configuration.
|
data/context/index.yaml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Automatically generated context index for Utopia::Project guides.
|
|
2
|
+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
|
|
3
|
+
---
|
|
4
|
+
description: An implementation of the Rack protocol/specification.
|
|
5
|
+
metadata:
|
|
6
|
+
documentation_uri: https://socketry.github.io/protocol-rack/
|
|
7
|
+
source_code_uri: https://github.com/socketry/protocol-rack.git
|
|
8
|
+
files:
|
|
9
|
+
- path: getting-started.md
|
|
10
|
+
title: Getting Started
|
|
11
|
+
description: This guide explains how to get started with `protocol-rack` and integrate
|
|
12
|
+
Rack applications with `Protocol::HTTP` servers.
|
|
13
|
+
- path: request-response.md
|
|
14
|
+
title: Request and Response Handling
|
|
15
|
+
description: This guide explains how to work with requests and responses when bridging
|
|
16
|
+
between Rack and `Protocol::HTTP`, covering advanced use cases and edge cases.
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Request and Response Handling
|
|
2
|
+
|
|
3
|
+
This guide explains how to work with requests and responses when bridging between Rack and `Protocol::HTTP`, covering advanced use cases and edge cases.
|
|
4
|
+
|
|
5
|
+
## Request Conversion
|
|
6
|
+
|
|
7
|
+
The {ruby Protocol::Rack::Request} class converts Rack environment hashes into rich `Protocol::HTTP` request objects, providing access to modern HTTP features while maintaining compatibility with Rack.
|
|
8
|
+
|
|
9
|
+
### Basic Request Access
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require "protocol/rack/request"
|
|
13
|
+
|
|
14
|
+
run do |env|
|
|
15
|
+
request = Protocol::Rack::Request[env]
|
|
16
|
+
|
|
17
|
+
# Access request properties:
|
|
18
|
+
puts request.method # "GET", "POST", etc.
|
|
19
|
+
puts request.path # "/users/123"
|
|
20
|
+
puts request.url_scheme # "http" or "https"
|
|
21
|
+
puts request.authority # "example.com:80"
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Headers
|
|
26
|
+
|
|
27
|
+
Headers are automatically extracted from Rack's `HTTP_*` environment variables:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
run do |env|
|
|
31
|
+
request = Protocol::Rack::Request[env]
|
|
32
|
+
|
|
33
|
+
# Headers are available as a `Protocol::HTTP::Headers` object:
|
|
34
|
+
user_agent = request.headers["user-agent"]
|
|
35
|
+
content_type = request.headers["content-type"]
|
|
36
|
+
|
|
37
|
+
# Headers are case-insensitive:
|
|
38
|
+
user_agent = request.headers["User-Agent"] # Same as above
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The adapter converts Rack's `HTTP_ACCEPT_ENCODING` format to standard HTTP header names (`accept-encoding`).
|
|
43
|
+
|
|
44
|
+
### Request Body
|
|
45
|
+
|
|
46
|
+
The request body is wrapped in a `Protocol::HTTP`-compatible interface:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
run do |env|
|
|
50
|
+
request = Protocol::Rack::Request[env]
|
|
51
|
+
|
|
52
|
+
# Read the entire body:
|
|
53
|
+
body = request.body.read
|
|
54
|
+
|
|
55
|
+
# Or stream it:
|
|
56
|
+
request.body.each do |chunk|
|
|
57
|
+
process_chunk(chunk)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# The body supports rewind if the underlying Rack input supports it:
|
|
61
|
+
request.body.rewind
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The body wrapper handles Rack's `rack.input` interface, which may or may not support `rewind` depending on the server.
|
|
66
|
+
|
|
67
|
+
### Query Parameters
|
|
68
|
+
|
|
69
|
+
Query parameters are parsed from the request path:
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
run do |env|
|
|
73
|
+
request = Protocol::Rack::Request[env]
|
|
74
|
+
|
|
75
|
+
# Access query string:
|
|
76
|
+
query = request.query # "name=value&other=123"
|
|
77
|
+
|
|
78
|
+
# Parse query parameters (if using a helper):
|
|
79
|
+
params = URI.decode_www_form(query).to_h
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Protocol Upgrades
|
|
84
|
+
|
|
85
|
+
The adapter handles protocol upgrade requests (like WebSockets):
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
run do |env|
|
|
89
|
+
request = Protocol::Rack::Request[env]
|
|
90
|
+
|
|
91
|
+
# Check for upgrade protocols:
|
|
92
|
+
if protocols = request.protocol
|
|
93
|
+
# protocols is an array: ["websocket"]:
|
|
94
|
+
if protocols.include?("websocket")
|
|
95
|
+
# Handle WebSocket upgrade.
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Protocols are extracted from either `rack.protocol` or the `HTTP_UPGRADE` header.
|
|
102
|
+
|
|
103
|
+
## Response Conversion
|
|
104
|
+
|
|
105
|
+
The {ruby Protocol::Rack::Response} class and {ruby Protocol::Rack::Adapter.make_response} handle converting `Protocol::HTTP` responses back to Rack format.
|
|
106
|
+
|
|
107
|
+
### Basic Response
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
require "protocol/rack/adapter"
|
|
111
|
+
|
|
112
|
+
run do |env|
|
|
113
|
+
request = Protocol::Rack::Request[env]
|
|
114
|
+
|
|
115
|
+
# Create a `Protocol::HTTP` response:
|
|
116
|
+
response = Protocol::HTTP::Response[
|
|
117
|
+
200,
|
|
118
|
+
{"content-type" => "text/html"},
|
|
119
|
+
["<h1>Hello</h1>"]
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
# Convert to Rack format:
|
|
123
|
+
Protocol::Rack::Adapter.make_response(env, response)
|
|
124
|
+
end
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Response Bodies
|
|
128
|
+
|
|
129
|
+
The adapter handles different types of response bodies:
|
|
130
|
+
|
|
131
|
+
#### Enumerable Bodies
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
# Array bodies:
|
|
135
|
+
response = Protocol::HTTP::Response[
|
|
136
|
+
200,
|
|
137
|
+
{"content-type" => "text/plain"},
|
|
138
|
+
["Hello", " ", "World"]
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
# Enumerable bodies:
|
|
142
|
+
response = Protocol::HTTP::Response[
|
|
143
|
+
200,
|
|
144
|
+
{"content-type" => "text/plain"},
|
|
145
|
+
Enumerator.new do |yielder|
|
|
146
|
+
yielder << "Chunk 1\n"
|
|
147
|
+
yielder << "Chunk 2\n"
|
|
148
|
+
end
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Streaming Bodies
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
# Streaming response body:
|
|
156
|
+
body = Protocol::HTTP::Body::Buffered.new(["Streaming content"])
|
|
157
|
+
|
|
158
|
+
response = Protocol::HTTP::Response[
|
|
159
|
+
200,
|
|
160
|
+
{"content-type" => "text/plain"},
|
|
161
|
+
body
|
|
162
|
+
]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### File Bodies
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
# File-based responses:
|
|
169
|
+
body = Protocol::HTTP::Body::File.open("path/to/file.txt")
|
|
170
|
+
|
|
171
|
+
response = Protocol::HTTP::Response[
|
|
172
|
+
200,
|
|
173
|
+
{"content-type" => "text/plain"},
|
|
174
|
+
body
|
|
175
|
+
]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### HEAD Requests
|
|
179
|
+
|
|
180
|
+
The adapter automatically handles HEAD requests by removing response bodies:
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
run do |env|
|
|
184
|
+
request = Protocol::Rack::Request[env]
|
|
185
|
+
|
|
186
|
+
# Create a response with a body:
|
|
187
|
+
response = Protocol::HTTP::Response[
|
|
188
|
+
200,
|
|
189
|
+
{"content-type" => "text/html"},
|
|
190
|
+
["<h1>Full Response</h1>"]
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
# For HEAD requests, the body is automatically removed:
|
|
194
|
+
Protocol::Rack::Adapter.make_response(env, response)
|
|
195
|
+
end
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Status Codes Without Bodies
|
|
199
|
+
|
|
200
|
+
Certain status codes (204 No Content, 205 Reset Content, 304 Not Modified) should not include response bodies. The adapter handles this automatically:
|
|
201
|
+
|
|
202
|
+
```ruby
|
|
203
|
+
response = Protocol::HTTP::Response[
|
|
204
|
+
204, # No Content
|
|
205
|
+
{},
|
|
206
|
+
["This body will be removed"]
|
|
207
|
+
]
|
|
208
|
+
|
|
209
|
+
# The adapter automatically removes the body for 204 responses.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Rack-Specific Features
|
|
213
|
+
|
|
214
|
+
#### Hijacking
|
|
215
|
+
|
|
216
|
+
Rack supports response hijacking, which allows taking over the connection:
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
# In a Rack application:
|
|
220
|
+
[200, {"rack.hijack" => proc{|io| io.write("Hijacked!")}}, []]
|
|
221
|
+
|
|
222
|
+
# The adapter handles hijacking automatically using streaming responses.
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Response Finished Callbacks
|
|
226
|
+
|
|
227
|
+
Rack 2+ supports `rack.response_finished` callbacks:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
env["rack.response_finished"] ||= []
|
|
231
|
+
env["rack.response_finished"] << proc do |env, status, headers, error|
|
|
232
|
+
# Cleanup or logging after response is sent
|
|
233
|
+
puts "Response finished: #{status}"
|
|
234
|
+
end
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The adapter invokes these callbacks in reverse order of registration, as specified by the Rack specification.
|
|
238
|
+
|
|
239
|
+
### Hop Headers
|
|
240
|
+
|
|
241
|
+
HTTP hop-by-hop headers (like `Connection`, `Transfer-Encoding`) are automatically removed from responses, as they should not be forwarded through proxies:
|
|
242
|
+
|
|
243
|
+
```ruby
|
|
244
|
+
response = Protocol::HTTP::Response[
|
|
245
|
+
200,
|
|
246
|
+
{
|
|
247
|
+
"content-type" => "text/plain",
|
|
248
|
+
"connection" => "close", # This will be removed
|
|
249
|
+
"transfer-encoding" => "chunked" # This will be removed
|
|
250
|
+
},
|
|
251
|
+
["Body"]
|
|
252
|
+
]
|
|
253
|
+
```
|
|
@@ -135,6 +135,38 @@ module Protocol
|
|
|
135
135
|
}
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
# Handle errors that occur during request processing. Logs the error, closes any response body, invokes `rack.response_finished` callbacks, and returns an appropriate failure response.
|
|
139
|
+
#
|
|
140
|
+
# The `rack.response_finished` callbacks are invoked in reverse order of registration, as specified by the Rack specification. If a callback raises an exception, it is caught and logged, but does not prevent other callbacks from being invoked.
|
|
141
|
+
#
|
|
142
|
+
# @parameter env [Hash] The Rack environment hash.
|
|
143
|
+
# @parameter status [Integer | Nil] The HTTP status code, if available. May be `nil` if the error occurred before the application returned a response.
|
|
144
|
+
# @parameter headers [Hash | Nil] The response headers, if available. May be `nil` if the error occurred before the application returned a response.
|
|
145
|
+
# @parameter body [Object | Nil] The response body, if available. May be `nil` if the error occurred before the application returned a response.
|
|
146
|
+
# @parameter error [Exception] The exception that occurred during request processing.
|
|
147
|
+
# @returns [Protocol::HTTP::Response] A failure response representing the error.
|
|
148
|
+
def handle_error(env, status, headers, body, error)
|
|
149
|
+
Console.error(self, "Error occurred during request processing:", error)
|
|
150
|
+
|
|
151
|
+
# Close the response body if it exists and supports closing.
|
|
152
|
+
body&.close if body.respond_to?(:close)
|
|
153
|
+
|
|
154
|
+
# Invoke `rack.response_finished` callbacks in reverse order of registration.
|
|
155
|
+
# This ensures that callbacks registered later are invoked first, matching the Rack specification.
|
|
156
|
+
env&.[](RACK_RESPONSE_FINISHED)&.reverse_each do |callback|
|
|
157
|
+
begin
|
|
158
|
+
callback.call(env, status, headers, error)
|
|
159
|
+
rescue => callback_error
|
|
160
|
+
# If a callback raises an exception, log it but continue invoking other callbacks.
|
|
161
|
+
# The Rack specification states that callbacks should not raise exceptions, but we handle
|
|
162
|
+
# this gracefully to prevent one misbehaving callback from breaking others.
|
|
163
|
+
Console.error(self, "Error occurred during response finished callback:", callback_error)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
return failure_response(error)
|
|
168
|
+
end
|
|
169
|
+
|
|
138
170
|
# Build a rack `env` from the incoming request and apply it to the rack middleware.
|
|
139
171
|
#
|
|
140
172
|
# @parameter request [Protocol::HTTP::Request] The incoming request.
|
|
@@ -158,16 +190,8 @@ module Protocol
|
|
|
158
190
|
headers, meta = self.wrap_headers(headers)
|
|
159
191
|
|
|
160
192
|
return Response.wrap(env, status, headers, meta, body, request)
|
|
161
|
-
rescue =>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
body&.close if body.respond_to?(:close)
|
|
165
|
-
|
|
166
|
-
env&.[](RACK_RESPONSE_FINISHED)&.each do |callback|
|
|
167
|
-
callback.call(env, status, headers, exception)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
return failure_response(exception)
|
|
193
|
+
rescue => error
|
|
194
|
+
return self.handle_error(env, status, headers, body, error)
|
|
171
195
|
end
|
|
172
196
|
|
|
173
197
|
# Generate a suitable response for the given exception.
|
|
@@ -111,17 +111,8 @@ module Protocol
|
|
|
111
111
|
# end
|
|
112
112
|
|
|
113
113
|
return Response.wrap(env, status, headers, meta, body, request)
|
|
114
|
-
rescue =>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
body&.close if body.respond_to?(:close)
|
|
118
|
-
|
|
119
|
-
# Rack 2 does not include `rack.response_finished` in the specification. However, if the application has set it, we will call the callbacks here as it would be extremely surprising to not do so.
|
|
120
|
-
env&.[](RACK_RESPONSE_FINISHED)&.each do |callback|
|
|
121
|
-
callback.call(env, status, headers, exception)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
return failure_response(exception)
|
|
114
|
+
rescue => error
|
|
115
|
+
return self.handle_error(env, status, headers, body, error)
|
|
125
116
|
end
|
|
126
117
|
|
|
127
118
|
# Process the rack response headers into a {Protocol::HTTP::Headers} instance, along with any extra `rack.` metadata.
|
data/lib/protocol/rack/body.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative "body/streaming"
|
|
|
7
7
|
require_relative "body/enumerable"
|
|
8
8
|
require_relative "constants"
|
|
9
9
|
|
|
10
|
+
require "console"
|
|
10
11
|
require "protocol/http/body/completable"
|
|
11
12
|
require "protocol/http/body/head"
|
|
12
13
|
|
|
@@ -103,8 +104,10 @@ module Protocol
|
|
|
103
104
|
return body
|
|
104
105
|
end
|
|
105
106
|
|
|
106
|
-
# Create a completion callback for response finished handlers.
|
|
107
|
-
#
|
|
107
|
+
# Create a completion callback for response finished handlers. The callback is called with any error that occurred during response processing.
|
|
108
|
+
#
|
|
109
|
+
# Callbacks are invoked in reverse order of registration, as specified by the Rack specification.
|
|
110
|
+
# If a callback raises an exception, it is caught and logged, but does not prevent other callbacks from being invoked.
|
|
108
111
|
#
|
|
109
112
|
# @parameter response_finished [Array] Array of response finished callbacks.
|
|
110
113
|
# @parameter env [Hash] The Rack environment.
|
|
@@ -113,8 +116,16 @@ module Protocol
|
|
|
113
116
|
# @returns [Proc] A callback that calls all response finished handlers.
|
|
114
117
|
def self.completion_callback(response_finished, env, status, headers)
|
|
115
118
|
proc do |error|
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
# Invoke callbacks in reverse order of registration, as specified by the Rack specification.
|
|
120
|
+
response_finished.reverse_each do |callback|
|
|
121
|
+
begin
|
|
122
|
+
callback.call(env, status, headers, error)
|
|
123
|
+
rescue => callback_error
|
|
124
|
+
# If a callback raises an exception, log it but continue invoking other callbacks.
|
|
125
|
+
# The Rack specification states that callbacks should not raise exceptions, but we handle
|
|
126
|
+
# this gracefully to prevent one misbehaving callback from breaking others.
|
|
127
|
+
Console.error(self, "Error occurred during response finished callback:", callback_error)
|
|
128
|
+
end
|
|
118
129
|
end
|
|
119
130
|
end
|
|
120
131
|
end
|
data/readme.md
CHANGED
|
@@ -13,6 +13,10 @@ Provides abstractions for working with the Rack specification on top of [`Protoc
|
|
|
13
13
|
|
|
14
14
|
Please see the [project documentation](https://socketry.github.io/protocol-rack/) for more details.
|
|
15
15
|
|
|
16
|
+
- [Getting Started](https://socketry.github.io/protocol-rack/guides/getting-started/index) - This guide explains how to get started with `protocol-rack` and integrate Rack applications with `Protocol::HTTP` servers.
|
|
17
|
+
|
|
18
|
+
- [Request and Response Handling](https://socketry.github.io/protocol-rack/guides/request-response/index) - This guide explains how to work with requests and responses when bridging between Rack and `Protocol::HTTP`, covering advanced use cases and edge cases.
|
|
19
|
+
|
|
16
20
|
### Application Adapter
|
|
17
21
|
|
|
18
22
|
Given a rack application, you can adapt it for use on `async-http`:
|
|
@@ -67,6 +71,11 @@ end
|
|
|
67
71
|
|
|
68
72
|
Please see the [project releases](https://socketry.github.io/protocol-rack/releases/index) for all releases.
|
|
69
73
|
|
|
74
|
+
### v0.18.0
|
|
75
|
+
|
|
76
|
+
- Correctly invoke `rack.response_finished` in reverse order.
|
|
77
|
+
- Tolerate errors during `rack.response_finished` callbacks.
|
|
78
|
+
|
|
70
79
|
### v0.17.0
|
|
71
80
|
|
|
72
81
|
- Support `rack.response_finished` in Rack 2 if it's present in the environment.
|
data/releases.md
CHANGED
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.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -86,6 +86,9 @@ executables: []
|
|
|
86
86
|
extensions: []
|
|
87
87
|
extra_rdoc_files: []
|
|
88
88
|
files:
|
|
89
|
+
- context/getting-started.md
|
|
90
|
+
- context/index.yaml
|
|
91
|
+
- context/request-response.md
|
|
89
92
|
- lib/protocol/rack.rb
|
|
90
93
|
- lib/protocol/rack/adapter.rb
|
|
91
94
|
- lib/protocol/rack/adapter/generic.rb
|
metadata.gz.sig
CHANGED
|
Binary file
|