manticore 0.7.0-java → 0.7.1-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
- 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
|
- - ">="
|