manticore 0.3.1-java → 0.3.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.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
|