itsi 0.2.16 → 0.2.17
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
- data/CHANGELOG.md +13 -0
- data/Cargo.lock +4 -2
- data/crates/itsi_acme/Cargo.toml +1 -1
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.toml +3 -1
- data/crates/itsi_server/src/lib.rs +6 -1
- data/crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +2 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_call.rs +4 -4
- data/crates/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +14 -13
- data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +64 -33
- data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +151 -152
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +6 -15
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +26 -5
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -1
- data/crates/itsi_server/src/server/binds/listener.rs +45 -7
- data/crates/itsi_server/src/server/frame_stream.rs +142 -0
- data/crates/itsi_server/src/server/http_message_types.rs +142 -9
- data/crates/itsi_server/src/server/io_stream.rs +28 -5
- data/crates/itsi_server/src/server/lifecycle_event.rs +1 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +8 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +3 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +54 -56
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +5 -7
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +5 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +7 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +1 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +4 -6
- data/crates/itsi_server/src/server/mod.rs +1 -0
- data/crates/itsi_server/src/server/process_worker.rs +3 -4
- data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +16 -12
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +87 -31
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +158 -142
- data/crates/itsi_server/src/server/signal.rs +37 -9
- data/crates/itsi_server/src/server/thread_worker.rs +84 -69
- data/crates/itsi_server/src/services/itsi_http_service.rs +43 -43
- data/crates/itsi_server/src/services/static_file_server.rs +28 -47
- data/docs/benchmark-dashboard/.gitignore +27 -0
- data/docs/benchmark-dashboard/app/api/benchmarks/route.ts +22 -0
- data/docs/benchmark-dashboard/app/globals.css +94 -0
- data/docs/benchmark-dashboard/app/layout.tsx +20 -0
- data/docs/benchmark-dashboard/app/page.tsx +252 -0
- data/docs/benchmark-dashboard/components/benchmark-dashboard.tsx +1663 -0
- data/docs/benchmark-dashboard/components/theme-provider.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/accordion.tsx +58 -0
- data/docs/benchmark-dashboard/components/ui/alert-dialog.tsx +141 -0
- data/docs/benchmark-dashboard/components/ui/alert.tsx +59 -0
- data/docs/benchmark-dashboard/components/ui/aspect-ratio.tsx +7 -0
- data/docs/benchmark-dashboard/components/ui/avatar.tsx +50 -0
- data/docs/benchmark-dashboard/components/ui/badge.tsx +36 -0
- data/docs/benchmark-dashboard/components/ui/breadcrumb.tsx +115 -0
- data/docs/benchmark-dashboard/components/ui/button.tsx +56 -0
- data/docs/benchmark-dashboard/components/ui/calendar.tsx +66 -0
- data/docs/benchmark-dashboard/components/ui/card.tsx +79 -0
- data/docs/benchmark-dashboard/components/ui/carousel.tsx +262 -0
- data/docs/benchmark-dashboard/components/ui/chart.tsx +365 -0
- data/docs/benchmark-dashboard/components/ui/checkbox.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/collapsible.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/command.tsx +153 -0
- data/docs/benchmark-dashboard/components/ui/context-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/dialog.tsx +122 -0
- data/docs/benchmark-dashboard/components/ui/drawer.tsx +118 -0
- data/docs/benchmark-dashboard/components/ui/dropdown-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/form.tsx +178 -0
- data/docs/benchmark-dashboard/components/ui/hover-card.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/input-otp.tsx +71 -0
- data/docs/benchmark-dashboard/components/ui/input.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/label.tsx +26 -0
- data/docs/benchmark-dashboard/components/ui/loading-spinner.tsx +12 -0
- data/docs/benchmark-dashboard/components/ui/menubar.tsx +236 -0
- data/docs/benchmark-dashboard/components/ui/navigation-menu.tsx +128 -0
- data/docs/benchmark-dashboard/components/ui/pagination.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/popover.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/progress.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/radio-group.tsx +44 -0
- data/docs/benchmark-dashboard/components/ui/resizable.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/scroll-area.tsx +48 -0
- data/docs/benchmark-dashboard/components/ui/select.tsx +160 -0
- data/docs/benchmark-dashboard/components/ui/separator.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/sheet.tsx +140 -0
- data/docs/benchmark-dashboard/components/ui/sidebar.tsx +763 -0
- data/docs/benchmark-dashboard/components/ui/skeleton.tsx +15 -0
- data/docs/benchmark-dashboard/components/ui/slider.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/sonner.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/switch.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/table.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/tabs.tsx +55 -0
- data/docs/benchmark-dashboard/components/ui/textarea.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/toast.tsx +129 -0
- data/docs/benchmark-dashboard/components/ui/toaster.tsx +35 -0
- data/docs/benchmark-dashboard/components/ui/toggle-group.tsx +61 -0
- data/docs/benchmark-dashboard/components/ui/toggle.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/tooltip.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/components/ui/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/components.json +21 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.css +1 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.iife.js +211 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.png +0 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.svg +1 -0
- data/docs/benchmark-dashboard/dist/placeholder-user.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.svg +1 -0
- data/docs/benchmark-dashboard/embed.tsx +13 -0
- data/docs/benchmark-dashboard/hooks/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/hooks/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/lib/benchmark-utils.ts +54 -0
- data/docs/benchmark-dashboard/lib/utils.ts +6 -0
- data/docs/benchmark-dashboard/next.config.mjs +14 -0
- data/docs/benchmark-dashboard/package-lock.json +5859 -0
- data/docs/benchmark-dashboard/package.json +72 -0
- data/docs/benchmark-dashboard/pnpm-lock.yaml +5 -0
- data/docs/benchmark-dashboard/postcss.config.mjs +8 -0
- data/docs/benchmark-dashboard/styles/globals.css +94 -0
- data/docs/benchmark-dashboard/tailwind.config.ts +96 -0
- data/docs/benchmark-dashboard/tsconfig.json +27 -0
- data/docs/benchmark-dashboard/vite.config.ts +24 -0
- data/docs/build.rb +52 -0
- data/docs/content/benchmarks/index.md +96 -0
- data/docs/content/getting_started/_index.md +76 -46
- data/docs/hugo.yaml +3 -0
- data/docs/static/results.json +1 -0
- data/docs/static/scripts/benchmark-dashboard.iife.js +211 -0
- data/docs/static/styles/benchmark-dashboard.css +1 -0
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +3 -1
- data/gems/server/exe/itsi +6 -1
- data/gems/server/lib/itsi/http_request.rb +31 -39
- data/gems/server/lib/itsi/http_response.rb +5 -0
- data/gems/server/lib/itsi/rack_env_pool.rb +59 -0
- data/gems/server/lib/itsi/server/config/dsl.rb +5 -4
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +1 -1
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +2 -2
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +6 -2
- data/gems/server/lib/itsi/server/config/options/include.rb +5 -2
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.md +16 -0
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/writev.md +25 -0
- data/gems/server/lib/itsi/server/config/options/writev.rb +19 -0
- data/gems/server/lib/itsi/server/config.rb +21 -8
- data/gems/server/lib/itsi/server/default_config/Itsi.rb +1 -4
- data/gems/server/lib/itsi/server/grpc/grpc_call.rb +2 -0
- data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +2 -2
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -1
- data/gems/server/lib/itsi/server/rack_interface.rb +17 -12
- data/gems/server/lib/itsi/server/scheduler_interface.rb +2 -0
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +1 -0
- data/gems/server/lib/ruby_lsp/itsi/addon.rb +12 -13
- data/gems/server/test/helpers/test_helper.rb +12 -13
- data/gems/server/test/middleware/grpc/grpc.rb +13 -14
- data/gems/server/test/middleware/grpc/test_service_impl.rb +3 -3
- data/gems/server/test/middleware/proxy.rb +262 -268
- data/lib/itsi/version.rb +1 -1
- metadata +96 -6
- data/tasks.txt +0 -28
@@ -1,16 +1,14 @@
|
|
1
1
|
require_relative "../helpers/test_helper"
|
2
2
|
|
3
3
|
class TestProxy < Minitest::Test
|
4
|
-
|
5
4
|
def test_successful_forwarding
|
6
|
-
|
7
5
|
backend_bind = free_bind
|
8
6
|
server(
|
9
7
|
itsi_rb: lambda do
|
10
|
-
log_requests before: { format: "GET {path_and_query}", level: "INFO"}
|
11
|
-
get("/foo")
|
8
|
+
log_requests before: { format: "GET {path_and_query}", level: "INFO" }
|
9
|
+
get("/foo") do |r|
|
12
10
|
r.ok "backend success. #{r.query_params["bar"]}"
|
13
|
-
|
11
|
+
end
|
14
12
|
end,
|
15
13
|
bind: backend_bind
|
16
14
|
) do
|
@@ -25,9 +23,9 @@ class TestProxy < Minitest::Test
|
|
25
23
|
timeout: 30,
|
26
24
|
tls_sni: false,
|
27
25
|
error_response: "internal_server_error"
|
28
|
-
get("/foo")
|
26
|
+
get("/foo") do |r|
|
29
27
|
r.ok "should not get here"
|
30
|
-
|
28
|
+
end
|
31
29
|
end
|
32
30
|
) do
|
33
31
|
res = get_resp("/foo?bar=baz")
|
@@ -60,11 +58,10 @@ class TestProxy < Minitest::Test
|
|
60
58
|
end
|
61
59
|
|
62
60
|
def test_overriding_headers
|
63
|
-
|
64
61
|
backend_bind = free_bind
|
65
62
|
server(
|
66
63
|
itsi_rb: lambda do
|
67
|
-
log_requests before: { format: "GET {path_and_query}", level: "INFO"}
|
64
|
+
log_requests before: { format: "GET {path_and_query}", level: "INFO" }
|
68
65
|
get("/header-test") do |r|
|
69
66
|
# Return the incoming header value.
|
70
67
|
r.ok r.header("X-Forwarded-For").first
|
@@ -72,7 +69,6 @@ class TestProxy < Minitest::Test
|
|
72
69
|
end,
|
73
70
|
bind: backend_bind
|
74
71
|
) do
|
75
|
-
|
76
72
|
# Start proxy server.
|
77
73
|
server(
|
78
74
|
itsi_rb: lambda do
|
@@ -96,278 +92,279 @@ class TestProxy < Minitest::Test
|
|
96
92
|
end
|
97
93
|
|
98
94
|
def test_proxy_with_static_to_only
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
95
|
+
backend_bind = free_bind
|
96
|
+
server(
|
97
|
+
itsi_rb: lambda do
|
98
|
+
get("/static") { |r| r.ok "static response" }
|
99
|
+
end,
|
100
|
+
bind: backend_bind
|
101
|
+
) do
|
102
|
+
server(
|
103
|
+
itsi_rb: lambda do
|
104
|
+
proxy \
|
105
|
+
to: "#{backend_bind}{path}{query}",
|
106
|
+
backend_priority: "round_robin",
|
107
|
+
headers: {},
|
108
|
+
verify_ssl: false,
|
109
|
+
timeout: 30,
|
110
|
+
tls_sni: false,
|
111
|
+
error_response: "internal_server_error"
|
112
|
+
get("/static") { |r| r.ok "should not get here" }
|
113
|
+
end
|
114
|
+
) do
|
115
|
+
res = get_resp("/static")
|
116
|
+
assert_equal "200", res.code, "Expected success status from static 'to' URL"
|
117
|
+
assert_equal "static response", res.body
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
125
121
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
122
|
+
def test_proxy_with_backend_host_override
|
123
|
+
backend_bind1 = free_bind
|
124
|
+
backend_bind2 = free_bind
|
125
|
+
# Start two dummy backends that respond with their Host header.
|
126
|
+
thread1 = Thread.new do
|
127
|
+
server(
|
128
|
+
itsi_rb: lambda do
|
129
|
+
get("/host-test") { |r| r.ok r.header("Host").first }
|
130
|
+
end,
|
131
|
+
bind: backend_bind1
|
132
|
+
) { sleep 1 }
|
133
|
+
end
|
134
|
+
thread2 = Thread.new do
|
135
|
+
server(
|
136
|
+
itsi_rb: lambda do
|
137
|
+
get("/host-test") { |r| r.ok r.header("Host").first }
|
138
|
+
end,
|
139
|
+
bind: backend_bind2
|
140
|
+
) { sleep 1 }
|
141
|
+
end
|
146
142
|
|
147
|
-
|
143
|
+
sleep 0.1
|
148
144
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
145
|
+
server(
|
146
|
+
itsi_rb: lambda do
|
147
|
+
proxy \
|
148
|
+
to: "#{backend_bind1}{path}{query}",
|
149
|
+
backends: ["#{backend_bind1}", "#{backend_bind2}"],
|
150
|
+
backend_priority: "round_robin",
|
151
|
+
headers: { "Host" => "custom.backend.example.com" },
|
152
|
+
verify_ssl: false,
|
153
|
+
timeout: 30,
|
154
|
+
tls_sni: true,
|
155
|
+
error_response: "internal_server_error"
|
156
|
+
get("/host-test") { |r| r.ok "should not get here" }
|
157
|
+
end
|
158
|
+
) do
|
159
|
+
res = get_resp("/host-test")
|
160
|
+
assert_equal "200", res.code, "Expected successful response with host override"
|
161
|
+
assert_equal "custom.backend.example.com", res.body, "Expected the Host header to be overridden"
|
162
|
+
end
|
167
163
|
|
168
|
-
|
169
|
-
|
170
|
-
|
164
|
+
thread1.kill
|
165
|
+
thread2.kill
|
166
|
+
end
|
171
167
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
168
|
+
def test_proxy_timeout
|
169
|
+
backend_bind = free_bind
|
170
|
+
# Start a backend server that sleeps for 1 second before responding.
|
171
|
+
server(
|
172
|
+
itsi_rb: lambda do
|
173
|
+
get("/slow") do |r|
|
174
|
+
sleep 1
|
175
|
+
r.ok "delayed response"
|
176
|
+
end
|
177
|
+
end,
|
178
|
+
bind: backend_bind
|
179
|
+
) do
|
180
|
+
server(
|
181
|
+
itsi_rb: lambda do
|
182
|
+
# Set a very short timeout (0 seconds) to force a timeout.
|
183
|
+
proxy \
|
184
|
+
to: "#{backend_bind}{path}{query}",
|
185
|
+
backends: ["#{backend_bind}"],
|
186
|
+
backend_priority: "round_robin",
|
187
|
+
headers: {},
|
188
|
+
verify_ssl: false,
|
189
|
+
timeout: 0,
|
190
|
+
tls_sni: false,
|
191
|
+
error_response: "gateway_timeout"
|
192
|
+
get("/slow") { |r| r.ok "should not get here" }
|
193
|
+
end
|
194
|
+
) do
|
195
|
+
res = get_resp("/slow")
|
196
|
+
assert_equal "504", res.code, "Expected 504 Gateway Timeout when backend response exceeds timeout"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
204
200
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
201
|
+
def test_error_response_internal_server_error
|
202
|
+
server(
|
203
|
+
itsi_rb: lambda do
|
204
|
+
proxy \
|
205
|
+
to: "invalid_url",
|
206
|
+
backends: ["127.0.0.1:3001"],
|
207
|
+
backend_priority: "round_robin",
|
208
|
+
headers: {},
|
209
|
+
verify_ssl: false,
|
210
|
+
timeout: 30,
|
211
|
+
tls_sni: false,
|
212
|
+
error_response: "internal_server_error"
|
213
|
+
get("/foo") { |r| r.ok "should not get here" }
|
214
|
+
end
|
215
|
+
) do
|
216
|
+
res = get_resp("/foo")
|
217
|
+
assert_equal "500", res.code, "Expected error response code 500 for internal_server_error"
|
218
|
+
end
|
219
|
+
end
|
224
220
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
221
|
+
def test_error_response_not_found
|
222
|
+
server(
|
223
|
+
itsi_rb: lambda do
|
224
|
+
proxy \
|
225
|
+
to: "invalid_url",
|
226
|
+
backends: ["127.0.0.1:3001"],
|
227
|
+
backend_priority: "round_robin",
|
228
|
+
headers: {},
|
229
|
+
verify_ssl: false,
|
230
|
+
timeout: 30,
|
231
|
+
tls_sni: false,
|
232
|
+
error_response: "not_found"
|
233
|
+
get("/foo") { |r| r.ok "should not get here" }
|
234
|
+
end
|
235
|
+
) do
|
236
|
+
res = get_resp("/foo")
|
237
|
+
assert_equal "404", res.code, "Expected error response code 404 for not_found"
|
238
|
+
end
|
239
|
+
end
|
244
240
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
241
|
+
def test_error_response_unauthorized
|
242
|
+
server(
|
243
|
+
itsi_rb: lambda do
|
244
|
+
proxy \
|
245
|
+
to: "invalid_url",
|
246
|
+
backends: ["127.0.0.1:3001"],
|
247
|
+
backend_priority: "round_robin",
|
248
|
+
headers: {},
|
249
|
+
verify_ssl: false,
|
250
|
+
timeout: 30,
|
251
|
+
tls_sni: false,
|
252
|
+
error_response: "unauthorized"
|
253
|
+
get("/foo") { |r| r.ok "should not get here" }
|
254
|
+
end
|
255
|
+
) do
|
256
|
+
res = get_resp("/foo")
|
257
|
+
assert_equal "401", res.code, "Expected error response code 401 for unauthorized"
|
258
|
+
end
|
259
|
+
end
|
264
260
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
261
|
+
def test_error_response_forbidden
|
262
|
+
server(
|
263
|
+
itsi_rb: lambda do
|
264
|
+
proxy \
|
265
|
+
to: "invalid_url",
|
266
|
+
backends: ["127.0.0.1:3001"],
|
267
|
+
backend_priority: "round_robin",
|
268
|
+
headers: {},
|
269
|
+
verify_ssl: false,
|
270
|
+
timeout: 30,
|
271
|
+
tls_sni: false,
|
272
|
+
error_response: "forbidden"
|
273
|
+
get("/foo") { |r| r.ok "should not get here" }
|
274
|
+
end
|
275
|
+
) do
|
276
|
+
res = get_resp("/foo")
|
277
|
+
assert_equal "403", res.code, "Expected error response code 403 for forbidden"
|
278
|
+
end
|
279
|
+
end
|
284
280
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
281
|
+
def test_error_response_payload_too_large
|
282
|
+
server(
|
283
|
+
itsi_rb: lambda do
|
284
|
+
proxy \
|
285
|
+
to: "invalid_url",
|
286
|
+
backends: ["127.0.0.1:3001"],
|
287
|
+
backend_priority: "round_robin",
|
288
|
+
headers: {},
|
289
|
+
verify_ssl: false,
|
290
|
+
timeout: 30,
|
291
|
+
tls_sni: false,
|
292
|
+
error_response: "payload_too_large"
|
293
|
+
get("/foo") { |r| r.ok "should not get here" }
|
294
|
+
end
|
295
|
+
) do
|
296
|
+
res = get_resp("/foo")
|
297
|
+
assert_equal "413", res.code, "Expected error response code 413 for payload_too_large"
|
298
|
+
end
|
299
|
+
end
|
304
300
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
301
|
+
def test_error_response_too_many_requests
|
302
|
+
server(
|
303
|
+
itsi_rb: lambda do
|
304
|
+
proxy \
|
305
|
+
to: "invalid_url",
|
306
|
+
backends: ["127.0.0.1:3001"],
|
307
|
+
backend_priority: "round_robin",
|
308
|
+
headers: {},
|
309
|
+
verify_ssl: false,
|
310
|
+
timeout: 30,
|
311
|
+
tls_sni: false,
|
312
|
+
error_response: "too_many_requests"
|
313
|
+
get("/foo") { |r| r.ok "should not get here" }
|
314
|
+
end
|
315
|
+
) do
|
316
|
+
res = get_resp("/foo")
|
317
|
+
assert_equal "429", res.code, "Expected error response code 429 for too_many_requests"
|
318
|
+
end
|
319
|
+
end
|
324
320
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
321
|
+
def test_error_response_service_unavailable
|
322
|
+
server(
|
323
|
+
itsi_rb: lambda do
|
324
|
+
proxy \
|
325
|
+
to: "invalid_url",
|
326
|
+
backends: ["127.0.0.1:3001"],
|
327
|
+
backend_priority: "round_robin",
|
328
|
+
headers: {},
|
329
|
+
verify_ssl: false,
|
330
|
+
timeout: 30,
|
331
|
+
tls_sni: false,
|
332
|
+
error_response: "service_unavailable"
|
333
|
+
get("/foo") { |r| r.ok "should not get here" }
|
334
|
+
end
|
335
|
+
) do
|
336
|
+
res = get_resp("/foo")
|
337
|
+
assert_equal "503", res.code, "Expected error response code 503 for service_unavailable"
|
338
|
+
end
|
339
|
+
end
|
344
340
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
341
|
+
def test_error_response_gateway_timeout
|
342
|
+
server(
|
343
|
+
itsi_rb: lambda do
|
344
|
+
proxy \
|
345
|
+
to: "invalid_url",
|
346
|
+
backends: ["127.0.0.1:3001"],
|
347
|
+
backend_priority: "round_robin",
|
348
|
+
headers: {},
|
349
|
+
verify_ssl: false,
|
350
|
+
timeout: 30,
|
351
|
+
tls_sni: false,
|
352
|
+
error_response: "gateway_timeout"
|
353
|
+
get("/foo") { |r| r.ok "should not get here" }
|
354
|
+
end
|
355
|
+
) do
|
356
|
+
res = get_resp("/foo")
|
357
|
+
assert_equal "504", res.code, "Expected error response code 504 for gateway_timeout"
|
362
358
|
end
|
363
359
|
end
|
364
360
|
|
365
|
-
def test_failover_behavior
|
361
|
+
def test_failover_behavior # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
366
362
|
# Obtain two free bind addresses for backend servers.
|
367
363
|
backend1_bind = free_bind
|
368
364
|
backend2_bind = free_bind
|
369
365
|
|
370
|
-
|
366
|
+
Itsi::Server.start_in_background_thread(binds: [backend2_bind]) do
|
367
|
+
workers 1
|
371
368
|
get("/failover") { |r| r.ok "backend2" }
|
372
369
|
end
|
373
370
|
|
@@ -376,14 +373,13 @@ class TestProxy < Minitest::Test
|
|
376
373
|
# # Allow the backend servers to start.
|
377
374
|
sleep 0.2
|
378
375
|
|
379
|
-
|
380
376
|
# Start the proxy server with an ordered backend selection.
|
381
377
|
server(
|
382
378
|
cleanup: false,
|
383
379
|
itsi_rb: lambda do
|
384
380
|
proxy \
|
385
381
|
to: "http://proxied_host.com{path}{query}",
|
386
|
-
backends:
|
382
|
+
backends: [backend1_bind[%r{//(.*)}, 1], backend2_bind[%r{//(.*)}, 1]],
|
387
383
|
backend_priority: "ordered",
|
388
384
|
headers: {},
|
389
385
|
verify_ssl: false,
|
@@ -393,18 +389,16 @@ class TestProxy < Minitest::Test
|
|
393
389
|
get("/failover") { |r| r.ok "should not get here" }
|
394
390
|
end
|
395
391
|
) do
|
396
|
-
|
397
|
-
|
398
392
|
res = get_resp("/failover")
|
399
393
|
assert_equal "200", res.code, "Expected success when fallback backend is available"
|
400
394
|
assert_equal "backend2", res.body, "Expected response from backend2"
|
401
395
|
|
402
|
-
|
396
|
+
Itsi::Server.start_in_background_thread(binds: [backend1_bind]) do
|
397
|
+
workers 1
|
403
398
|
get("/failover") { |r| r.ok "backend1" }
|
404
399
|
end
|
405
400
|
|
406
401
|
sleep 1
|
407
|
-
|
408
402
|
res = get_resp("/failover")
|
409
403
|
assert_equal "200", res.code, "Expected reversion when primary becomes available"
|
410
404
|
assert_equal "backend1", res.body, "Expected response from backend1 with ordered priority"
|
data/lib/itsi/version.rb
CHANGED