nonnative 3.38.0 → 3.40.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
- data/README.md +7 -4
- data/lib/nonnative/configuration.rb +3 -1
- data/lib/nonnative/http_client.rb +15 -10
- data/lib/nonnative/http_proxy_server.rb +9 -4
- data/lib/nonnative/observability.rb +3 -2
- data/lib/nonnative/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f3513aa619cd9dab8134d9c4e8d22d333dcd2300f92e271cb8dee10ed7c0de2c
|
|
4
|
+
data.tar.gz: 4aeae3fd49ad6bd1da6b929bfa666c17c3c346a73a56b430ca7214a82ee19698
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d5c02d41c403e663ba1ffe2e8f36e67fe4a2a36910b60a921d0e02c3ac84b1c68be01158ff223c40ee3e6990e429d79faf79eada9e538195a26652523d89813a
|
|
7
|
+
data.tar.gz: 6be1f9067df0fd1c121d0604813d3f91b4e9bbe9cbecfcd10aacd8a96a06a76f27a0a42bb3a08398cb7f0c3e68678a42c0f55b62390f304461814332a1e7e1bf
|
data/README.md
CHANGED
|
@@ -182,8 +182,9 @@ expect(response.code).to eq(200)
|
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
HTTP error statuses are returned as response objects so callers can inspect `.code` and `.body`.
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
Broken connections raise their RestClient exceptions, and a request timeout raises either a RestClient
|
|
186
|
+
timeout exception or `Timeout::Error` (the latter when `read_timeout` bounds a Net::HTTP retry of an
|
|
187
|
+
idempotent verb); observability requests are not retried automatically.
|
|
187
188
|
|
|
188
189
|
`Nonnative.grpc_health` is a helper for the standard gRPC health checking protocol:
|
|
189
190
|
|
|
@@ -608,8 +609,10 @@ end
|
|
|
608
609
|
The system allows you to define an in-process HTTP forward proxy server for external systems, e.g. `api.github.com`. This is a server implementation, not a fault-injection service proxy.
|
|
609
610
|
|
|
610
611
|
The upstream scheme defaults to HTTPS on the scheme's default port; pass `scheme:`/`port:` to
|
|
611
|
-
`Nonnative::HTTPProxyServer.new` to target an `http://` upstream or a non-default port. The
|
|
612
|
-
|
|
612
|
+
`Nonnative::HTTPProxyServer.new` to target an `http://` upstream or a non-default port. The whole
|
|
613
|
+
upstream call defaults to a one-second bound, including Net::HTTP's built-in retry of an
|
|
614
|
+
unresponsive idempotent request; pass `upstream_timeout:` to tune it for a slow dependency. The
|
|
615
|
+
proxy forwards the request path and query for `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, and
|
|
613
616
|
`OPTIONS`, while removing proxy credentials, `Host`, `Accept-Encoding`, hop-by-hop headers, and
|
|
614
617
|
headers nominated by `Connection` before the upstream request.
|
|
615
618
|
|
|
@@ -93,6 +93,8 @@ module Nonnative
|
|
|
93
93
|
process = Nonnative::ConfigurationProcess.new
|
|
94
94
|
yield process
|
|
95
95
|
|
|
96
|
+
raise ArgumentError, "Process '#{process.name}' requires 'command' or 'go'" if process.command.nil?
|
|
97
|
+
|
|
96
98
|
processes << process
|
|
97
99
|
end
|
|
98
100
|
|
|
@@ -157,7 +159,7 @@ module Nonnative
|
|
|
157
159
|
tools = go.tools || []
|
|
158
160
|
|
|
159
161
|
-> { Nonnative.go_argv(tools, go.output, go.executable, go.command, *params) }
|
|
160
|
-
|
|
162
|
+
elsif process.command
|
|
161
163
|
-> { process.command }
|
|
162
164
|
end
|
|
163
165
|
end
|
|
@@ -18,7 +18,8 @@ module Nonnative
|
|
|
18
18
|
@host = host
|
|
19
19
|
@exceptions = [
|
|
20
20
|
RestClient::Exceptions::Timeout,
|
|
21
|
-
RestClient::ServerBrokeConnection
|
|
21
|
+
RestClient::ServerBrokeConnection,
|
|
22
|
+
::Timeout::Error
|
|
22
23
|
]
|
|
23
24
|
end
|
|
24
25
|
|
|
@@ -40,7 +41,7 @@ module Nonnative
|
|
|
40
41
|
# @param opts [Hash] RestClient request options (e.g. `headers`, `read_timeout`, `open_timeout`)
|
|
41
42
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
42
43
|
def get(pathname, opts = {})
|
|
43
|
-
with_exception do
|
|
44
|
+
with_exception(opts) do
|
|
44
45
|
resource(pathname, opts).get
|
|
45
46
|
end
|
|
46
47
|
end
|
|
@@ -52,7 +53,7 @@ module Nonnative
|
|
|
52
53
|
# @param opts [Hash] RestClient request options
|
|
53
54
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
54
55
|
def post(pathname, payload, opts = {})
|
|
55
|
-
with_exception do
|
|
56
|
+
with_exception(opts) do
|
|
56
57
|
resource(pathname, opts).post(payload)
|
|
57
58
|
end
|
|
58
59
|
end
|
|
@@ -63,7 +64,7 @@ module Nonnative
|
|
|
63
64
|
# @param opts [Hash] RestClient request options
|
|
64
65
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
65
66
|
def delete(pathname, opts = {})
|
|
66
|
-
with_exception do
|
|
67
|
+
with_exception(opts) do
|
|
67
68
|
resource(pathname, opts).delete
|
|
68
69
|
end
|
|
69
70
|
end
|
|
@@ -75,7 +76,7 @@ module Nonnative
|
|
|
75
76
|
# @param opts [Hash] RestClient request options
|
|
76
77
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
77
78
|
def put(pathname, payload, opts = {})
|
|
78
|
-
with_exception do
|
|
79
|
+
with_exception(opts) do
|
|
79
80
|
resource(pathname, opts).put(payload)
|
|
80
81
|
end
|
|
81
82
|
end
|
|
@@ -87,7 +88,7 @@ module Nonnative
|
|
|
87
88
|
# @param opts [Hash] RestClient request options
|
|
88
89
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
89
90
|
def patch(pathname, payload, opts = {})
|
|
90
|
-
with_exception do
|
|
91
|
+
with_exception(opts) do
|
|
91
92
|
resource(pathname, opts).patch(payload)
|
|
92
93
|
end
|
|
93
94
|
end
|
|
@@ -98,7 +99,7 @@ module Nonnative
|
|
|
98
99
|
# @param opts [Hash] RestClient request options (e.g. `headers`, `read_timeout`, `open_timeout`)
|
|
99
100
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
100
101
|
def head(pathname, opts = {})
|
|
101
|
-
with_exception do
|
|
102
|
+
with_exception(opts) do
|
|
102
103
|
resource(pathname, opts).head
|
|
103
104
|
end
|
|
104
105
|
end
|
|
@@ -109,7 +110,7 @@ module Nonnative
|
|
|
109
110
|
# @param opts [Hash] RestClient request options (e.g. `headers`, `read_timeout`, `open_timeout`)
|
|
110
111
|
# @return [RestClient::Response, String] response for non-2xx errors, otherwise the RestClient result
|
|
111
112
|
def options(pathname, opts = {})
|
|
112
|
-
with_exception do
|
|
113
|
+
with_exception(opts) do
|
|
113
114
|
RestClient::Request.execute(opts.merge(method: :options, url: request_url(pathname)))
|
|
114
115
|
end
|
|
115
116
|
end
|
|
@@ -131,8 +132,12 @@ module Nonnative
|
|
|
131
132
|
URI.join(host, pathname).to_s
|
|
132
133
|
end
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
# Net::HTTP silently retries idempotent verbs once on a read timeout, so bound the whole call
|
|
136
|
+
# (including any retry) by the wall clock rather than trusting `:read_timeout` alone.
|
|
137
|
+
def with_exception(opts = {}, &)
|
|
138
|
+
timeout = opts[:read_timeout]
|
|
139
|
+
|
|
140
|
+
timeout ? ::Timeout.timeout(timeout, &) : yield
|
|
136
141
|
rescue *exceptions => e
|
|
137
142
|
raise e
|
|
138
143
|
rescue RestClient::Exception => e
|
|
@@ -59,7 +59,8 @@ module Nonnative
|
|
|
59
59
|
].freeze
|
|
60
60
|
|
|
61
61
|
GATEWAY_TIMEOUT_ERRORS = [
|
|
62
|
-
RestClient::Exceptions::Timeout
|
|
62
|
+
RestClient::Exceptions::Timeout,
|
|
63
|
+
::Timeout::Error
|
|
63
64
|
].freeze
|
|
64
65
|
|
|
65
66
|
GATEWAY_CONNECTION_ERRORS = [
|
|
@@ -112,10 +113,12 @@ module Nonnative
|
|
|
112
113
|
# @return [RestClient::Response] response for error statuses, otherwise RestClient return value
|
|
113
114
|
# @raise [Sinatra::Halt] with a gateway status when the upstream is unavailable or times out
|
|
114
115
|
def api_response(method:, url:, headers:, payload: nil)
|
|
115
|
-
options = { method:, url:, headers: }
|
|
116
|
+
options = { method:, url:, headers:, open_timeout: settings.upstream_timeout, read_timeout: settings.upstream_timeout }
|
|
116
117
|
options[:payload] = payload unless payload.nil?
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
# Net::HTTP retries idempotent verbs once on a read timeout, so bound the whole
|
|
120
|
+
# call (including any retry) by the wall clock rather than trusting read_timeout alone.
|
|
121
|
+
::Timeout.timeout(settings.upstream_timeout) { RestClient::Request.execute(options) }
|
|
119
122
|
rescue *GATEWAY_TIMEOUT_ERRORS
|
|
120
123
|
halt 504
|
|
121
124
|
rescue *GATEWAY_CONNECTION_ERRORS
|
|
@@ -246,11 +249,13 @@ module Nonnative
|
|
|
246
249
|
# @param service [Nonnative::ConfigurationServer] server configuration
|
|
247
250
|
# @param scheme [String] upstream scheme, `"http"` or `"https"`
|
|
248
251
|
# @param port [Integer, nil] upstream port; `nil` uses the scheme's default port
|
|
249
|
-
|
|
252
|
+
# @param upstream_timeout [Numeric] maximum seconds for each upstream operation (defaults to `1.0`)
|
|
253
|
+
def initialize(host, service, scheme: 'https', port: nil, upstream_timeout: ConfigurationRunner::DEFAULT_TIMEOUT)
|
|
250
254
|
http_service = Class.new(Nonnative::HTTPProxy) do
|
|
251
255
|
set :host, host
|
|
252
256
|
set :scheme, scheme
|
|
253
257
|
set :port, port
|
|
258
|
+
set :upstream_timeout, upstream_timeout
|
|
254
259
|
end
|
|
255
260
|
|
|
256
261
|
super(http_service.new, service)
|
|
@@ -14,8 +14,9 @@ module Nonnative
|
|
|
14
14
|
#
|
|
15
15
|
# Requests are performed using {Nonnative::HTTPClient}, so callers may pass RestClient options
|
|
16
16
|
# such as `headers`, `open_timeout`, and `read_timeout`. HTTP error statuses are returned as response
|
|
17
|
-
# objects;
|
|
18
|
-
#
|
|
17
|
+
# objects; broken connections raise their RestClient exceptions, and a timeout raises either a
|
|
18
|
+
# RestClient timeout exception or `Timeout::Error` (the latter when `read_timeout` bounds a Net::HTTP
|
|
19
|
+
# retry of an idempotent verb). Requests are not retried automatically.
|
|
19
20
|
#
|
|
20
21
|
# @example
|
|
21
22
|
# Nonnative.configure do |config|
|
data/lib/nonnative/version.rb
CHANGED