manticore 0.3.1-java → 0.3.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +18 -0
- data/README.md +37 -3
- data/lib/manticore/client.rb +134 -33
- data/lib/manticore/version.rb +1 -1
- data/spec/manticore/client_spec.rb +97 -2
- data/spec/spec_helper.rb +23 -11
- data/spec/ssl/ca_cert.pem +33 -0
- data/spec/ssl/ca_key.pem +52 -0
- data/spec/ssl/client.p12 +0 -0
- data/spec/ssl/localhost.key +28 -0
- data/spec/ssl/localhost.pem +100 -0
- data/spec/ssl/readme.md +14 -0
- data/spec/ssl/test_truststore +0 -0
- metadata +17 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb2cec897fad8daff54f1823bb5a01f33da18d2e
|
4
|
+
data.tar.gz: 4ee22665fa497aceaa9b5df01c79264ef47a8667
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2be50f1dff4384bd95f61d6d5328aa4690461436c9d57dadae905fba897602b1c470d41763edca4955ea1d45f96f48ef80a52eccab4b3679e26bda1317cd78d6
|
7
|
+
data.tar.gz: 174cae4b6fef3465b339bbd4e831eed8aeb40284459102fe68fa32b3412b04460b3cbc8c649267339e50830263d0a894760fe14c55ee6c778c9370e021a6db45
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
## v0.3
|
2
|
+
### v0.3.3 (pending)
|
3
|
+
### v0.3.2
|
4
|
+
* :ignore_ssl_validation is now deprecated. It has been replaced with :ssl, which takes a hash of options. These include:
|
5
|
+
|
6
|
+
:verify - :strict (default), :browser, :none -- Specify hostname verification behaviors.
|
7
|
+
:protocols - An array of protocols to accept
|
8
|
+
:cipher_suites - An array of cipher suites to accept
|
9
|
+
:truststore - Path to a keytool trust store, for specifying custom trusted certificate signers
|
10
|
+
:truststore_password - Password for the file specified in `:truststore`
|
11
|
+
:truststore_type - Specify the trust store type (JKS, PKCS12)
|
12
|
+
:keystore - Path to a keytool trust store, for specifying client authentication certificates
|
13
|
+
:keystore_password - Password for the file specified in `:keystore`
|
14
|
+
:keystore_type - Specify the key store type (JKS, PKCS12)
|
15
|
+
|
16
|
+
(thanks @torrancew)
|
17
|
+
|
18
|
+
* Fix encodings for bodies (thanks @synhaptein)
|
19
|
+
|
2
20
|
### v0.3.1
|
3
21
|
* Added `automatic_retries` (default 3) parameter to client. The client will automatically retry requests that failed
|
4
22
|
due to socket exceptions and empty responses up to this number of times. The most practical effect of this setting is
|
data/README.md
CHANGED
@@ -47,9 +47,15 @@ If you don't want to worry about setting up and maintaining client pools, Mantic
|
|
47
47
|
|
48
48
|
```ruby
|
49
49
|
document_body = Manticore.get("http://www.google.com/").body
|
50
|
+
|
51
|
+
# Or
|
52
|
+
|
53
|
+
document_body = Manticore.http(:get, "http://www.google.com/").body
|
50
54
|
```
|
51
55
|
|
52
|
-
|
56
|
+
This is threadsafe and automatically backed with a pool, so you can execute `Manticore.get` in multiple threads without harming performance.
|
57
|
+
|
58
|
+
Alternately, you can mix the `Manticore::Facade` into your own class for similar behavior:
|
53
59
|
|
54
60
|
```ruby
|
55
61
|
class MyClient
|
@@ -74,9 +80,11 @@ class MyOtherClient
|
|
74
80
|
end
|
75
81
|
```
|
76
82
|
|
77
|
-
|
83
|
+
For detailed documentation, see the [full Manticore::Client documentation](http://www.rubydoc.info/github/cheald/manticore/master/Manticore/Client).
|
84
|
+
|
85
|
+
### Configuring clients
|
78
86
|
|
79
|
-
|
87
|
+
Rather than using the Facade, you can create your own standalone Client instances. When you create a `Client`, you will pass various parameters that it will use to set up the pool.
|
80
88
|
|
81
89
|
```ruby
|
82
90
|
client = Manticore::Client.new(request_timeout: 5, connect_timeout: 5, socket_timeout: 5, pool_max: 10, pool_max_per_route: 2)
|
@@ -99,6 +107,32 @@ client = Manticore::Client.new(socket_timeout: 5) do |http_client_builder, reque
|
|
99
107
|
end
|
100
108
|
```
|
101
109
|
|
110
|
+
### Pools
|
111
|
+
|
112
|
+
You've seen "pools" mentioned a few times. Manticore creates and configures a [PoolingHttpClientConnectionManager](http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html)
|
113
|
+
which all requests are run through. The advantage here is that configuration and setup is performed once, and this lets clients take advantage of things like keepalive,
|
114
|
+
per-route concurrency limits, and other neat things. In general, you should create one `Manticore::Client` instance pe unique configuration needed. For example, you might have an app that performs 2 functions:
|
115
|
+
|
116
|
+
1. General HTTP requesting from the internet-at-large
|
117
|
+
2. Communication with a backend service over SSL, using a custom trust store
|
118
|
+
|
119
|
+
To set this up, you might create 2 pools, each configured for the task:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
general_http_client = Manticore::Client.new connect_timeout: 10, socket_timeout: 10, request_timeout: 10, follow_redirects: true, max_per_route: 2
|
123
|
+
proxied_backend_client = Manticore::Client.new proxy: "https://backend.internal:4242", truststore: "./truststore.jks", truststore_password: "s3cr3t"
|
124
|
+
```
|
125
|
+
|
126
|
+
This would create 2 separate request pools; the first would be configured with generous timeouts and redirect following, and would use the system
|
127
|
+
default trust stores (ie, the normal certs used to verify SSL certificates with the normal certificate authorities). Additionally, it will only permit
|
128
|
+
2 concurrent requests to a given domain ("route") at a time; this can be nice for web crawling or fetching against rate-limited APIs, to help you stay
|
129
|
+
under your rate limits even when executing in a parallel context. The second client would use a custom trust store to recognize certs signed with your
|
130
|
+
internal CA, and would proxy all requests through an internal server.
|
131
|
+
|
132
|
+
Creating pools is expensive, so you don't want to be doing it for each request. Instead, you should set up your pools once and then re-use them.
|
133
|
+
Clients and their backing pools are thread-safe, so feel free to set them up once before you start performing parallel operations.
|
134
|
+
|
135
|
+
|
102
136
|
### Parallel execution
|
103
137
|
|
104
138
|
Manticore can perform concurrent execution of multiple requests.
|
data/lib/manticore/client.rb
CHANGED
@@ -48,11 +48,11 @@ module Manticore
|
|
48
48
|
#
|
49
49
|
# @!macro [new] http_method_shared_async_with_body
|
50
50
|
# @macro http_method_shared_async
|
51
|
-
# @option options [
|
51
|
+
# @option options [String] body Body to pass with the request
|
52
52
|
#
|
53
53
|
# @!macro [new] http_method_shared_sync_with_body
|
54
54
|
# @macro http_method_shared_sync
|
55
|
-
# @option options [
|
55
|
+
# @option options [String] body Body to pass with the request
|
56
56
|
|
57
57
|
# Core Manticore client, with a backing {http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html PoolingHttpClientConnectionManager}
|
58
58
|
class Client
|
@@ -60,6 +60,7 @@ module Manticore
|
|
60
60
|
include_package "org.apache.http.client.entity"
|
61
61
|
include_package "org.apache.http.client.config"
|
62
62
|
include_package "org.apache.http.config"
|
63
|
+
include_package "org.apache.http.conn.socket"
|
63
64
|
include_package "org.apache.http.impl"
|
64
65
|
include_package "org.apache.http.impl.client"
|
65
66
|
include_package "org.apache.http.impl.conn"
|
@@ -72,6 +73,8 @@ module Manticore
|
|
72
73
|
include_package "org.apache.http.client.protocol"
|
73
74
|
include_package 'org.apache.http.conn.ssl'
|
74
75
|
java_import "org.apache.http.HttpHost"
|
76
|
+
java_import "javax.net.ssl.SSLContext"
|
77
|
+
java_import "java.security.KeyStore"
|
75
78
|
|
76
79
|
include ProxiesInterface
|
77
80
|
|
@@ -101,27 +104,40 @@ module Manticore
|
|
101
104
|
# http_client_builder.disable_redirect_handling
|
102
105
|
# end
|
103
106
|
#
|
104
|
-
# @param options
|
105
|
-
# @option options [String]
|
106
|
-
# @option options [Integer]
|
107
|
-
# @option options [integer]
|
108
|
-
# @option options [boolean]
|
109
|
-
# @option options [boolean]
|
110
|
-
# @option options [integer]
|
111
|
-
# @option options [integer]
|
112
|
-
# @option options [integer]
|
113
|
-
# @option options [boolean]
|
114
|
-
# @option options [integer]
|
115
|
-
# @option options [integer]
|
116
|
-
# @option options [integer]
|
117
|
-
# @option options [boolean]
|
118
|
-
# @option options [boolean]
|
119
|
-
# @option options [String]
|
120
|
-
# @option options [Hash]
|
121
|
-
# @option options [URI]
|
122
|
-
# @option options [Boolean/
|
123
|
-
#
|
124
|
-
#
|
107
|
+
# @param options [Hash] Client pool options
|
108
|
+
# @option options [String] user_agent The user agent used in requests.
|
109
|
+
# @option options [Integer] pool_max (50) The maximum number of active connections in the pool
|
110
|
+
# @option options [integer] pool_max_per_route (pool_max) Sets the maximum number of active connections for a given target endpoint
|
111
|
+
# @option options [boolean] cookies (true) enable or disable automatic cookie management between requests
|
112
|
+
# @option options [boolean] compression (true) enable or disable transparent gzip/deflate support
|
113
|
+
# @option options [integer] request_timeout (60) Sets the timeout for requests. Raises {Manticore::Timeout} on failure.
|
114
|
+
# @option options [integer] connect_timeout (10) Sets the timeout for connections. Raises Manticore::Timeout on failure.
|
115
|
+
# @option options [integer] socket_timeout (10) Sets SO_TIMEOUT for open connections. A value of 0 is an infinite timeout. Raises Manticore::Timeout on failure.
|
116
|
+
# @option options [boolean] tcp_no_delay (true) Enable or disable Nagle's algorithm
|
117
|
+
# @option options [integer] request_timeout (60) Sets the timeout for a given request. Raises Manticore::Timeout on failure.
|
118
|
+
# @option options [integer] max_redirects (5) Sets the maximum number of redirects to follow.
|
119
|
+
# @option options [integer] automatic_retries (3) Sets the number of times the client will automatically retry failed requests.
|
120
|
+
# @option options [boolean] expect_continue (false) Enable support for HTTP 100
|
121
|
+
# @option options [boolean] stale_check (false) Enable support for stale connection checking. Adds overhead.
|
122
|
+
# @option options [String] proxy Proxy host in form: http://proxy.org:1234
|
123
|
+
# @option options [Hash] proxy Proxy host in form: {host: 'proxy.org'[, port: 80[, scheme: 'http']]}
|
124
|
+
# @option options [URI] proxy Proxy host as a URI object
|
125
|
+
# @option options [Boolean/Fixnum] keepalive (true) Whether to allow connections to be reused. Defaults to true. If an integer,
|
126
|
+
# then connections will be kept alive for this long when Connection: keep-alive
|
127
|
+
# is sent, but no Keep-Alive header is sent.
|
128
|
+
# @option options [Hash] ssl Hash of options for configuring SSL
|
129
|
+
# @option options [Array<String>] ssl[:protocols] (nil) A list of protocols that Manticore should accept
|
130
|
+
# @option options [Array<String>] ssl[:cipher_suites] (nil) A list of cipher suites that Manticore should accept
|
131
|
+
# @option options [Symbol] ssl[:verify] (:strict) Hostname verification setting. Set to `:disable` to turn off hostname verification. Setting to `:browser` will
|
132
|
+
# cause Manticore to accept a certificate for *.foo.com for all subdomains and sub-subdomains (eg a.b.foo.com).
|
133
|
+
# The default `:strict` is like `:browser` except it'll only accept a single level of subdomains for wildcards,
|
134
|
+
# eg `b.foo.com` will be accepted for a `*.foo.com` certificate, but `a.b.foo.com` will not be.
|
135
|
+
# @option options [String] ssl[:truststore] (nil) Path to a custom trust store to use the verifying SSL connections
|
136
|
+
# @option options [String] ssl[:truststore_password] (nil) Password used for decrypting the server trust store
|
137
|
+
# @option options [String] ssl[:truststore_type] (nil) Format of the trust store, ie "JKS" or "PKCS12". If left nil, the type will be inferred from the truststore filename.
|
138
|
+
# @option options [String] ssl[:keystore] (nil) Path to a custom key store to use for client certificate authentication
|
139
|
+
# @option options [String] ssl[:keystore_password] (nil) Password used for decrypting the client auth key store
|
140
|
+
# @option options [String] ssl[:keystore_type] (nil) Format of the key store, ie "JKS" or "PKCS12". If left nil, the type will be inferred from the keystore filename.
|
125
141
|
def initialize(options = {})
|
126
142
|
builder = client_builder
|
127
143
|
builder.set_user_agent options.fetch(:user_agent, "Manticore #{VERSION}")
|
@@ -241,6 +257,19 @@ module Manticore
|
|
241
257
|
end
|
242
258
|
end
|
243
259
|
|
260
|
+
# Perform an HTTP request, passing the method as a parameter
|
261
|
+
# @param method [String, Symbol] Method to call (get put head post options patch)
|
262
|
+
# @macro http_method_shared
|
263
|
+
# @macro http_request_exceptions
|
264
|
+
def http(method, url, options = {}, &block)
|
265
|
+
case method.to_s.downcase
|
266
|
+
when *%w(get put head post options patch)
|
267
|
+
send method, url, options, &block
|
268
|
+
else
|
269
|
+
raise "Invalid method: #{method}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
244
273
|
# Cause this client to return a stubbed response for this URL
|
245
274
|
# @param url [String] URL to stub for
|
246
275
|
# @param stubs [Hash] Hash of options to return for the stubbed response
|
@@ -289,14 +318,17 @@ module Manticore
|
|
289
318
|
end
|
290
319
|
|
291
320
|
def pool_builder(options)
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
PoolingHttpClientConnectionManager.new
|
321
|
+
http_sf = PlainConnectionSocketFactory.new
|
322
|
+
|
323
|
+
if options[:ignore_ssl_validation]
|
324
|
+
$stderr.puts 'The options[:ignore_ssl_validation] setting is deprecated in favor of options[:ssl][:verify]'
|
325
|
+
options[:ssl] ||= {}
|
326
|
+
options[:ssl] = {:verify => !options.delete(:ignore_ssl_validation)}.merge(options[:ssl])
|
299
327
|
end
|
328
|
+
|
329
|
+
https_sf = ssl_socket_factory_from_options options.fetch(:ssl, {})
|
330
|
+
registry = RegistryBuilder.create.register("http", http_sf).register("https", https_sf).build
|
331
|
+
PoolingHttpClientConnectionManager.new(registry)
|
300
332
|
end
|
301
333
|
|
302
334
|
def pool(options = {})
|
@@ -380,7 +412,7 @@ module Manticore
|
|
380
412
|
if options[:params]
|
381
413
|
req.set_entity hash_to_entity(options[:params])
|
382
414
|
elsif options[:body]
|
383
|
-
req.set_entity StringEntity.new(options[:body])
|
415
|
+
req.set_entity StringEntity.new(options[:body], minimum_encoding_for(options[:body]))
|
384
416
|
elsif options[:entity]
|
385
417
|
req.set_entity options[:entity]
|
386
418
|
end
|
@@ -442,10 +474,79 @@ module Manticore
|
|
442
474
|
end
|
443
475
|
|
444
476
|
def hash_to_entity(hash)
|
477
|
+
# This is a really stupid way to get the "lowest common denominator" encoding for the options hash
|
478
|
+
# Is there a better way?
|
479
|
+
encoding = minimum_encoding_for hash.to_a.flatten.join
|
445
480
|
pairs = hash.map do |key, val|
|
446
481
|
BasicNameValuePair.new(key, val)
|
447
482
|
end
|
448
|
-
UrlEncodedFormEntity.new(pairs)
|
483
|
+
UrlEncodedFormEntity.new(pairs, encoding)
|
484
|
+
end
|
485
|
+
|
486
|
+
# Apache HTTP assumes ISO_8859_1 for StringEntities; we'll try to be nice and pass that when possible
|
487
|
+
# so that it doesn't have to any multibyte work.
|
488
|
+
ISO_8859_1 = "ISO-8859-1".freeze
|
489
|
+
def minimum_encoding_for(string)
|
490
|
+
if string.ascii_only?
|
491
|
+
ISO_8859_1
|
492
|
+
else
|
493
|
+
string.encoding.to_s
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# Configure the SSL Context
|
498
|
+
def ssl_socket_factory_from_options(ssl_options)
|
499
|
+
trust_store = trust_strategy = nil
|
500
|
+
|
501
|
+
verifier = SSLConnectionSocketFactory::STRICT_HOSTNAME_VERIFIER
|
502
|
+
case ssl_options.fetch(:verify, :strict)
|
503
|
+
when false, :disable, :none
|
504
|
+
trust_store = nil
|
505
|
+
trust_strategy = TrustSelfSignedStrategy.new
|
506
|
+
verifier = SSLConnectionSocketFactory::ALLOW_ALL_HOSTNAME_VERIFIER
|
507
|
+
when :browser
|
508
|
+
verifier = SSLConnectionSocketFactory::BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
|
509
|
+
when true, :strict, :default
|
510
|
+
verifier = SSLConnectionSocketFactory::STRICT_HOSTNAME_VERIFIER
|
511
|
+
else
|
512
|
+
raise "Invalid value for :verify. Valid values are (:all, :browser, :default)"
|
513
|
+
end
|
514
|
+
|
515
|
+
|
516
|
+
context = SSLContexts.custom
|
517
|
+
|
518
|
+
trust_store = get_store(:truststore, ssl_options) if ssl_options.key?(:truststore)
|
519
|
+
context.load_trust_material(trust_store, trust_strategy)
|
520
|
+
|
521
|
+
if ssl_options.key?(:keystore)
|
522
|
+
key_store = get_store(:keystore, ssl_options)
|
523
|
+
context.load_key_material(key_store, ssl_options.fetch(:keystore_password, nil).to_java.toCharArray)
|
524
|
+
end
|
525
|
+
|
526
|
+
SSLConnectionSocketFactory.new context.build, ssl_options[:protocols], ssl_options[:cipher_suites], verifier
|
527
|
+
end
|
528
|
+
|
529
|
+
def get_trust_store(options)
|
530
|
+
get_store :truststore, options
|
531
|
+
end
|
532
|
+
|
533
|
+
def get_key_store(options)
|
534
|
+
get_store :keystore, options
|
535
|
+
end
|
536
|
+
|
537
|
+
def get_store(prefix, options)
|
538
|
+
KeyStore.get_instance(options[:"#{prefix}_type"] || guess_store_type(options[prefix])).tap do |store|
|
539
|
+
instream = open(options[prefix], "rb").to_inputstream
|
540
|
+
store.load(instream, options.fetch(:"#{prefix}_password", nil).to_java.toCharArray)
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
def guess_store_type(filename)
|
545
|
+
if filename.end_with?(".p12")
|
546
|
+
"pkcs12"
|
547
|
+
else
|
548
|
+
KeyStore.get_default_type
|
549
|
+
end
|
449
550
|
end
|
450
551
|
end
|
451
|
-
end
|
552
|
+
end
|
data/lib/manticore/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
java_import 'org.apache.http.entity.mime.MultipartEntityBuilder'
|
@@ -41,7 +42,7 @@ describe Manticore::Client do
|
|
41
42
|
j["uri"]["port"].should == 55441
|
42
43
|
end
|
43
44
|
|
44
|
-
describe "ignore_ssl_validation" do
|
45
|
+
describe "ignore_ssl_validation (deprecated option)" do
|
45
46
|
context "when on" do
|
46
47
|
let(:client) { Manticore::Client.new ignore_ssl_validation: true }
|
47
48
|
|
@@ -59,6 +60,90 @@ describe Manticore::Client do
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
63
|
+
describe 'ssl settings' do
|
64
|
+
describe 'verify' do
|
65
|
+
context 'default' do
|
66
|
+
let(:client) { Manticore::Client.new }
|
67
|
+
|
68
|
+
it "should break on SSL validation errors" do
|
69
|
+
expect { client.get("https://localhost:55444/").call }.to raise_exception(Manticore::ClientProtocolException)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when on and no trust store is given' do
|
74
|
+
let(:client) { Manticore::Client.new :ssl => {:verify => :strict} }
|
75
|
+
|
76
|
+
it "should break on SSL validation errors" do
|
77
|
+
expect { client.get("https://localhost:55444/").call }.to raise_exception(Manticore::ClientProtocolException)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when on and custom trust store is given' do
|
82
|
+
let(:client) { Manticore::Client.new :ssl => {verify: :strict, truststore: File.expand_path("../../ssl/test_truststore", __FILE__), truststore_password: "test123"} }
|
83
|
+
|
84
|
+
it "should verify the request and succeed" do
|
85
|
+
expect { client.get("https://localhost:55444/").body }.to_not raise_exception
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when on and custom trust store is given with the wrong password' do
|
90
|
+
let(:client) { Manticore::Client.new :ssl => {verify: :strict, truststore: File.expand_path("../../ssl/test_truststore", __FILE__), truststore_password: "wrongpass"} }
|
91
|
+
|
92
|
+
it "should fail to load the keystore" do
|
93
|
+
expect { client.get("https://localhost:55444/").body }.to raise_exception(Java::JavaIo::IOException)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when off' do
|
98
|
+
let(:client) { Manticore::Client.new :ssl => {:verify => :none} }
|
99
|
+
|
100
|
+
it "should not break on SSL validation errors" do
|
101
|
+
expect { client.get("https://localhost:55444/").body }.to_not raise_exception
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "against a server that verifies clients" do
|
106
|
+
context "when client cert auth is provided" do
|
107
|
+
let(:client) {
|
108
|
+
options = {
|
109
|
+
truststore: File.expand_path("../../ssl/test_truststore", __FILE__),
|
110
|
+
truststore_password: "test123",
|
111
|
+
keystore: File.expand_path("../../ssl/client.p12", __FILE__),
|
112
|
+
keystore_password: ""
|
113
|
+
}
|
114
|
+
Manticore::Client.new :ssl => options.merge(verify: :strict)
|
115
|
+
}
|
116
|
+
|
117
|
+
it "should successfully auth requests" do
|
118
|
+
expect(client.get("https://localhost:55445/").body).to match("hello")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when client cert auth is not provided" do
|
123
|
+
let(:client) {
|
124
|
+
options = {
|
125
|
+
truststore: File.expand_path("../../ssl/test_truststore", __FILE__),
|
126
|
+
truststore_password: "test123"
|
127
|
+
}
|
128
|
+
Manticore::Client.new :ssl => options.merge(verify: :strict)
|
129
|
+
}
|
130
|
+
|
131
|
+
it "should fail the request" do
|
132
|
+
expect { client.get("https://localhost:55445/").body }.to raise_exception(Manticore::ClientProtocolException)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe ":cipher_suites" do
|
139
|
+
pending
|
140
|
+
end
|
141
|
+
|
142
|
+
describe ":protocols" do
|
143
|
+
pending
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
62
147
|
describe "lazy evaluation" do
|
63
148
|
it "should not call synchronous requests by default" do
|
64
149
|
req = client.get(local_server)
|
@@ -231,9 +316,19 @@ describe Manticore::Client do
|
|
231
316
|
JSON.load(response.body)["body"].should == "This is a post body"
|
232
317
|
end
|
233
318
|
|
319
|
+
it "should send a UTF-8 body" do
|
320
|
+
response = client.post(local_server, body: "This is a post body ∑")
|
321
|
+
JSON.load(response.body)["body"].should == "This is a post body ∑"
|
322
|
+
end
|
323
|
+
|
234
324
|
it "should send params" do
|
235
325
|
response = client.post(local_server, params: {key: "value"})
|
236
|
-
JSON.load(response.body)["body"].should == "key=value"
|
326
|
+
CGI.unescape(JSON.load(response.body)["body"]).should == "key=value"
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should send non-ASCII params" do
|
330
|
+
response = client.post(local_server, params: {"∑" => "√"})
|
331
|
+
CGI.unescape(JSON.load(response.body)["body"]).should == "∑=√"
|
237
332
|
end
|
238
333
|
|
239
334
|
it "should send an arbitrary entity" do
|
data/spec/spec_helper.rb
CHANGED
@@ -6,6 +6,7 @@ require 'json'
|
|
6
6
|
require 'rack'
|
7
7
|
require 'webrick'
|
8
8
|
require 'webrick/https'
|
9
|
+
require 'openssl'
|
9
10
|
|
10
11
|
PORT = 55441
|
11
12
|
|
@@ -16,14 +17,14 @@ end
|
|
16
17
|
def read_nonblock(socket)
|
17
18
|
buffer = ""
|
18
19
|
loop {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
begin
|
21
|
+
buffer << socket.read_nonblock(4096)
|
22
|
+
rescue Errno::EAGAIN
|
23
|
+
# Resource temporarily unavailable - read would block
|
24
|
+
break
|
25
|
+
end
|
25
26
|
}
|
26
|
-
buffer
|
27
|
+
buffer.force_encoding("UTF-8")
|
27
28
|
end
|
28
29
|
|
29
30
|
def start_server(port = PORT)
|
@@ -37,7 +38,7 @@ def start_server(port = PORT)
|
|
37
38
|
end
|
38
39
|
|
39
40
|
if cl = request[:headers]["Content-Length"] || request[:headers]["Transfer-Encoding"] == "chunked"
|
40
|
-
request[:body] = read_nonblock
|
41
|
+
request[:body] = read_nonblock(stream.socket)
|
41
42
|
end
|
42
43
|
|
43
44
|
content_type = request[:headers]["X-Content-Type"] || "text/plain"
|
@@ -87,18 +88,28 @@ def stop_servers
|
|
87
88
|
@servers.values.each(&:kill) if @servers
|
88
89
|
end
|
89
90
|
|
90
|
-
def start_ssl_server(port)
|
91
|
+
def start_ssl_server(port, options = {})
|
91
92
|
cert_name = [
|
92
93
|
%w[CN localhost],
|
93
94
|
]
|
95
|
+
cert = OpenSSL::X509::Certificate.new File.read(File.expand_path('../ssl/localhost.pem', __FILE__))
|
96
|
+
pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path('../ssl/localhost.key', __FILE__))
|
94
97
|
@servers[port] = Thread.new {
|
95
|
-
server = WEBrick::HTTPServer.new(
|
98
|
+
server = WEBrick::HTTPServer.new(
|
99
|
+
{
|
100
|
+
:Port => port,
|
101
|
+
:SSLEnable => true,
|
102
|
+
:SSLCertificate => cert,
|
103
|
+
:SSLPrivateKey => pkey,
|
104
|
+
:AccessLog => [],
|
105
|
+
:Logger => WEBrick::Log.new("/dev/null")
|
106
|
+
}.merge(options)
|
107
|
+
)
|
96
108
|
server.mount_proc "/" do |req, res|
|
97
109
|
res.body = "hello!"
|
98
110
|
end
|
99
111
|
|
100
112
|
server.start
|
101
|
-
puts "Server started?"
|
102
113
|
}
|
103
114
|
end
|
104
115
|
|
@@ -110,6 +121,7 @@ RSpec.configure do |c|
|
|
110
121
|
start_server 55441
|
111
122
|
start_server 55442
|
112
123
|
start_ssl_server 55444
|
124
|
+
start_ssl_server 55445, :SSLVerifyClient => OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, :SSLCACertificateFile => File.expand_path("../ssl/ca_cert.pem", __FILE__)
|
113
125
|
}
|
114
126
|
|
115
127
|
c.after(:suite) { stop_servers }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
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
|
32
|
+
wuhTyH5RfnYu
|
33
|
+
-----END CERTIFICATE-----
|
data/spec/ssl/ca_key.pem
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
2
|
+
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
|
51
|
+
umjprdvaT6QOMOjb1GZqJhdCLskcB/w=
|
52
|
+
-----END PRIVATE KEY-----
|
data/spec/ssl/client.p12
ADDED
Binary file
|
@@ -0,0 +1,28 @@
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
2
|
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4I1J9AVuytCuy
|
3
|
+
BlmDQD/ZhJygHhLhGN2ZBPd2mBs0OfnNO2ert9zo5jUaRvHAKhTs6/gmmMd2U39R
|
4
|
+
TnN4cqHtEVbyDp/97zY4v75rL9iILk8l18qJVSbdsbEdZ9fyuj9MnLNY+J100FVS
|
5
|
+
jfNIR+mCunVPjI+Mb2tooSOZKovdcTZVZcLVwnnkXsPbDFOZbWp3V0v0vqyYxAQB
|
6
|
+
sLEypEtt1fzKrL0gevTCsRFYxsUbjdaJmb4E63hKAr+PkrjXT6r6gR4oWjFejoIm
|
7
|
+
OhEZxm1H6cLwBWK/PM55b7kdV9pNUetXTNz5uTjKx0512rsBC9GZK9rM/wATI1o+
|
8
|
+
KsXSxuDnAgMBAAECggEAG2OFnXpaPVZ3OV+gaNlhpeUHtvlCLaEZNO18MXOmeDo3
|
9
|
+
YcN4RB5xCWNUergatU6NFkBzBKqs4HjC80EMA9ppI2301MRAH/E4y3AZzq+rMXZR
|
10
|
+
53sVcR/tTARmJ82OXVg+mhKkypMQOJPUXRcoHJQ1s3AwisiJgYYBH+r39IxTiXhQ
|
11
|
+
vMuiUFHmQSn7TAsDV9ULMvYmMh4FA+9RVW1DJ9zH5/IQKtRyLVupulGimF8n0kVR
|
12
|
+
tNVqwTckZpJJlZFdLHUjaTiSm4s5vYwoxNzNXxZ0GnBXBxs5YAErEjas/OhmYguZ
|
13
|
+
lFwpkVuV9/dwR4jfPRciGuRuJqO2I2Pp6K6/Z+QLoQKBgQDmYRNnOfESwaqVWh9G
|
14
|
+
VmT70bhob5A2GwVS2fJ+UOBCfnwrn+ybR2AZjliKlM4a6k+pboPrwl4rncH2LlXO
|
15
|
+
o/EX9VyTdDCMxiN+YMlvOuzpVF1LrM/BL6pw3uMjmWBEMmbprwiMFCKRC4BJZ3Vv
|
16
|
+
X07A1zoKq8oNFW+m80Db1eMciwKBgQDMncDJLJFBqIcas5plUlwTQXmr8Xq/+Q/B
|
17
|
+
UB4yU75eUbp1H0jFrJ8ier6A1IXX2bVnxUjilATM/trIH4GLMK66j5hp0ih0JfjE
|
18
|
+
gYnI83GKOxL+KF0C2tLjjhuTAVtmWXla8s37dBtz3ZleyyKfaGzvgm3zjheD+s/R
|
19
|
+
ordHaRpMlQKBgEOvq9q9TFX9bpf45Y1t3reZ03tjo9Qxtiu0eymfq3P944+Rqhup
|
20
|
+
KdP4XY1B0RhZVVRrcvj2n2JjNFSXIoDW7APlA/ESxxzlLhJ4b1Zt0qNvNQYB3Pxe
|
21
|
+
e84zvjp8WqtOv6vS0EkPtWQ2I9ftPLSfJO1FjvkJphCYBrjfaWPtgI+nAoGBAMOS
|
22
|
+
RKIEJxJKslejMv+FKNx+yHy/4kN7GsP6f+I6iMo986nerP/DbpbWGx+oAgW94NW+
|
23
|
+
i1uFftExBowhEQCpF1jZxyPd6yyY3p1z8u5PQUaOECk9CymfXdKCEXkA4wuAma2E
|
24
|
+
Rb0BzPuB4wXnwr/6X6TNVaplNbTAFcKZc/SdULXBAoGBAM02iPIys9ghA1nfQHD+
|
25
|
+
MD4lJNyPzOrnx1C8SXPP/hHUbFRmZF9hW3U9vuwo7jD2MzIrHAycAaIUjIDkTD+w
|
26
|
+
rUYsH9nOAHCbk1lGqy24SF4Pcvpj28O4gfHBdBEq4c2b48moml3tJOPOTEude8fp
|
27
|
+
PgYaeX3y+gzY7K7ZSM+gIuuo
|
28
|
+
-----END PRIVATE KEY-----
|
@@ -0,0 +1,100 @@
|
|
1
|
+
Certificate:
|
2
|
+
Data:
|
3
|
+
Version: 3 (0x2)
|
4
|
+
Serial Number: 3 (0x3)
|
5
|
+
Signature Algorithm: sha256WithRSAEncryption
|
6
|
+
Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com
|
7
|
+
Validity
|
8
|
+
Not Before: Nov 29 00:38:23 2014 GMT
|
9
|
+
Not After : Aug 25 00:38:23 2017 GMT
|
10
|
+
Subject: C=US, ST=Arizona, L=NA, O=Manticore, OU=Manticore, CN=localhost
|
11
|
+
Subject Public Key Info:
|
12
|
+
Public Key Algorithm: rsaEncryption
|
13
|
+
Public-Key: (2048 bit)
|
14
|
+
Modulus:
|
15
|
+
00:b8:23:52:7d:01:5b:b2:b4:2b:b2:06:59:83:40:
|
16
|
+
3f:d9:84:9c:a0:1e:12:e1:18:dd:99:04:f7:76:98:
|
17
|
+
1b:34:39:f9:cd:3b:67:ab:b7:dc:e8:e6:35:1a:46:
|
18
|
+
f1:c0:2a:14:ec:eb:f8:26:98:c7:76:53:7f:51:4e:
|
19
|
+
73:78:72:a1:ed:11:56:f2:0e:9f:fd:ef:36:38:bf:
|
20
|
+
be:6b:2f:d8:88:2e:4f:25:d7:ca:89:55:26:dd:b1:
|
21
|
+
b1:1d:67:d7:f2:ba:3f:4c:9c:b3:58:f8:9d:74:d0:
|
22
|
+
55:52:8d:f3:48:47:e9:82:ba:75:4f:8c:8f:8c:6f:
|
23
|
+
6b:68:a1:23:99:2a:8b:dd:71:36:55:65:c2:d5:c2:
|
24
|
+
79:e4:5e:c3:db:0c:53:99:6d:6a:77:57:4b:f4:be:
|
25
|
+
ac:98:c4:04:01:b0:b1:32:a4:4b:6d:d5:fc:ca:ac:
|
26
|
+
bd:20:7a:f4:c2:b1:11:58:c6:c5:1b:8d:d6:89:99:
|
27
|
+
be:04:eb:78:4a:02:bf:8f:92:b8:d7:4f:aa:fa:81:
|
28
|
+
1e:28:5a:31:5e:8e:82:26:3a:11:19:c6:6d:47:e9:
|
29
|
+
c2:f0:05:62:bf:3c:ce:79:6f:b9:1d:57:da:4d:51:
|
30
|
+
eb:57:4c:dc:f9:b9:38:ca:c7:4e:75:da:bb:01:0b:
|
31
|
+
d1:99:2b:da:cc:ff:00:13:23:5a:3e:2a:c5:d2:c6:
|
32
|
+
e0:e7
|
33
|
+
Exponent: 65537 (0x10001)
|
34
|
+
X509v3 extensions:
|
35
|
+
X509v3 Subject Key Identifier:
|
36
|
+
00:AD:24:E9:F6:F5:82:D6:44:2E:DB:A3:16:75:E4:B9:56:5E:87:55
|
37
|
+
X509v3 Authority Key Identifier:
|
38
|
+
keyid:C8:B7:44:26:1E:FA:12:7F:5E:DE:C1:D0:A8:91:36:CE:43:A5:8A:41
|
39
|
+
|
40
|
+
X509v3 Basic Constraints:
|
41
|
+
CA:FALSE
|
42
|
+
X509v3 Key Usage:
|
43
|
+
Digital Signature, Non Repudiation, Key Encipherment
|
44
|
+
Signature Algorithm: sha256WithRSAEncryption
|
45
|
+
99:1b:a2:a5:63:03:22:70:62:4a:ff:3d:c7:46:53:25:9d:4c:
|
46
|
+
9c:73:4f:b6:fa:cd:7a:57:cb:96:3b:8f:58:4e:26:b4:30:ea:
|
47
|
+
39:25:ad:8f:f9:ce:8c:87:ef:fc:5a:8e:94:3e:37:ac:35:e2:
|
48
|
+
d1:4f:e2:1c:59:33:4c:19:08:33:53:6b:d3:da:d1:2b:7a:90:
|
49
|
+
2a:15:f6:49:4f:95:4a:34:46:a1:a6:43:15:2d:c5:bc:e8:1b:
|
50
|
+
9a:1c:bd:f3:01:b1:60:16:5d:7e:1b:52:9c:08:d6:b8:2e:68:
|
51
|
+
2c:68:11:65:52:8a:52:fa:86:ee:a7:9f:bc:a7:54:a0:4d:3e:
|
52
|
+
78:4a:f6:fb:a5:ed:83:51:68:93:e5:46:c4:c9:30:ff:76:ee:
|
53
|
+
e3:e6:cd:c6:7f:1f:19:61:01:0d:5e:05:c3:38:fa:c2:dd:c3:
|
54
|
+
ec:0a:18:5e:bf:66:6b:c1:09:9b:38:47:43:69:09:9f:91:ff:
|
55
|
+
4c:2c:71:d9:4a:63:0a:84:68:ef:ac:d3:29:f8:16:dc:d5:3f:
|
56
|
+
38:8b:14:a1:a6:00:c2:b4:5d:53:7f:14:ce:fc:74:f4:cc:c2:
|
57
|
+
ee:9f:b6:9c:22:6c:af:1c:a5:ee:36:f7:ef:f2:02:80:18:69:
|
58
|
+
eb:ec:bc:03:df:b6:e1:3f:6f:a2:26:57:a0:6b:23:2f:05:bd:
|
59
|
+
7a:36:db:41:7f:2e:30:b4:06:a6:47:9d:a7:8a:f3:3b:6e:b8:
|
60
|
+
b1:86:14:a0:38:2c:64:14:cb:df:4e:b3:47:f4:a0:e1:50:02:
|
61
|
+
cc:20:db:01:31:77:35:35:e9:ad:2b:f5:4f:f9:40:35:fb:1a:
|
62
|
+
ad:33:fd:37:7d:e9:52:65:11:df:d6:6a:9e:dd:ed:54:c1:25:
|
63
|
+
71:33:08:5b:62:18:67:c8:4e:d6:82:64:f7:d7:3b:b8:9d:5d:
|
64
|
+
55:36:fc:6f:da:97:56:48:91:28:e8:fa:38:5f:a3:c6:60:b5:
|
65
|
+
35:f0:a9:bf:15:40:d0:fb:3a:42:df:e8:25:82:ff:19:93:a8:
|
66
|
+
57:dc:f2:2c:5f:de:1a:13:c6:c9:e3:5d:a8:f7:d9:6e:66:0d:
|
67
|
+
3e:fc:ea:59:25:89:2c:ff:91:0e:3e:08:83:25:2f:f2:de:3e:
|
68
|
+
ec:be:27:64:3c:84:20:20:47:1b:2a:e6:1f:33:6c:15:af:86:
|
69
|
+
79:86:a5:0a:12:d3:89:0b:82:b4:98:cc:02:7b:ef:b6:4f:5a:
|
70
|
+
ef:96:7a:d9:51:dc:b7:41:b4:a3:23:6a:ed:32:22:76:88:b6:
|
71
|
+
ec:e5:be:cb:a6:98:b3:35:d5:74:7e:5f:1c:97:a3:ac:f6:75:
|
72
|
+
e0:98:64:57:4c:22:ea:c4:93:37:cb:74:28:c6:a0:fe:eb:ec:
|
73
|
+
48:00:cc:06:97:de:82:7c
|
74
|
+
-----BEGIN CERTIFICATE-----
|
75
|
+
MIIEnjCCAoagAwIBAgIBAzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
|
76
|
+
MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
|
77
|
+
QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDExMjkwMDM4
|
78
|
+
MjNaFw0xNzA4MjUwMDM4MjNaMGgxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6
|
79
|
+
b25hMQswCQYDVQQHDAJOQTESMBAGA1UECgwJTWFudGljb3JlMRIwEAYDVQQLDAlN
|
80
|
+
YW50aWNvcmUxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD
|
81
|
+
ggEPADCCAQoCggEBALgjUn0BW7K0K7IGWYNAP9mEnKAeEuEY3ZkE93aYGzQ5+c07
|
82
|
+
Z6u33OjmNRpG8cAqFOzr+CaYx3ZTf1FOc3hyoe0RVvIOn/3vNji/vmsv2IguTyXX
|
83
|
+
yolVJt2xsR1n1/K6P0ycs1j4nXTQVVKN80hH6YK6dU+Mj4xva2ihI5kqi91xNlVl
|
84
|
+
wtXCeeRew9sMU5ltandXS/S+rJjEBAGwsTKkS23V/MqsvSB69MKxEVjGxRuN1omZ
|
85
|
+
vgTreEoCv4+SuNdPqvqBHihaMV6OgiY6ERnGbUfpwvAFYr88znlvuR1X2k1R61dM
|
86
|
+
3Pm5OMrHTnXauwEL0Zkr2sz/ABMjWj4qxdLG4OcCAwEAAaNaMFgwHQYDVR0OBBYE
|
87
|
+
FACtJOn29YLWRC7boxZ15LlWXodVMB8GA1UdIwQYMBaAFMi3RCYe+hJ/Xt7B0KiR
|
88
|
+
Ns5DpYpBMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEBCwUAA4IC
|
89
|
+
AQCZG6KlYwMicGJK/z3HRlMlnUycc0+2+s16V8uWO49YTia0MOo5Ja2P+c6Mh+/8
|
90
|
+
Wo6UPjesNeLRT+IcWTNMGQgzU2vT2tErepAqFfZJT5VKNEahpkMVLcW86BuaHL3z
|
91
|
+
AbFgFl1+G1KcCNa4LmgsaBFlUopS+obup5+8p1SgTT54Svb7pe2DUWiT5UbEyTD/
|
92
|
+
du7j5s3Gfx8ZYQENXgXDOPrC3cPsChhev2ZrwQmbOEdDaQmfkf9MLHHZSmMKhGjv
|
93
|
+
rNMp+Bbc1T84ixShpgDCtF1TfxTO/HT0zMLun7acImyvHKXuNvfv8gKAGGnr7LwD
|
94
|
+
37bhP2+iJlegayMvBb16NttBfy4wtAamR52nivM7brixhhSgOCxkFMvfTrNH9KDh
|
95
|
+
UALMINsBMXc1NemtK/VP+UA1+xqtM/03felSZRHf1mqe3e1UwSVxMwhbYhhnyE7W
|
96
|
+
gmT31zu4nV1VNvxv2pdWSJEo6Po4X6PGYLU18Km/FUDQ+zpC3+glgv8Zk6hX3PIs
|
97
|
+
X94aE8bJ412o99luZg0+/OpZJYks/5EOPgiDJS/y3j7svidkPIQgIEcbKuYfM2wV
|
98
|
+
r4Z5hqUKEtOJC4K0mMwCe++2T1rvlnrZUdy3QbSjI2rtMiJ2iLbs5b7LppizNdV0
|
99
|
+
fl8cl6Os9nXgmGRXTCLqxJM3y3QoxqD+6+xIAMwGl96CfA==
|
100
|
+
-----END CERTIFICATE-----
|
data/spec/ssl/readme.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
test_truststore is a trust store which has trusted the cacert.pem certificate
|
2
|
+
|
3
|
+
localhost.pem is a server certificate signed by our test CA
|
4
|
+
|
5
|
+
We can test custom trust stores by:
|
6
|
+
|
7
|
+
1. Starting a server which uses localhost.pem/localhost.key to serve SSL
|
8
|
+
2. Trusting ca_cert.pem (via the test_truststore)
|
9
|
+
|
10
|
+
And then verifying that SSL operations complete successfully.
|
11
|
+
|
12
|
+
The test_truststore password is `test123`
|
13
|
+
|
14
|
+
You should never use these certificates or keys for anything other than testing Manticore's SSL behavior.
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manticore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Chris Heald
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
E7PWS50D9moUJ6xWcemf0qKYC87qBFh0ng73awjG9uf+13lMslqJRMtek8C92cvh
|
31
31
|
+R9zgQlbeNjy9O1i
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-
|
33
|
+
date: 2014-12-11 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: addressable
|
@@ -114,6 +114,13 @@ files:
|
|
114
114
|
- spec/manticore/response_spec.rb
|
115
115
|
- spec/manticore/stubbed_response_spec.rb
|
116
116
|
- spec/spec_helper.rb
|
117
|
+
- spec/ssl/ca_cert.pem
|
118
|
+
- spec/ssl/ca_key.pem
|
119
|
+
- spec/ssl/client.p12
|
120
|
+
- spec/ssl/localhost.key
|
121
|
+
- spec/ssl/localhost.pem
|
122
|
+
- spec/ssl/readme.md
|
123
|
+
- spec/ssl/test_truststore
|
117
124
|
homepage: https://github.com/cheald/manticore
|
118
125
|
licenses:
|
119
126
|
- MIT
|
@@ -134,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
141
|
version: '0'
|
135
142
|
requirements: []
|
136
143
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.1.9
|
138
145
|
signing_key:
|
139
146
|
specification_version: 4
|
140
147
|
summary: Manticore is an HTTP client built on the Apache HttpCore components
|
@@ -146,3 +153,10 @@ test_files:
|
|
146
153
|
- spec/manticore/response_spec.rb
|
147
154
|
- spec/manticore/stubbed_response_spec.rb
|
148
155
|
- spec/spec_helper.rb
|
156
|
+
- spec/ssl/ca_cert.pem
|
157
|
+
- spec/ssl/ca_key.pem
|
158
|
+
- spec/ssl/client.p12
|
159
|
+
- spec/ssl/localhost.key
|
160
|
+
- spec/ssl/localhost.pem
|
161
|
+
- spec/ssl/readme.md
|
162
|
+
- spec/ssl/test_truststore
|
metadata.gz.sig
CHANGED
Binary file
|