manticore 0.7.0-java → 0.7.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -5
- data/CHANGELOG.md +9 -1
- data/README.md +17 -4
- data/lib/manticore.rb +26 -2
- data/lib/manticore/client.rb +20 -13
- data/lib/manticore/response.rb +12 -12
- data/lib/manticore/version.rb +1 -1
- data/manticore.gemspec +2 -0
- data/spec/manticore/client_spec.rb +14 -2
- data/spec/manticore/response_spec.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67e67c0611ad51fbaf279f456ef5a9e463038f1017c0eb8c7665032a05534b59
|
4
|
+
data.tar.gz: 0ecf2a3014befbbc5b26d95c3ee36809ccc8605e450631e4ec0f1c143225bbc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19f7db686cff19817b8310f7838f9115d343ab7516e7cbab066c0f0f7d223c7a0a42c40f9e361426c07345088dbdb818cabab59fb2a481d35050f939e27afafd
|
7
|
+
data.tar.gz: ebc35118980baac6eff3e1f795f5ad3aa0af01c7ac29cd6a9502f9300fb1da88d8b97ecfc7c1198d5902a35ab2501179df775791e3306e27004e85d690145bc2
|
data/.travis.yml
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
dist:
|
1
|
+
dist: trusty # due Oracle JDK
|
2
2
|
language: ruby
|
3
3
|
cache:
|
4
4
|
- bundler
|
5
5
|
- directories:
|
6
6
|
- $HOME/.m2
|
7
7
|
rvm:
|
8
|
-
- jruby-9.
|
9
|
-
- jruby-9.2.13.0 # Ruby 2.5
|
8
|
+
- jruby-9.2.16.0 # Ruby 2.5
|
10
9
|
jdk:
|
11
|
-
-
|
10
|
+
- oraclejdk8
|
11
|
+
- openjdk8
|
12
12
|
- openjdk11
|
13
13
|
before_install:
|
14
14
|
- gem install bundler -v 1.17.3
|
15
15
|
matrix:
|
16
16
|
include:
|
17
17
|
- rvm: jruby-head
|
18
|
-
jdk:
|
18
|
+
jdk: openjdk11
|
19
|
+
- rvm: jruby-9.1.17.0 # Ruby 2.3
|
20
|
+
jdk: openjdk8
|
19
21
|
allow_failures:
|
20
22
|
- rvm: jruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
## v0.
|
1
|
+
## v0.7
|
2
|
+
|
3
|
+
### v0.7.1
|
4
|
+
|
5
|
+
* Don't override certificates with same Subject (#93)
|
6
|
+
* Set Java cause for ManticoreException types (#96)
|
7
|
+
* Fix SSL handshake hang indefinitely (#98)
|
2
8
|
|
3
9
|
### v0.7.0
|
4
10
|
|
5
11
|
* Drop support for JRuby 1.7. It probably still works, but we don't test against it anymore
|
6
12
|
* Fix a thread safety issue with regards to adding requests to the parallel execution queue while the client is already processing a queue (#80)
|
7
13
|
|
14
|
+
## v0.6
|
15
|
+
|
8
16
|
### v0.6.4
|
9
17
|
|
10
18
|
* client_cert and client_key now take the literal keys as strings, OpenSSL::X509::Certificate/OpenSSL::PKey::Pkey instances, or key file paths. (#77)
|
data/README.md
CHANGED
@@ -90,7 +90,11 @@ For detailed documentation, see the [full Manticore::Client documentation](http:
|
|
90
90
|
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.
|
91
91
|
|
92
92
|
```ruby
|
93
|
-
client = Manticore::Client.new(request_timeout: 5,
|
93
|
+
client = Manticore::Client.new(request_timeout: 5,
|
94
|
+
connect_timeout: 5,
|
95
|
+
socket_timeout: 5,
|
96
|
+
pool_max: 10,
|
97
|
+
pool_max_per_route: 2)
|
94
98
|
```
|
95
99
|
|
96
100
|
Then, you can make requests from the client. Pooling and route maximum constraints are automatically managed:
|
@@ -122,11 +126,20 @@ per-route concurrency limits, and other neat things. In general, you should crea
|
|
122
126
|
To set this up, you might create 2 pools, each configured for the task:
|
123
127
|
|
124
128
|
```ruby
|
125
|
-
general_http_client = Manticore::Client.new
|
129
|
+
general_http_client = Manticore::Client.new(connect_timeout: 10,
|
130
|
+
socket_timeout: 10,
|
131
|
+
request_timeout: 10,
|
132
|
+
follow_redirects: true,
|
133
|
+
max_per_route: 2)
|
126
134
|
# With an OpenSSL CA store
|
127
|
-
proxied_backend_client = Manticore::Client.new
|
135
|
+
proxied_backend_client = Manticore::Client.new(proxy: "https://backend.internal:4242",
|
136
|
+
ssl: { ca_file: "my_certs.pem" })
|
128
137
|
# Or with a .jks truststore
|
129
|
-
|
138
|
+
proxied_backend_client = Manticore::Client.new(proxy: "https://backend.internal:4242",
|
139
|
+
ssl: {
|
140
|
+
truststore: "./truststore.jks",
|
141
|
+
truststore_password: "s3cr3t"
|
142
|
+
})
|
130
143
|
```
|
131
144
|
|
132
145
|
This would create 2 separate request pools; the first would be configured with generous timeouts and redirect following, and would use the system
|
data/lib/manticore.rb
CHANGED
@@ -5,7 +5,11 @@ require "cgi"
|
|
5
5
|
require_relative "./manticore_jars.rb"
|
6
6
|
require_relative "./org/manticore/manticore-ext"
|
7
7
|
|
8
|
-
|
8
|
+
if defined? JRuby::Util.load_ext
|
9
|
+
JRuby::Util.load_ext 'org.manticore.Manticore'
|
10
|
+
else
|
11
|
+
org.manticore.Manticore.new.load(JRuby.runtime, false)
|
12
|
+
end
|
9
13
|
|
10
14
|
require_relative "./manticore/version"
|
11
15
|
|
@@ -13,7 +17,27 @@ require_relative "./manticore/version"
|
|
13
17
|
# with the beauty of Ruby.
|
14
18
|
module Manticore
|
15
19
|
# General base class for all Manticore exceptions
|
16
|
-
class ManticoreException < StandardError
|
20
|
+
class ManticoreException < StandardError
|
21
|
+
def initialize(arg = nil)
|
22
|
+
case arg
|
23
|
+
when nil
|
24
|
+
@_cause = nil
|
25
|
+
super()
|
26
|
+
when java.lang.Throwable
|
27
|
+
@_cause = arg
|
28
|
+
super(arg.message)
|
29
|
+
else
|
30
|
+
@_cause = nil
|
31
|
+
super(arg)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return cause which is likely to be a Java exception
|
36
|
+
# @overload Exception#cause
|
37
|
+
def cause
|
38
|
+
@_cause || super
|
39
|
+
end
|
40
|
+
end
|
17
41
|
|
18
42
|
# Exception thrown if you attempt to read from a closed Response stream
|
19
43
|
class StreamClosedException < ManticoreException; end
|
data/lib/manticore/client.rb
CHANGED
@@ -69,10 +69,8 @@ module Manticore
|
|
69
69
|
include_package "org.apache.http.client.config"
|
70
70
|
include_package "org.apache.http.config"
|
71
71
|
include_package "org.apache.http.conn.socket"
|
72
|
-
include_package "org.apache.http.impl"
|
73
72
|
include_package "org.apache.http.impl.client"
|
74
73
|
include_package "org.apache.http.impl.conn"
|
75
|
-
include_package "org.apache.http.impl.auth"
|
76
74
|
include_package "org.apache.http.entity"
|
77
75
|
include_package "org.apache.http.message"
|
78
76
|
include_package "org.apache.http.params"
|
@@ -80,16 +78,20 @@ module Manticore
|
|
80
78
|
include_package "org.apache.http.auth"
|
81
79
|
include_package "java.util.concurrent"
|
82
80
|
include_package "org.apache.http.client.protocol"
|
83
|
-
include_package "org.apache.http.conn.ssl"
|
84
81
|
include_package "java.security.cert"
|
85
82
|
include_package "java.security.spec"
|
86
83
|
include_package "java.security"
|
87
|
-
include_package "org.apache.http.client.utils"
|
88
84
|
java_import "org.apache.http.HttpHost"
|
89
85
|
java_import "javax.net.ssl.SSLContext"
|
90
86
|
java_import "org.manticore.HttpGetWithEntity"
|
91
87
|
java_import "org.manticore.HttpDeleteWithEntity"
|
92
88
|
java_import "org.apache.http.auth.UsernamePasswordCredentials"
|
89
|
+
java_import "org.apache.http.conn.ssl.SSLConnectionSocketFactory"
|
90
|
+
java_import "org.apache.http.conn.ssl.SSLContextBuilder"
|
91
|
+
java_import "org.apache.http.conn.ssl.TrustSelfSignedStrategy"
|
92
|
+
java_import "org.apache.http.client.utils.URIBuilder"
|
93
|
+
java_import "org.apache.http.impl.DefaultConnectionReuseStrategy"
|
94
|
+
java_import "org.apache.http.impl.auth.BasicScheme"
|
93
95
|
|
94
96
|
# This is a class rather than a proc because the proc holds a closure around
|
95
97
|
# the instance of the Client that creates it.
|
@@ -201,11 +203,7 @@ module Manticore
|
|
201
203
|
builder.set_connection_reuse_strategy DefaultConnectionReuseStrategy.new
|
202
204
|
end
|
203
205
|
|
204
|
-
|
205
|
-
socket_config_builder.set_so_timeout(options.fetch(:socket_timeout, DEFAULT_SOCKET_TIMEOUT) * 1000)
|
206
|
-
socket_config_builder.set_tcp_no_delay(options.fetch(:tcp_no_delay, true))
|
207
|
-
builder.set_default_socket_config socket_config_builder.build
|
208
|
-
|
206
|
+
builder.set_default_socket_config socket_config_from_options(options)
|
209
207
|
builder.set_connection_manager pool(options)
|
210
208
|
|
211
209
|
request_config = RequestConfig.custom
|
@@ -407,10 +405,19 @@ module Manticore
|
|
407
405
|
cm.set_validate_after_inactivity options.fetch(:check_connection_timeout, 2_000)
|
408
406
|
cm.set_default_max_per_route options.fetch(:pool_max_per_route, @max_pool_size)
|
409
407
|
cm.set_max_total @max_pool_size
|
408
|
+
cm.set_default_socket_config socket_config_from_options(options)
|
409
|
+
|
410
410
|
finalize cm, :shutdown
|
411
411
|
end
|
412
412
|
end
|
413
413
|
end
|
414
|
+
|
415
|
+
def socket_config_from_options(options)
|
416
|
+
socket_config_builder = SocketConfig.custom
|
417
|
+
socket_config_builder.set_so_timeout(options.fetch(:socket_timeout, DEFAULT_SOCKET_TIMEOUT) * 1000)
|
418
|
+
socket_config_builder.set_tcp_no_delay(options.fetch(:tcp_no_delay, true))
|
419
|
+
socket_config_builder.build
|
420
|
+
end
|
414
421
|
|
415
422
|
def create_executor_if_needed
|
416
423
|
return @executor if @executor
|
@@ -510,7 +517,7 @@ module Manticore
|
|
510
517
|
|
511
518
|
if @use_cookies == :per_request
|
512
519
|
store = BasicCookieStore.new
|
513
|
-
context.setAttribute(ClientContext
|
520
|
+
context.setAttribute(ClientContext::COOKIE_STORE, store)
|
514
521
|
end
|
515
522
|
|
516
523
|
return req, context
|
@@ -618,7 +625,7 @@ module Manticore
|
|
618
625
|
raise "Invalid value for :verify. Valid values are (:all, :browser, :default)"
|
619
626
|
end
|
620
627
|
|
621
|
-
context =
|
628
|
+
context = SSLContextBuilder.new
|
622
629
|
setup_trust_store ssl_options, context, trust_strategy
|
623
630
|
setup_key_store ssl_options, context
|
624
631
|
|
@@ -633,8 +640,8 @@ module Manticore
|
|
633
640
|
trust_store ||= blank_keystore
|
634
641
|
open(ssl_options[:ca_file]) do |fp|
|
635
642
|
cert_collection = CertificateFactory.get_instance("X509").generate_certificates(fp.to_inputstream).to_a
|
636
|
-
cert_collection.
|
637
|
-
trust_store.set_certificate_entry(cert.getSubjectX500Principal.name, cert)
|
643
|
+
cert_collection.each_with_index do |cert, i|
|
644
|
+
trust_store.set_certificate_entry("#{i}#" + cert.getSubjectX500Principal.name, cert)
|
638
645
|
end
|
639
646
|
end
|
640
647
|
end
|
data/lib/manticore/response.rb
CHANGED
@@ -11,14 +11,13 @@ module Manticore
|
|
11
11
|
# @!attribute [r] callback_result
|
12
12
|
# @return Value returned from any given on_success/response block
|
13
13
|
class Response
|
14
|
-
|
15
|
-
|
16
|
-
include_package "org.apache.http.protocol"
|
14
|
+
|
15
|
+
java_import "org.apache.http.client.ResponseHandler"
|
17
16
|
java_import "org.apache.http.client.protocol.HttpClientContext"
|
18
|
-
java_import "
|
17
|
+
java_import "org.apache.http.protocol.ExecutionContext"
|
19
18
|
|
20
|
-
include ResponseHandler
|
21
|
-
include Callable
|
19
|
+
include org.apache.http.client.ResponseHandler
|
20
|
+
include java.util.concurrent.Callable
|
22
21
|
|
23
22
|
attr_accessor :background
|
24
23
|
attr_reader :context, :request, :callback_result, :called, :future
|
@@ -54,15 +53,16 @@ module Manticore
|
|
54
53
|
ex = Manticore::ConnectTimeout
|
55
54
|
rescue Java::JavaNet::SocketException => e
|
56
55
|
ex = Manticore::SocketException
|
57
|
-
rescue Java::OrgApacheHttpClient::ClientProtocolException, Java::JavaxNetSsl::SSLHandshakeException,
|
58
|
-
Java::
|
56
|
+
rescue Java::OrgApacheHttpClient::ClientProtocolException, Java::JavaxNetSsl::SSLHandshakeException,
|
57
|
+
Java::OrgApacheHttpConn::HttpHostConnectException, Java::OrgApacheHttp::NoHttpResponseException,
|
58
|
+
Java::OrgApacheHttp::ConnectionClosedException => e
|
59
59
|
ex = Manticore::ClientProtocolException
|
60
60
|
rescue Java::JavaNet::UnknownHostException => e
|
61
61
|
ex = Manticore::ResolutionFailure
|
62
62
|
rescue Java::JavaLang::IllegalArgumentException => e
|
63
63
|
ex = Manticore::InvalidArgumentException
|
64
64
|
rescue Java::JavaLang::IllegalStateException => e
|
65
|
-
if e.message.
|
65
|
+
if (e.message || '').index('Connection pool shut down')
|
66
66
|
ex = Manticore::ClientStoppedException
|
67
67
|
else
|
68
68
|
@exception = e
|
@@ -75,7 +75,7 @@ module Manticore
|
|
75
75
|
|
76
76
|
# TODO: If calling async, execute_complete may fail and then silently swallow exceptions. How do we fix that?
|
77
77
|
if ex || @exception
|
78
|
-
@exception ||= ex.new(e
|
78
|
+
@exception ||= ex.new(e)
|
79
79
|
@handlers[:failure].call @exception
|
80
80
|
execute_complete
|
81
81
|
nil
|
@@ -90,8 +90,8 @@ module Manticore
|
|
90
90
|
# @return [String]
|
91
91
|
def final_url
|
92
92
|
call_once
|
93
|
-
last_request = context.get_attribute ExecutionContext
|
94
|
-
last_host = context.get_attribute ExecutionContext
|
93
|
+
last_request = context.get_attribute ExecutionContext::HTTP_REQUEST
|
94
|
+
last_host = context.get_attribute ExecutionContext::HTTP_TARGET_HOST
|
95
95
|
host = last_host.to_uri
|
96
96
|
url = last_request.get_uri
|
97
97
|
URI.join(host, url.to_s)
|
data/lib/manticore/version.rb
CHANGED
data/manticore.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.required_ruby_version = '>= 2.3' # JRuby >= 9.1
|
23
|
+
|
22
24
|
private_key = File.expand_path("~/.gemcert/gem-private_key.pem")
|
23
25
|
if File.exists? private_key
|
24
26
|
spec.signing_key = private_key
|
@@ -130,7 +130,13 @@ describe Manticore::Client do
|
|
130
130
|
let(:client) { Manticore::Client.new :ssl => {:verify => :strict} }
|
131
131
|
|
132
132
|
it "breaks on SSL validation errors" do
|
133
|
-
|
133
|
+
begin
|
134
|
+
client.get("https://localhost:55445/").body
|
135
|
+
rescue Manticore::ClientProtocolException => e
|
136
|
+
expect( e.cause ).to be_a javax.net.ssl.SSLHandshakeException
|
137
|
+
else
|
138
|
+
fail "exception not raised"
|
139
|
+
end
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
@@ -830,7 +836,13 @@ describe Manticore::Client do
|
|
830
836
|
let(:client) { Manticore::Client.new request_timeout: 1, connect_timeout: 1, socket_timeout: 1 }
|
831
837
|
|
832
838
|
it "times out" do
|
833
|
-
|
839
|
+
begin
|
840
|
+
client.get(local_server "/?sleep=2").body
|
841
|
+
rescue Manticore::SocketTimeout => e
|
842
|
+
expect( e.cause ).to be_a java.net.SocketTimeoutException
|
843
|
+
else
|
844
|
+
fail "exception not raised"
|
845
|
+
end
|
834
846
|
end
|
835
847
|
|
836
848
|
it "times out when custom request options are passed" do
|
@@ -6,7 +6,7 @@ describe Manticore::Response do
|
|
6
6
|
|
7
7
|
its(:headers) { is_expected.to be_a Hash }
|
8
8
|
its(:body) { is_expected.to be_a String }
|
9
|
-
its(:length) { is_expected.to be_a
|
9
|
+
its(:length) { is_expected.to be_a Integer }
|
10
10
|
|
11
11
|
it "provides response header lookup via #[]" do
|
12
12
|
expect(subject["Content-Type"]).to eq "application/json"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manticore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Chris Heald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
124
|
requirements:
|
125
125
|
- - ">="
|
126
126
|
- !ruby/object:Gem::Version
|
127
|
-
version: '
|
127
|
+
version: '2.3'
|
128
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
130
|
- - ">="
|