patron 0.14.0 → 1.0.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/CHANGELOG.md +77 -0
- data/README.md +83 -49
- data/ext/patron/extconf.rb +54 -23
- data/ext/patron/session_ext.c +1044 -923
- data/lib/patron/compat.rb +57 -0
- data/lib/patron/error.rb +21 -13
- data/lib/patron/header_parser.rb +27 -25
- data/lib/patron/request.rb +98 -144
- data/lib/patron/response.rb +28 -24
- data/lib/patron/response_decoding.rb +60 -67
- data/lib/patron/session.rb +114 -108
- data/lib/patron/util.rb +14 -12
- data/lib/patron/version.rb +3 -1
- data/lib/patron.rb +9 -15
- metadata +12 -58
- data/.autotest +0 -15
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/ci.yml +0 -79
- data/.gitignore +0 -10
- data/.rspec +0 -0
- data/.travis.yml +0 -13
- data/.yardopts +0 -1
- data/Gemfile +0 -18
- data/Rakefile +0 -31
- data/ext/patron/.gitignore +0 -4
- data/ext/patron/membuffer.c +0 -85
- data/ext/patron/membuffer.h +0 -78
- data/ext/patron/sglib.h +0 -1952
- data/lib/patron/proxy_type.rb +0 -11
- data/patron.gemspec +0 -39
- data/pic.png +0 -0
- data/script/console +0 -11
- data/script/generate_client_certs +0 -65
- data/script/test_server +0 -7
- data/spec/header_parser_spec.rb +0 -101
- data/spec/patron_spec.rb +0 -28
- data/spec/request_spec.rb +0 -89
- data/spec/response_spec.rb +0 -145
- data/spec/sample_response_headers/headers_wetransfer.txt +0 -18
- data/spec/sample_response_headers/headers_wetransfer_with_proxy_status.txt +0 -20
- data/spec/sample_response_headers/headers_wetransfer_with_redirect.txt +0 -24
- data/spec/sample_response_headers/headers_with_set_cookie.txt +0 -9
- data/spec/sample_response_headers/sample_http2_header.txt +0 -16
- data/spec/sample_response_headers/webmock_headers_without_trailing_crlf.txt +0 -15
- data/spec/session_spec.rb +0 -865
- data/spec/session_ssl_spec.rb +0 -431
- data/spec/spec_helper.rb +0 -40
- data/spec/support/certs/cacert.pem +0 -36
- data/spec/support/certs/client.p12 +0 -0
- data/spec/support/certs/client_ca.pem +0 -20
- data/spec/support/certs/client_cert.pem +0 -20
- data/spec/support/certs/client_key.pem +0 -30
- data/spec/support/certs/privkey.pem +0 -51
- data/spec/support/certs/rogue_client.p12 +0 -0
- data/spec/support/config.ru +0 -153
- data/spec/support/fork.rb +0 -70
- data/spec/support/raw_request_capture.rb +0 -93
- data/spec/support/test_server.rb +0 -29
- data/spec/support/valgrind.supp +0 -2
- data/spec/util_spec.rb +0 -71
data/spec/session_ssl_spec.rb
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
require File.expand_path("./spec") + '/spec_helper.rb'
|
|
2
|
-
require 'webrick'
|
|
3
|
-
require 'yaml'
|
|
4
|
-
require 'base64'
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
|
|
7
|
-
describe Patron::Session do
|
|
8
|
-
|
|
9
|
-
def yaml_load(str)
|
|
10
|
-
if RUBY_VERSION >= '3.1.0'
|
|
11
|
-
YAML::safe_load(str, permitted_classes: [OpenStruct])
|
|
12
|
-
else
|
|
13
|
-
YAML::load(str)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
before(:each) do
|
|
18
|
-
@session = Patron::Session.new
|
|
19
|
-
@session.base_url = "https://localhost:9043"
|
|
20
|
-
@session.insecure = true
|
|
21
|
-
# The first TLS handshake takes a few seconds when both ends run under valgrind
|
|
22
|
-
@session.connect_timeout = 10
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "should retrieve a url with :get" do
|
|
26
|
-
response = @session.get("/test")
|
|
27
|
-
body = yaml_load(response.body)
|
|
28
|
-
expect(body.request_method).to be == "GET"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "should download content with :get and a file path" do
|
|
32
|
-
tmpfile = "/tmp/patron_test.yaml"
|
|
33
|
-
response = @session.get_file "/test", tmpfile
|
|
34
|
-
expect(response.body).to be_nil
|
|
35
|
-
body = yaml_load(File.open(tmpfile).read)
|
|
36
|
-
expect(body.request_method).to be == "GET"
|
|
37
|
-
FileUtils.rm tmpfile
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# See https://github.com/curl/curl/issues/788
|
|
41
|
-
# Basically any HTTPS operation crashes on OSX with securetransport-enabled libCURL
|
|
42
|
-
it "should download content in a forked subprocess" do
|
|
43
|
-
# To trigger the bug, we need to perform a request in the master process first
|
|
44
|
-
tmpfile = "/tmp/patron_test.yaml"
|
|
45
|
-
@session.get_file "/test", tmpfile
|
|
46
|
-
FileUtils.rm tmpfile
|
|
47
|
-
|
|
48
|
-
# and this one segfaults
|
|
49
|
-
pid = fork do
|
|
50
|
-
response = @session.get_file "/test", tmpfile
|
|
51
|
-
expect(response.body).to be_nil
|
|
52
|
-
body = yaml_load(File.open(tmpfile).read)
|
|
53
|
-
expect(body.request_method).to be == "GET"
|
|
54
|
-
FileUtils.rm tmpfile
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
exit_pid, status = Process.wait2(pid)
|
|
58
|
-
expect(status.exitstatus).to be_zero
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "should download correctly(md5 ok) with get_file" do
|
|
62
|
-
tmpfile = "/tmp/picture"
|
|
63
|
-
response = @session.get_file "/picture", tmpfile
|
|
64
|
-
expect(response.body).to be_nil
|
|
65
|
-
expect(File.size(File.join(File.dirname(__FILE__),"../pic.png"))).to be == File.size(tmpfile)
|
|
66
|
-
FileUtils.rm tmpfile
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "should include custom headers in a request" do
|
|
70
|
-
response = @session.get("/test", {"User-Agent" => "PatronTest"})
|
|
71
|
-
body = yaml_load(response.body)
|
|
72
|
-
expect(body.header["user-agent"]).to be == ["PatronTest"]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "should merge custom headers with session headers" do
|
|
76
|
-
@session.headers["X-Test"] = "Testing"
|
|
77
|
-
response = @session.get("/test", {"User-Agent" => "PatronTest"})
|
|
78
|
-
body = yaml_load(response.body)
|
|
79
|
-
expect(body.header["user-agent"]).to be == ["PatronTest"]
|
|
80
|
-
expect(body.header["x-test"]).to be == ["Testing"]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "should raise an exception on timeout" do
|
|
84
|
-
@session.timeout = 1
|
|
85
|
-
expect {
|
|
86
|
-
@session.get("/timeout?millis=1100")
|
|
87
|
-
}.to raise_error(Patron::TimeoutError)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it "should follow redirects by default" do
|
|
91
|
-
@session.max_redirects = 1
|
|
92
|
-
response = @session.get("/redirect")
|
|
93
|
-
body = yaml_load(response.body)
|
|
94
|
-
expect(response.status).to be == 200
|
|
95
|
-
expect(body.path).to be == "/test"
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it "should include redirect count in response" do
|
|
99
|
-
@session.max_redirects = 1
|
|
100
|
-
response = @session.get("/redirect")
|
|
101
|
-
expect(response.redirect_count).to be == 1
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "should not follow redirects when configured to do so" do
|
|
105
|
-
@session.max_redirects = 0
|
|
106
|
-
response = @session.get("/redirect")
|
|
107
|
-
expect(response.status).to be == 301
|
|
108
|
-
expect(response.body).to be_empty
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "should retrieve URL metadata with :head" do
|
|
112
|
-
response = @session.head("/test")
|
|
113
|
-
expect(response.status).to be == 200
|
|
114
|
-
expect(response.body).to be_empty
|
|
115
|
-
expect(response.headers).to_not be_empty
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it "should send a delete request with :delete" do
|
|
119
|
-
response = @session.delete("/test")
|
|
120
|
-
body = yaml_load(response.body)
|
|
121
|
-
expect(body.request_method).to be == "DELETE"
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "should send a COPY request with :copy" do
|
|
125
|
-
response = @session.copy("/test", "/test2")
|
|
126
|
-
body = yaml_load(response.body)
|
|
127
|
-
expect(body.request_method).to be == "COPY"
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it "should include a Destination header in COPY requests" do
|
|
131
|
-
response = @session.copy("/test", "/test2")
|
|
132
|
-
body = yaml_load(response.body)
|
|
133
|
-
expect(body.header['destination'].first).to be == "/test2"
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "should upload data with :get" do
|
|
137
|
-
data = "upload data"
|
|
138
|
-
response = @session.request(:get, "/test", {}, :data => data)
|
|
139
|
-
body = yaml_load(response.body)
|
|
140
|
-
expect(body.request_method).to be == "GET"
|
|
141
|
-
expect(body.header['content-length']).to be == [data.size.to_s]
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "should upload data with :put" do
|
|
145
|
-
data = "upload data"
|
|
146
|
-
response = @session.put("/test", data)
|
|
147
|
-
body = yaml_load(response.body)
|
|
148
|
-
expect(body.request_method).to be == "PUT"
|
|
149
|
-
expect(body.header['content-length']).to be == [data.size.to_s]
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
it "should raise when no data is provided to :put" do
|
|
153
|
-
expect { @session.put("/test", nil) }.to raise_error(ArgumentError)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
it "should upload a file with :put" do
|
|
157
|
-
response = @session.put_file("/test", "LICENSE")
|
|
158
|
-
body = yaml_load(response.body)
|
|
159
|
-
expect(body.request_method).to be == "PUT"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
it "should raise when no file is provided to :put" do
|
|
163
|
-
expect { @session.put_file("/test", nil) }.to raise_error(ArgumentError)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
it "should upload a file with :put using chunked transfer-encoding" do
|
|
167
|
-
# Transfer-Encoding is a hop-by-hop header (RFC 7230 3.3.1): a conformant server
|
|
168
|
-
# decodes the chunked framing and never exposes the header to the application, so
|
|
169
|
-
# we capture the raw request to assert how Patron actually frames the upload.
|
|
170
|
-
captured = capture_request(ssl: true) do |url|
|
|
171
|
-
session = Patron::Session.new
|
|
172
|
-
session.base_url = url
|
|
173
|
-
session.insecure = true
|
|
174
|
-
session.timeout = 5
|
|
175
|
-
session.put_file("/test", "LICENSE")
|
|
176
|
-
end
|
|
177
|
-
expect(captured.request_line).to start_with("PUT ")
|
|
178
|
-
expect(captured.headers["transfer-encoding"]).to be == "chunked"
|
|
179
|
-
expect(captured.headers).to_not have_key("content-length")
|
|
180
|
-
expect(captured.body.bytesize).to be == File.size("LICENSE")
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
it "should upload data with :post" do
|
|
184
|
-
data = "upload data"
|
|
185
|
-
response = @session.post("/test", data)
|
|
186
|
-
body = yaml_load(response.body)
|
|
187
|
-
expect(body.request_method).to be == "POST"
|
|
188
|
-
expect(body.header['content-length']).to be == [data.size.to_s]
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
it "should post a hash of arguments as a urlencoded form" do
|
|
192
|
-
data = {:foo => 123, 'baz' => '++hello world++'}
|
|
193
|
-
response = @session.post("/testpost", data)
|
|
194
|
-
body = yaml_load(response.body)
|
|
195
|
-
expect(body['content_type']).to be == "application/x-www-form-urlencoded"
|
|
196
|
-
expect(body['body']).to match(/baz=%2B%2Bhello%20world%2B%2B/)
|
|
197
|
-
expect(body['body']).to match(/foo=123/)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
it "should raise when no data is provided to :post" do
|
|
201
|
-
expect { @session.post("/test", nil) }.to raise_error(ArgumentError)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
it "should upload a file with :post" do
|
|
205
|
-
response = @session.post_file("/test", "LICENSE")
|
|
206
|
-
body = yaml_load(response.body)
|
|
207
|
-
expect(body.request_method).to be == "POST"
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
it "should upload a multipart with :post" do
|
|
211
|
-
response = @session.post_multipart("/test", { :test_data => "123" }, { :test_file => "LICENSE" } )
|
|
212
|
-
body = yaml_load(response.body)
|
|
213
|
-
expect(body.request_method).to be == "POST"
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
it "should raise when no file is provided to :post" do
|
|
217
|
-
expect { @session.post_file("/test", nil) }.to raise_error(ArgumentError)
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
it "should upload a file with :post using chunked transfer-encoding" do
|
|
221
|
-
# See the :put counterpart above: Transfer-Encoding is hop-by-hop and invisible
|
|
222
|
-
# to the application, so we capture the raw request to assert the framing.
|
|
223
|
-
captured = capture_request(ssl: true) do |url|
|
|
224
|
-
session = Patron::Session.new
|
|
225
|
-
session.base_url = url
|
|
226
|
-
session.insecure = true
|
|
227
|
-
session.timeout = 5
|
|
228
|
-
session.post_file("/test", "LICENSE")
|
|
229
|
-
end
|
|
230
|
-
expect(captured.request_line).to start_with("POST ")
|
|
231
|
-
expect(captured.headers["transfer-encoding"]).to be == "chunked"
|
|
232
|
-
expect(captured.headers).to_not have_key("content-length")
|
|
233
|
-
expect(captured.body.bytesize).to be == File.size("LICENSE")
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
it "should handle cookies if set" do
|
|
237
|
-
@session.handle_cookies
|
|
238
|
-
response = @session.get("/setcookie").body
|
|
239
|
-
expect(yaml_load(response).header['cookie'].first).to be == "session_id=foo123"
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
it "should not handle cookies by default" do
|
|
243
|
-
response = @session.get("/setcookie").body
|
|
244
|
-
expect(yaml_load(response).header).to_not include('cookie')
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
it "should raise exception if cookie store is not writable or readable" do
|
|
248
|
-
expect { @session.handle_cookies("/trash/clash/foo") }.to raise_error(ArgumentError)
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
it "should work with multiple threads" do
|
|
252
|
-
threads = []
|
|
253
|
-
3.times do
|
|
254
|
-
threads << Thread.new do
|
|
255
|
-
session = Patron::Session.new
|
|
256
|
-
session.base_url = "https://localhost:9043"
|
|
257
|
-
session.insecure = true
|
|
258
|
-
session.post_file("/test", "LICENSE")
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
threads.each {|t| t.join }
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
it "should fail when insecure mode is off" do
|
|
265
|
-
expect {
|
|
266
|
-
@session.insecure = nil
|
|
267
|
-
response = @session.get("/test")
|
|
268
|
-
}.to raise_error(Patron::Error)
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it "should work when insecure mode is off but certificate is supplied" do
|
|
272
|
-
@session.insecure = nil
|
|
273
|
-
@session.cacert = File.join(__dir__, 'support', 'certs', 'cacert.pem')
|
|
274
|
-
response = @session.get("/test")
|
|
275
|
-
body = yaml_load(response.body)
|
|
276
|
-
expect(body.request_method).to be == "GET"
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
it "should allow to specify insecure mode per-request" do
|
|
280
|
-
@session.insecure = false
|
|
281
|
-
expect {
|
|
282
|
-
@session.request(:get, "/test", {}, insecure: true)
|
|
283
|
-
}.not_to raise_error
|
|
284
|
-
expect {
|
|
285
|
-
@session.request(:get, "/test", {})
|
|
286
|
-
}.to raise_error(Patron::Error)
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
it "should work with different SSL versions" do
|
|
290
|
-
['TLSv1_0','TLSv1_1'].each do |version|
|
|
291
|
-
@session.ssl_version = version
|
|
292
|
-
response = @session.get("/test")
|
|
293
|
-
expect(response.status).to be == 200
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "should raise when an unsupported or unknown SSL version is requested" do
|
|
298
|
-
['something', 1].each do |version|
|
|
299
|
-
@session.ssl_version = version
|
|
300
|
-
expect {
|
|
301
|
-
@session.get("/test")
|
|
302
|
-
}.to raise_error(Patron::UnsupportedSSLVersion)
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
it "should work with different HTTP versions" do
|
|
307
|
-
['HTTPv1_0','HTTPv1_1'].each do |version|
|
|
308
|
-
@session.http_version = version
|
|
309
|
-
response = @session.get("/test")
|
|
310
|
-
expect(response.status).to be == 200
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "should raise when an unsupported or unknown HTTP version is requested" do
|
|
315
|
-
['something', 1].each do |version|
|
|
316
|
-
@session.http_version = version
|
|
317
|
-
expect {
|
|
318
|
-
@session.get("/test")
|
|
319
|
-
}.to raise_error(Patron::UnsupportedHTTPVersion)
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
# ------------------------------------------------------------------------
|
|
324
|
-
describe 'when debug is enabled' do
|
|
325
|
-
it 'it should not clobber stderr' do
|
|
326
|
-
rdev = STDERR.stat.rdev
|
|
327
|
-
|
|
328
|
-
@session.enable_debug
|
|
329
|
-
expect(STDERR.stat.rdev).to be == rdev
|
|
330
|
-
|
|
331
|
-
@session.enable_debug
|
|
332
|
-
expect(STDERR.stat.rdev).to be == rdev
|
|
333
|
-
end
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
describe 'with a server that requires a client certificate' do
|
|
337
|
-
let(:certs) { File.join(__dir__, 'support', 'certs') }
|
|
338
|
-
|
|
339
|
-
# libcurl's GnuTLS backend reports any client certificate it can't load as CURLE_SSL_CONNECT_ERROR
|
|
340
|
-
let(:gnutls) { Patron.libcurl_version.include?('GnuTLS') }
|
|
341
|
-
|
|
342
|
-
def refused_by_server
|
|
343
|
-
raise_error { |e|
|
|
344
|
-
expect(e).to be_kind_of(Patron::Error)
|
|
345
|
-
expect(e).not_to be_kind_of(Patron::ClientCertificateError)
|
|
346
|
-
expect(e).not_to be_kind_of(Patron::TimeoutError)
|
|
347
|
-
}
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
before(:each) do
|
|
351
|
-
@session.base_url = "https://localhost:9044"
|
|
352
|
-
@session.insecure = false
|
|
353
|
-
@session.cacert = File.join(certs, 'cacert.pem')
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
it "presents a PKCS#12 client certificate" do
|
|
357
|
-
@session.ssl_cert = File.join(certs, 'client.p12')
|
|
358
|
-
@session.ssl_cert_type = 'P12'
|
|
359
|
-
@session.ssl_key_password = 'patron'
|
|
360
|
-
response = @session.get("/peercert")
|
|
361
|
-
expect(response.status).to be == 200
|
|
362
|
-
expect(response.body).to include('CN=patron-test-client')
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
it "presents a PEM client certificate with a separate encrypted key" do
|
|
366
|
-
@session.ssl_cert = File.join(certs, 'client_cert.pem')
|
|
367
|
-
@session.ssl_cert_type = 'PEM'
|
|
368
|
-
@session.ssl_key = File.join(certs, 'client_key.pem')
|
|
369
|
-
@session.ssl_key_password = 'patron'
|
|
370
|
-
response = @session.get("/peercert")
|
|
371
|
-
expect(response.status).to be == 200
|
|
372
|
-
expect(response.body).to include('CN=patron-test-client')
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
it "accepts the client certificate as a per-request option" do
|
|
376
|
-
response = @session.request(:get, "/peercert", {},
|
|
377
|
-
ssl_cert: File.join(certs, 'client.p12'), ssl_cert_type: 'P12', ssl_key_password: 'patron')
|
|
378
|
-
expect(response.body).to include('CN=patron-test-client')
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
it "accepts Pathnames for the certificate and key and a Symbol for the type" do
|
|
382
|
-
@session.cacert = Pathname(certs).join('cacert.pem')
|
|
383
|
-
@session.ssl_cert = Pathname(certs).join('client_cert.pem')
|
|
384
|
-
@session.ssl_cert_type = :PEM
|
|
385
|
-
@session.ssl_key = Pathname(certs).join('client_key.pem')
|
|
386
|
-
@session.ssl_key_password = 'patron'
|
|
387
|
-
response = @session.get("/peercert")
|
|
388
|
-
expect(response.body).to include('CN=patron-test-client')
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
it "does not leak a failed request's options into the next one" do
|
|
392
|
-
@session.ssl_cert = File.join(certs, 'client.p12')
|
|
393
|
-
@session.ssl_cert_type = 'P12'
|
|
394
|
-
@session.ssl_key_password = 'patron'
|
|
395
|
-
expect {
|
|
396
|
-
@session.request(:get, "/test", {'X-Leaked' => 'yes'}, ssl_key_password: 1234)
|
|
397
|
-
}.to raise_error(TypeError)
|
|
398
|
-
|
|
399
|
-
body = yaml_load(@session.get("/test").body)
|
|
400
|
-
expect(body.header).not_to have_key('x-leaked')
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
it "raises ClientCertificateError when the key password is wrong" do
|
|
404
|
-
skip "GnuTLS does not tell this apart from a handshake failure" if gnutls
|
|
405
|
-
@session.ssl_cert = File.join(certs, 'client.p12')
|
|
406
|
-
@session.ssl_cert_type = 'P12'
|
|
407
|
-
@session.ssl_key_password = 'wrong'
|
|
408
|
-
expect { @session.get("/peercert") }.to raise_error(Patron::ClientCertificateError)
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
it "raises ClientCertificateError when the certificate file does not exist" do
|
|
412
|
-
skip "GnuTLS does not tell this apart from a handshake failure" if gnutls
|
|
413
|
-
@session.ssl_cert = File.join(certs, 'nonexistent.p12')
|
|
414
|
-
@session.ssl_cert_type = 'P12'
|
|
415
|
-
@session.ssl_key_password = 'patron'
|
|
416
|
-
expect { @session.get("/peercert") }.to raise_error(Patron::ClientCertificateError)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
it "fails when the server does not trust the client certificate" do
|
|
420
|
-
@session.ssl_cert = File.join(certs, 'rogue_client.p12')
|
|
421
|
-
@session.ssl_cert_type = 'P12'
|
|
422
|
-
@session.ssl_key_password = 'patron'
|
|
423
|
-
expect { @session.get("/peercert") }.to refused_by_server
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
it "fails when no client certificate is presented" do
|
|
427
|
-
# Depending on the TLS version the server rejects us either during or right after the handshake
|
|
428
|
-
expect { @session.get("/peercert") }.to refused_by_server
|
|
429
|
-
end
|
|
430
|
-
end
|
|
431
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
if ENV["COVERAGE"]
|
|
2
|
-
require 'simplecov'
|
|
3
|
-
SimpleCov.start do
|
|
4
|
-
add_filter "/spec/"
|
|
5
|
-
end
|
|
6
|
-
end
|
|
7
|
-
require 'rspec'
|
|
8
|
-
|
|
9
|
-
# Kill warnings that not raising a specific exception still allows the method
|
|
10
|
-
# to fail with another exception
|
|
11
|
-
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
|
|
12
|
-
|
|
13
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
14
|
-
$:.unshift(File.dirname(__FILE__) + '/../ext')
|
|
15
|
-
require 'patron'
|
|
16
|
-
|
|
17
|
-
$stderr.puts "Build against #{Patron.libcurl_version}"
|
|
18
|
-
|
|
19
|
-
Dir['./spec/support/**/*.rb'].each { |fn| require fn }
|
|
20
|
-
|
|
21
|
-
http_server = Fork.new { PatronTestServer.start(false, 9001) }
|
|
22
|
-
|
|
23
|
-
sleep 0.1 # Don't interfere the start up output of two processes.
|
|
24
|
-
|
|
25
|
-
https_server = Fork.new { PatronTestServer.start(true, 9043) }
|
|
26
|
-
|
|
27
|
-
mtls_server = Fork.new do
|
|
28
|
-
PatronTestServer.start(true, 9044, client_ca: File.join(__dir__, 'support', 'certs', 'client_ca.pem'))
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
RSpec.configure do |c|
|
|
32
|
-
c.after(:suite) do
|
|
33
|
-
http_server.kill("TERM")
|
|
34
|
-
https_server.kill("TERM")
|
|
35
|
-
mtls_server.kill("TERM")
|
|
36
|
-
http_server.wait
|
|
37
|
-
https_server.wait
|
|
38
|
-
mtls_server.wait
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
IuX/K2XpJzBZ1w9UdcU+xdc/veUR/uBS9DDkSEb8KXkPSDcA0W3oj1+VfB1qq/22
|
|
16
|
-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
-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
-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
-
v/a/jlVnNekkSlADsyvya7t4hqfsDAxB5q/s/MpXItrGYf1sgtZX0nnNkPkgrF28
|
|
20
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
|
|
35
|
-
djS6lZ9vTEbRM+GhU2PMKfvJbiQ/Y6Q=
|
|
36
|
-
-----END CERTIFICATE-----
|
|
Binary file
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIDWzCCAkOgAwIBAgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEg
|
|
3
|
-
MB4GA1UECgwXUGF0cm9uIFRlc3QgQ2VydGlmaWNhdGUxHjAcBgNVBAMMFVBhdHJv
|
|
4
|
-
biBUZXN0IENsaWVudCBDQTAeFw0yNTAxMDEwMDAwMDBaFw00NTAxMDEwMDAwMDBa
|
|
5
|
-
ME8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKDBdQYXRyb24gVGVzdCBDZXJ0aWZpY2F0
|
|
6
|
-
ZTEeMBwGA1UEAwwVUGF0cm9uIFRlc3QgQ2xpZW50IENBMIIBIjANBgkqhkiG9w0B
|
|
7
|
-
AQEFAAOCAQ8AMIIBCgKCAQEA1iqOoIm5gW9MP0onsmSuOdlAdFZkP5r7rRSn+100
|
|
8
|
-
5ceHDpRdaR+k8ZIoi7noesryrf7ibZL+9VzZEBGlCcUGEIjQjL/BHsHa5vLfAJnT
|
|
9
|
-
0zbeQFk5MjGZOUPXC33CgidsxF3DsRFDNmOqGBiCf3A/ae/VOMDEyv6aFdKc6JQC
|
|
10
|
-
OoudnCGzVNJuLIa+/yGx9HhIjobbYGuZ7gwLjJk3HW9WixTupUKJME9f7cTIPW+k
|
|
11
|
-
ahw7ZQGzIUHejqy8cDnmBRYNpZ8NU5oTuhr5NFDWhOSGfM70NYFlGDifI2kMPhdc
|
|
12
|
-
s4nEUajG1b3NLBfKMM1HioqG2ivMQv6WNRWGJCn3sdJEXQIDAQABo0IwQDAPBgNV
|
|
13
|
-
HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUd1Pmdua66Xyn
|
|
14
|
-
qKIbXkVUC389WA8wDQYJKoZIhvcNAQELBQADggEBAD+6HGi8mdkHDnegma3AvQ0K
|
|
15
|
-
4EoTtKljui93zVhsaXpycr/UtOe7p6jBApBdh93up6Fx9cYu2OtTLh0t9rnLXBWD
|
|
16
|
-
GZQt1jajEwvdRg2ncFfoWkxeftUttd5uTVMN6Apv3nGw3VXZnNmVaRyZnGG5j1JO
|
|
17
|
-
lnN94DfE37MyePhuFCDd5RZXegIsel62AMPJNV/RtwPf5b7T59f/Ol1oTMkaWEtM
|
|
18
|
-
wYU/2cFTqGjtqeTv7IewTERbqBxJcvIU3pNVHthq/jyiiuaLeAybbx1AZoI3fkY8
|
|
19
|
-
FO1LAtZx1/xZwjqtSuTZn8CbryLoMetpvVqsUlI72FxStQf5JAFjO+H4kWEEORU=
|
|
20
|
-
-----END CERTIFICATE-----
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIDSzCCAjOgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEg
|
|
3
|
-
MB4GA1UECgwXUGF0cm9uIFRlc3QgQ2VydGlmaWNhdGUxHjAcBgNVBAMMFVBhdHJv
|
|
4
|
-
biBUZXN0IENsaWVudCBDQTAeFw0yNTAxMDEwMDAwMDBaFw00NTAxMDEwMDAwMDBa
|
|
5
|
-
MEwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKDBdQYXRyb24gVGVzdCBDZXJ0aWZpY2F0
|
|
6
|
-
ZTEbMBkGA1UEAwwScGF0cm9uLXRlc3QtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEF
|
|
7
|
-
AAOCAQ8AMIIBCgKCAQEAnp7kL8f5Yk/T6B+IRoLWvCTHeORa4ilp7ixTE4EJOwTB
|
|
8
|
-
atAfnoue4U+xMBAX91oIiGT8u5yKcC+EbvmvcOuOYQPCVXvx3bHBzeTzjBkH37k1
|
|
9
|
-
rBeXVxfhEnkXAANJOccTpPJRH2m+1X/FcXuUNKZOnSrc4G/Gpraj2Opygz8ntxbW
|
|
10
|
-
JR94mz1nkkAILlkCie4VFfSdnxE5ghQSnt8B7W9SdqSKD22NKpBmOff2x5136IEo
|
|
11
|
-
YNK7zYintgJfX6Pa7TR8peEVtAkl3/EjSEoSmfFQVZz2OB7IK3xFT2RyqoC9MjO6
|
|
12
|
-
2mItbD0LgZzTD3f91g00a7z6EjSW8g8QYc5pXSdC1wIDAQABozUwMzAMBgNVHRMB
|
|
13
|
-
Af8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkq
|
|
14
|
-
hkiG9w0BAQsFAAOCAQEAU/u+MOKWMXQqkPSQx2RjrOale3KKdkHX6LlGfZYjqMhn
|
|
15
|
-
IQjYbEfGtIKyD2MChXrhKMLwuwvMUaCMQWq0r9vZb2cz+AGDS/OzHui/YXgoUU/D
|
|
16
|
-
JOqmT17ClM1JIBZjfbLaogGGY//l4NA48MjhTDHw9MGOnnjzVYUy7CC6qiFu0onC
|
|
17
|
-
Ko+ZE0Ebb3KyjUeJLSCXEhTVW0myGc+/jNRJP0YW/TvxKRZ5EAhaJrLXvKm7tjil
|
|
18
|
-
SZpXBETiXq6eZZsD+XNfQvytBIFO4eBhv3sipQ8Ga30L3SqkMlsb4ptWpa5+z1Vk
|
|
19
|
-
BlkuYdKpPhD/nmx/OfRdfTItDVstm8Q13+MGS5Rokw==
|
|
20
|
-
-----END CERTIFICATE-----
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
-
Proc-Type: 4,ENCRYPTED
|
|
3
|
-
DEK-Info: AES-256-CBC,73A5C7F43CBFB22BDECED16E3F6D4014
|
|
4
|
-
|
|
5
|
-
s2DHo+hKzlo9ZFcql4V84w5c8OADkBHNYp3DJJSII+LSufiNLJ1JVcACEZdr/JsF
|
|
6
|
-
vLKTlCIjExGY1b85GPZ25PArB5jrZvWCcOFfs5PGzr3/ykRTfTMHSXo+WfFwkZ2x
|
|
7
|
-
2k/Zt8yVJ7f69G7EevTtVbkmx/wLMnlTSjMKfzWfs/f57GP+dWM5rHOiMBKK2KhC
|
|
8
|
-
OlD6yhKV4frmF9YTQlslrg5Nmd+3UQsSubT6s4qLByYrLm7pJHB9mx2LNLLQnoxv
|
|
9
|
-
IBIL+FcQRQvLtGGbzV42BHEqr6Kq7aqDf9RT6JohOMdGMYMtABZP9/iOqCUMT2QB
|
|
10
|
-
2/cio1jjgijHqpVBsPg9D493t0fm+1FXLK21wfvQgP6/v0wDB3YKlGlHzWWiVc2f
|
|
11
|
-
4EF/VAyPR8bJwpnZvQpsQ16HEftyyHTbishVbiqzvTNi4HnmSX6WQI2pwFHlF22j
|
|
12
|
-
UWJzSfLqp8NW340zo/EYDAm/dPaqVGR+pVtUEta+oGSI7OQWB3hGt7znSpdgFrah
|
|
13
|
-
i1IOkcu3fie15FzSlBtFhByigtz6iedrTCvYZhfswU4XxJfPJtlVnDubQ9xKDXp6
|
|
14
|
-
3xuy8R4ekMysSOGHq2NdOaYvOoMK8LAJ++KZwEe6UJfBDvEkC23V3mkoCKiUANDY
|
|
15
|
-
GuJ5SOqw6DF6cO/i+StvOuB+2mxMOhR4x893N/ntQrITYldvRh+QHNFoyKc5NUu4
|
|
16
|
-
035ezDVRDR4kzJzzTFfO9yshGFrqb7oyfUegzZMGah1sNn7AWG7AtBSbxSzmRk5s
|
|
17
|
-
0uBrBX7ASfMUGkpUV7BFsvDPi819k5iWLYLFPiFB/CJ5Wq0HHU4j9XDIa/dEuSe+
|
|
18
|
-
0HvQpYf/2IiYocxKxnZOXfdO06cigip1OjxbIXgx1uqrCyzB7c7XMLEUXETpdj1p
|
|
19
|
-
XPCvZ/9BaRNjWvvTrNNB2nMSarFdtjY6pB8bZtP4xObiQ59L3mLoL9/MD87Cnhzn
|
|
20
|
-
Gr8Yr3V5TJk8o60rWNNpaXeCbIlJONFN128uAP8vgjaYviHNb15ViDW1a57fO/OW
|
|
21
|
-
4XOt5jqVDC/NfQXADku7bcs1SPUOKbDgVeYiiq0na3t5yePNRZVcA6FEHuc9hDLi
|
|
22
|
-
T+Fp7bqxXa7pZMn9FOCJ0cRhtoD6LaIqNbtzCIU9u6HBbJkg36Nz7ysh3riYPKBI
|
|
23
|
-
ShLhSb+unI2owdWBi6QwDRus2FtcvPwPNrqtnZ1V5/YyFY6k7ScLR6R67A4ESKNJ
|
|
24
|
-
qIWQ0iCN9nCjbCGpO62e5BzwoVGXiTQK7QK1WPT95+E3Qlv8q6hGi32d5gMUNR1h
|
|
25
|
-
r8OmL+HXMZE2azKJB1mKldYznOYiSIJDjvSp/Jm4A+6zYB6wwiQWwZUUrmW7zbg0
|
|
26
|
-
o7PHImDvRj8hkJlpNRCqLKkyKF+/PaqkFx2dJxJT3xmVJ+H7wqmwhii1Y0RE9YHu
|
|
27
|
-
yzrL7vZpC2a2cjyJnlDG7sX4ZLPNg1vOEXcnKO/6+HHDLkmPQj85+mqHInrTvuca
|
|
28
|
-
GqC/JZeD8FMnpsWQC51ZwThbwlzq91kvFPhSxOqEequ0HP/1K3DdNhxQNKwQseV2
|
|
29
|
-
0jK0rCgibSroD8bE7kghtUPK/fts6XGRqgXmPmx9i3VJGbJw14GvKGp3oyosVEna
|
|
30
|
-
-----END RSA PRIVATE KEY-----
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
02rqpiG6KYI5KHCnjKeuiYXddlg0ay+o1UZ8TdRvfniI4Z8e5jMJGziLQze5ph2v
|
|
18
|
-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
-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
-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
-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
-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
-
JL1MA0/YAQjGtEswRaSNUZr5hePHAIeC74nQ0Qrlw0G+25kk+QKCAQEA2RhtyNsn
|
|
24
|
-
Wb6KUyr1umdcom0k7Sdg5uBP4koFjGG/1Ynz/uX1n7sfgOHRiSvg6hxOt/7fb4vd
|
|
25
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
dD96eVftTuavTkdFZdWB8wSwxDZX3uV4ir1t6bIKDoyz+yqYM3v3HfweJIq0ox2p
|
|
43
|
-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
-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
-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
-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
-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
-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
-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
-
vrkNxM3gbBkhFPAJ9LrmA4YExODUXzWt6Y2mCXuH2Ly60yiLa66HbEfhHrs=
|
|
51
|
-
-----END RSA PRIVATE KEY-----
|
|
Binary file
|