manticore 0.6.2-java → 0.7.1-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 52e7c6c63c54c59317eb836e5caa6cc1dbb08fc1
4
- data.tar.gz: 362d618ee0a1e92762bd5acbb9639c0ea18af0e9
2
+ SHA256:
3
+ metadata.gz: 67e67c0611ad51fbaf279f456ef5a9e463038f1017c0eb8c7665032a05534b59
4
+ data.tar.gz: 0ecf2a3014befbbc5b26d95c3ee36809ccc8605e450631e4ec0f1c143225bbc5
5
5
  SHA512:
6
- metadata.gz: ab0c5c529908001ac420bc3c82234ff9016139024211dc2e1e9111dc71e43b37b6ce92c674a5b67c270329de752e3d33fc9e8cb726246a792bdc060e02bb3881
7
- data.tar.gz: 1aa799e26509c9e0ce51be46b5cf3f156bd0bfc33f9ecc8a41c136a039f2547ef8e8d0ad479afcfd69a34b6d0fbdb7525e670d65c8c594e51d50a4c53a04a62f
6
+ metadata.gz: 19f7db686cff19817b8310f7838f9115d343ab7516e7cbab066c0f0f7d223c7a0a42c40f9e361426c07345088dbdb818cabab59fb2a481d35050f939e27afafd
7
+ data.tar.gz: ebc35118980baac6eff3e1f795f5ad3aa0af01c7ac29cd6a9502f9300fb1da88d8b97ecfc7c1198d5902a35ab2501179df775791e3306e27004e85d690145bc2
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,42 @@
1
+ .default: &default
2
+ variables:
3
+ TERM: xterm-256color
4
+ JRUBY_OPTS: --debug
5
+ cache:
6
+ paths:
7
+ - bundler --path vendor/bundle
8
+ - $HOME/.m2
9
+ before_script:
10
+ - apt update && apt install -y git
11
+ - gem install ruby-maven
12
+ - bundle install --path vendor/bundle
13
+ script:
14
+ - bundle exec rake
15
+
16
+ test jruby-9.2:
17
+ <<: *default
18
+ image: jruby:9.2
19
+ artifacts:
20
+ expire_in: 3 days
21
+ paths:
22
+ - coverage
23
+
24
+ test jruby-9.1:
25
+ <<: *default
26
+ image: jruby:9.1
27
+
28
+ test jruby-1.7:
29
+ <<: *default
30
+ image: jruby:1.7
31
+
32
+ pages:
33
+ stage: deploy
34
+ only:
35
+ - master
36
+ artifacts:
37
+ expire_in: 3 days
38
+ paths:
39
+ - public
40
+ script:
41
+ - mkdir -p public
42
+ - mv coverage/ public/coverage/
data/.travis.yml CHANGED
@@ -1,23 +1,22 @@
1
+ dist: trusty # due Oracle JDK
1
2
  language: ruby
2
- sudo: false
3
3
  cache:
4
4
  - bundler
5
5
  - directories:
6
6
  - $HOME/.m2
7
7
  rvm:
8
- - jruby-1.7
9
- - jruby-9.0.5.0
8
+ - jruby-9.2.16.0 # Ruby 2.5
10
9
  jdk:
11
10
  - oraclejdk8
12
- - openjdk7
11
+ - openjdk8
12
+ - openjdk11
13
13
  before_install:
14
- - gem install ruby-maven bundler
15
- - bundle install
14
+ - gem install bundler -v 1.17.3
16
15
  matrix:
17
16
  include:
18
- - rvm: jruby-9.2.0.0
19
- jdk: oraclejdk8
20
17
  - rvm: jruby-head
21
- jdk: oraclejdk8
18
+ jdk: openjdk11
19
+ - rvm: jruby-9.1.17.0 # Ruby 2.3
20
+ jdk: openjdk8
22
21
  allow_failures:
23
22
  - rvm: jruby-head
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
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)
8
+
9
+ ### v0.7.0
10
+
11
+ * Drop support for JRuby 1.7. It probably still works, but we don't test against it anymore
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)
13
+
1
14
  ## v0.6
2
15
 
16
+ ### v0.6.4
17
+
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)
19
+ * Reduced unnecessary string copying (!78 - thanks @kares)
20
+
21
+ ### v0.6.2-v0.6.3
22
+
23
+ * Fixed the use of authentication information in proxy URLs (#71)
24
+ * Changed the default encoding to UTF-8 when a response MIME is application/json (#70)
25
+
3
26
  ### v0.6.1
4
27
 
5
28
  * Manticore will accept a URI object (which it calls #to_s on) as an alternate to a String for the URL in client#get(url)
data/Gemfile CHANGED
@@ -8,7 +8,9 @@ group :development, :test do
8
8
  gem "rspec", "~> 3.0"
9
9
  gem "rspec-its"
10
10
  gem "httpclient", "~> 2.3"
11
- gem "rack", "~> 1.5"
11
+ gem "rack", ">= 2.1.4"
12
12
  gem "rake-compiler"
13
13
  gem "gserver"
14
- end
14
+ gem "simplecov"
15
+ gem "json"
16
+ end
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Manticore
2
2
 
3
+ **Note**: While I'll continue to maintain the library here, I've moved the canonical copy to Gitlab at https://gitlab.com/cheald/manticore - it is preferred that you submit issues and PRs there.
4
+
3
5
  [![Build Status](https://travis-ci.org/cheald/manticore.svg?branch=master)](https://travis-ci.org/cheald/manticore)
4
6
 
5
7
  Manticore is a fast, robust HTTP client built on the Apache HTTPClient libraries. It is only compatible with JRuby.
@@ -88,7 +90,11 @@ For detailed documentation, see the [full Manticore::Client documentation](http:
88
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.
89
91
 
90
92
  ```ruby
91
- client = Manticore::Client.new(request_timeout: 5, connect_timeout: 5, socket_timeout: 5, pool_max: 10, pool_max_per_route: 2)
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)
92
98
  ```
93
99
 
94
100
  Then, you can make requests from the client. Pooling and route maximum constraints are automatically managed:
@@ -120,11 +126,20 @@ per-route concurrency limits, and other neat things. In general, you should crea
120
126
  To set this up, you might create 2 pools, each configured for the task:
121
127
 
122
128
  ```ruby
123
- general_http_client = Manticore::Client.new connect_timeout: 10, socket_timeout: 10, request_timeout: 10, follow_redirects: true, max_per_route: 2
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)
124
134
  # With an OpenSSL CA store
125
- proxied_backend_client = Manticore::Client.new proxy: "https://backend.internal:4242", ssl: {ca_file: "my_certs.pem"}
135
+ proxied_backend_client = Manticore::Client.new(proxy: "https://backend.internal:4242",
136
+ ssl: { ca_file: "my_certs.pem" })
126
137
  # Or with a .jks truststore
127
- # proxied_backend_client = Manticore::Client.new proxy: "https://backend.internal:4242", ssl: {truststore: "./truststore.jks", truststore_password: "s3cr3t"}
138
+ proxied_backend_client = Manticore::Client.new(proxy: "https://backend.internal:4242",
139
+ ssl: {
140
+ truststore: "./truststore.jks",
141
+ truststore_password: "s3cr3t"
142
+ })
128
143
  ```
129
144
 
130
145
  This would create 2 separate request pools; the first would be configured with generous timeouts and redirect following, and would use the system
@@ -39,14 +39,19 @@ public class Manticore implements Library {
39
39
  @JRubyMethod(name = "read_entity")
40
40
  public IRubyObject readEntity(ThreadContext context, IRubyObject rEntity, Block block) throws IOException {
41
41
  HttpEntity entity = (HttpEntity)rEntity.toJava(HttpEntity.class);
42
+
42
43
  String charset = EntityUtils.getContentCharSet(entity);
43
- if(charset == null) { charset = HTTP.DEFAULT_CONTENT_CHARSET; }
44
- Encoding encoding;
45
- try {
44
+ if (charset == null) {
46
45
  String mimeType = EntityUtils.getContentMimeType(entity);
47
- if (mimeType.startsWith("application/json")) {
46
+ if ( mimeType != null && mimeType.startsWith("application/json") ) {
48
47
  charset = "UTF-8";
48
+ } else {
49
+ charset = HTTP.DEFAULT_CONTENT_CHARSET;
49
50
  }
51
+ }
52
+
53
+ Encoding encoding;
54
+ try {
50
55
  encoding = context.getRuntime().getEncodingService().getEncodingFromString(charset);
51
56
  } catch(Throwable e) {
52
57
  encoding = context.getRuntime().getEncodingService().getEncodingFromString(HTTP.DEFAULT_CONTENT_CHARSET);
@@ -61,7 +66,7 @@ public class Manticore implements Library {
61
66
 
62
67
  private IRubyObject readWholeEntity(ThreadContext context, HttpEntity entity, Encoding encoding) throws IOException {
63
68
  ByteList bl = new ByteList(EntityUtils.toByteArray(entity), false);
64
- return RubyString.newStringShared(context.getRuntime(), bl, encoding);
69
+ return RubyString.newString(context.getRuntime(), bl, encoding);
65
70
  }
66
71
 
67
72
  private IRubyObject streamEntity(ThreadContext context, HttpEntity entity, Encoding encoding, Block block) throws IOException {
@@ -81,7 +86,7 @@ public class Manticore implements Library {
81
86
  byte[] tmp = new byte[4096];
82
87
  int l;
83
88
  while((l = instream.read(tmp)) != -1) {
84
- block.call( context, RubyString.newString(context.getRuntime(), new ByteList(tmp, 0, l, true), encoding) );
89
+ block.call( context, RubyString.newStringShared(context.getRuntime(), new ByteList(tmp, 0, l, false), encoding) );
85
90
  }
86
91
  } finally {
87
92
  instream.close();
@@ -89,4 +94,4 @@ public class Manticore implements Library {
89
94
  return context.nil;
90
95
  }
91
96
  }
92
- }
97
+ }
@@ -20,17 +20,12 @@ module Faraday
20
20
  ParallelManager.new
21
21
  end
22
22
 
23
- def initialize(app, connection_options = {})
24
- @connection_options = connection_options
25
- super(app)
26
- end
27
-
28
23
  def client(env)
29
24
  @client ||= begin
30
25
  opts = {}
31
26
  if ssl = env[:ssl].to_hash
32
27
  opts[:ssl] = {}
33
- opts[:ssl][:verify] = :disable if ssl[:verify] == false
28
+ opts[:ssl][:verify] = ssl[:verify] unless ssl[:verify].nil?
34
29
  opts[:ssl][:ca_file] = ssl[:ca_file]
35
30
  opts[:ssl][:client_cert] = ssl[:client_cert]
36
31
  opts[:ssl][:client_key] = ssl[:client_key]
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
- org.manticore.Manticore.new.load(JRuby.runtime, false)
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; end
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
@@ -1,6 +1,7 @@
1
1
  require "thread"
2
2
  require "base64"
3
3
  require "weakref"
4
+ require "openssl_pkcs8_pure"
4
5
 
5
6
  module Manticore
6
7
  # @!macro [new] http_method_shared
@@ -68,10 +69,8 @@ module Manticore
68
69
  include_package "org.apache.http.client.config"
69
70
  include_package "org.apache.http.config"
70
71
  include_package "org.apache.http.conn.socket"
71
- include_package "org.apache.http.impl"
72
72
  include_package "org.apache.http.impl.client"
73
73
  include_package "org.apache.http.impl.conn"
74
- include_package "org.apache.http.impl.auth"
75
74
  include_package "org.apache.http.entity"
76
75
  include_package "org.apache.http.message"
77
76
  include_package "org.apache.http.params"
@@ -79,16 +78,20 @@ module Manticore
79
78
  include_package "org.apache.http.auth"
80
79
  include_package "java.util.concurrent"
81
80
  include_package "org.apache.http.client.protocol"
82
- include_package "org.apache.http.conn.ssl"
83
81
  include_package "java.security.cert"
84
82
  include_package "java.security.spec"
85
83
  include_package "java.security"
86
- include_package "org.apache.http.client.utils"
87
84
  java_import "org.apache.http.HttpHost"
88
85
  java_import "javax.net.ssl.SSLContext"
89
86
  java_import "org.manticore.HttpGetWithEntity"
90
87
  java_import "org.manticore.HttpDeleteWithEntity"
91
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"
92
95
 
93
96
  # This is a class rather than a proc because the proc holds a closure around
94
97
  # the instance of the Client that creates it.
@@ -169,8 +172,8 @@ module Manticore
169
172
  # @option options [String] ssl[:keystore_password] (nil) Password used for decrypting the client auth key store
170
173
  # @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.
171
174
  # @option options [String] ssl[:ca_file] (nil) OpenSSL-style path to an X.509 certificate to use to validate SSL certificates
172
- # @option options [String] ssl[:client_cert] (nil) OpenSSL-style path to an X.509 certificate to use for client authentication
173
- # @option options [String] ssl[:client_key] (nil) OpenSSL-style path to an RSA key to use for client authentication
175
+ # @option options [String|OpenSSL::X509::Certificate] ssl[:client_cert] (nil) A string containing a base64-encoded X.509 certificate, OR a path to an OpenSSL-style X.509 certificate, OR an instance of OpenSSL::X509::Certificate
176
+ # @option options [String|OpenSSL::PKey::Pkey] ssl[:client_key] (nil) A string containing a base64-encoded RSA key to use for client authentication, OR a path to an OpenSSL-style RSA key, OR an instance of OpenSSL::PKey::PKey
174
177
  # @option options [boolean] ssl[:track_state] (false) Turn on or off connection state tracking. This helps prevent SSL information from leaking across threads, but means that connections
175
178
  # can't be shared across those threads. This should generally be left off unless you know what you're doing.
176
179
  def initialize(options = {})
@@ -200,11 +203,7 @@ module Manticore
200
203
  builder.set_connection_reuse_strategy DefaultConnectionReuseStrategy.new
201
204
  end
202
205
 
203
- socket_config_builder = SocketConfig.custom
204
- socket_config_builder.set_so_timeout(options.fetch(:socket_timeout, DEFAULT_SOCKET_TIMEOUT) * 1000)
205
- socket_config_builder.set_tcp_no_delay(options.fetch(:tcp_no_delay, true))
206
- builder.set_default_socket_config socket_config_builder.build
207
-
206
+ builder.set_default_socket_config socket_config_from_options(options)
208
207
  builder.set_connection_manager pool(options)
209
208
 
210
209
  request_config = RequestConfig.custom
@@ -222,7 +221,7 @@ module Manticore
222
221
  @client = builder.build
223
222
  finalize @client, :close
224
223
  @options = options
225
- @async_requests = []
224
+ @async_requests = Queue.new
226
225
  @stubs = {}
227
226
  end
228
227
 
@@ -333,8 +332,9 @@ module Manticore
333
332
  # @return [Array] An array of the responses from the requests executed.
334
333
  def execute!
335
334
  method = executor.java_method(:submit, [java.util.concurrent.Callable.java_class])
336
- result = @async_requests.map { |r| method.call r }
337
- @async_requests.clear
335
+
336
+ result = []
337
+ result << method.call(@async_requests.pop) until @async_requests.empty?
338
338
  result.map do |future|
339
339
  begin
340
340
  future.get
@@ -385,11 +385,13 @@ module Manticore
385
385
  def pool_builder(options)
386
386
  http_sf = PlainConnectionSocketFactory.new
387
387
 
388
+ # :nocov:
388
389
  if options[:ignore_ssl_validation]
389
390
  $stderr.puts "The options[:ignore_ssl_validation] setting is deprecated in favor of options[:ssl][:verify]"
390
391
  options[:ssl] ||= {}
391
392
  options[:ssl] = {:verify => !options.delete(:ignore_ssl_validation)}.merge(options[:ssl])
392
393
  end
394
+ # :nocov:
393
395
 
394
396
  https_sf = ssl_socket_factory_from_options options.fetch(:ssl, {})
395
397
  registry = RegistryBuilder.create.register("http", http_sf).register("https", https_sf).build
@@ -403,10 +405,19 @@ module Manticore
403
405
  cm.set_validate_after_inactivity options.fetch(:check_connection_timeout, 2_000)
404
406
  cm.set_default_max_per_route options.fetch(:pool_max_per_route, @max_pool_size)
405
407
  cm.set_max_total @max_pool_size
408
+ cm.set_default_socket_config socket_config_from_options(options)
409
+
406
410
  finalize cm, :shutdown
407
411
  end
408
412
  end
409
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
410
421
 
411
422
  def create_executor_if_needed
412
423
  return @executor if @executor
@@ -506,7 +517,7 @@ module Manticore
506
517
 
507
518
  if @use_cookies == :per_request
508
519
  store = BasicCookieStore.new
509
- context.setAttribute(ClientContext.COOKIE_STORE, store)
520
+ context.setAttribute(ClientContext::COOKIE_STORE, store)
510
521
  end
511
522
 
512
523
  return req, context
@@ -614,7 +625,7 @@ module Manticore
614
625
  raise "Invalid value for :verify. Valid values are (:all, :browser, :default)"
615
626
  end
616
627
 
617
- context = SSLContexts.custom
628
+ context = SSLContextBuilder.new
618
629
  setup_trust_store ssl_options, context, trust_strategy
619
630
  setup_key_store ssl_options, context
620
631
 
@@ -629,8 +640,8 @@ module Manticore
629
640
  trust_store ||= blank_keystore
630
641
  open(ssl_options[:ca_file]) do |fp|
631
642
  cert_collection = CertificateFactory.get_instance("X509").generate_certificates(fp.to_inputstream).to_a
632
- cert_collection.each do |cert|
633
- 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)
634
645
  end
635
646
  end
636
647
  end
@@ -645,39 +656,44 @@ module Manticore
645
656
  keystore_password = (ssl_options[:keystore_password] || "").to_java.toCharArray
646
657
 
647
658
  # Support OpenSSL-style bare X.509 certs with an RSA key
648
- # This is really dumb - we have to b64-decode the key ourselves, and we can only support PKCS8
649
659
  if ssl_options[:client_cert] && ssl_options[:client_key]
650
660
  key_store ||= blank_keystore
651
661
  certs, key = nil, nil
652
- open(ssl_options[:client_cert]) do |fp|
653
- certs = CertificateFactory.get_instance("X509").generate_certificates(fp.to_inputstream).to_array([].to_java(Certificate))
654
- end
662
+
663
+ cert_str = if ssl_options[:client_cert].is_a?(OpenSSL::X509::Certificate)
664
+ ssl_options[:client_cert].to_s
665
+ elsif ssl_options[:client_cert].is_a?(String) && File.exists?(ssl_options[:client_cert])
666
+ File.read(ssl_options[:client_cert])
667
+ else
668
+ ssl_options[:client_cert].to_s
669
+ end
670
+
671
+ cert_stream = java.io.ByteArrayInputStream.new(cert_str.strip.to_java_bytes)
672
+ certs = CertificateFactory.get_instance("X509").generate_certificates(cert_stream).to_array([].to_java(Certificate))
673
+
674
+ key_str = if ssl_options[:client_key].is_a?(OpenSSL::PKey::PKey)
675
+ ssl_options[:client_key].to_pem_pkcs8
676
+ elsif ssl_options[:client_key].is_a?(String) && File.exists?(ssl_options[:client_key])
677
+ File.read(ssl_options[:client_key])
678
+ else
679
+ ssl_options[:client_key].to_s
680
+ end
655
681
 
656
682
  # Add each of the keys in the given keyfile into the keystore.
657
- open(ssl_options[:client_key]) do |fp|
658
- key_parts = fp.read.scan(KEY_EXTRACTION_REGEXP)
659
- key_parts.each do |type, b64key|
660
- body = Base64.decode64 b64key
661
- spec = PKCS8EncodedKeySpec.new(body.to_java_bytes)
662
- type = type.strip
663
- type = "RSA" if type == ""
664
- key = KeyFactory.getInstance(type).generatePrivate(spec)
665
- key_store.set_key_entry("key-#{Digest::SHA1.hexdigest(body)}", key, keystore_password, certs)
666
- end
683
+ key_parts = key_str.scan(KEY_EXTRACTION_REGEXP)
684
+ key_parts.each do |type, b64key|
685
+ body = Base64.decode64 b64key
686
+ spec = PKCS8EncodedKeySpec.new(body.strip.to_java_bytes)
687
+ type = type.strip
688
+ type = "RSA" if type == ""
689
+ key = KeyFactory.getInstance(type).generatePrivate(spec)
690
+ key_store.set_key_entry("key-#{Digest::SHA1.hexdigest(body)}", key, keystore_password, certs)
667
691
  end
668
692
  end
669
693
 
670
694
  context.load_key_material(key_store, keystore_password) if key_store
671
695
  end
672
696
 
673
- def get_trust_store(options)
674
- get_store :truststore, options
675
- end
676
-
677
- def get_key_store(options)
678
- get_store :keystore, options
679
- end
680
-
681
697
  def get_store(prefix, options)
682
698
  KeyStore.get_instance(options[:"#{prefix}_type"] || guess_store_type(options[prefix])).tap do |store|
683
699
  instream = open(options[prefix], "rb").to_inputstream
@@ -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
- include_package "org.apache.http.client"
15
- include_package "org.apache.http.util"
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 "java.util.concurrent.Callable"
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, Java::OrgApacheHttpConn::HttpHostConnectException,
58
- Java::OrgApacheHttp::NoHttpResponseException, Java::OrgApacheHttp::ConnectionClosedException => e
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.match(/Connection pool shut down/)
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.cause || e.message)
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.HTTP_REQUEST
94
- last_host = context.get_attribute ExecutionContext.HTTP_TARGET_HOST
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)
@@ -1,3 +1,3 @@
1
1
  module Manticore
2
- VERSION = "0.6.2"
2
+ VERSION = "0.7.1"
3
3
  end
Binary file
data/manticore.gemspec CHANGED
@@ -19,15 +19,19 @@ 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
25
27
  spec.cert_chain = ['gem-public_cert.pem']
26
28
  end
27
29
 
28
- spec.add_development_dependency "bundler", "~> 1.3"
30
+ spec.add_dependency "openssl_pkcs8_pure"
31
+
32
+ spec.add_development_dependency "bundler"
29
33
  spec.add_development_dependency "rake"
30
- spec.add_development_dependency "jar-dependencies"
34
+ spec.add_development_dependency "jar-dependencies", "~> 0.4.1"
31
35
 
32
36
  spec.requirements << "jar org.apache.httpcomponents:httpclient, '~> 4.5.0'"
33
37
  spec.requirements << "jar org.apache.httpcomponents:httpmime, '~> 4.5.0'"
@@ -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
- expect { client.get("https://localhost:55444/").call }.to raise_exception(Manticore::ClientProtocolException)
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
 
@@ -166,7 +172,7 @@ describe Manticore::Client do
166
172
  end
167
173
  end
168
174
 
169
- context "when client_cert and client_key are given" do
175
+ context "when client_cert and client_key are given as file paths" do
170
176
  let(:client) {
171
177
  Manticore::Client.new(
172
178
  :ssl => {
@@ -183,6 +189,40 @@ describe Manticore::Client do
183
189
  end
184
190
  end
185
191
 
192
+ context "when client_cert and client_key are given as OpenSSL::X509::Certificate" do
193
+ let(:client) {
194
+ Manticore::Client.new(
195
+ :ssl => {
196
+ verify: :strict,
197
+ ca_file: File.expand_path("../../ssl/root-ca.crt", __FILE__),
198
+ client_cert: OpenSSL::X509::Certificate.new(File.read(File.expand_path("../../ssl/client.crt", __FILE__))),
199
+ client_key: OpenSSL::PKey::RSA.new(File.read(File.expand_path("../../ssl/client.key", __FILE__))),
200
+ },
201
+ )
202
+ }
203
+
204
+ it "successfully auths requests" do
205
+ expect(client.get("https://localhost:55445/").body).to match("hello")
206
+ end
207
+ end
208
+
209
+ context "when client_cert and client_key are given as strings" do
210
+ let(:client) {
211
+ Manticore::Client.new(
212
+ :ssl => {
213
+ verify: :strict,
214
+ ca_file: File.expand_path("../../ssl/root-ca.crt", __FILE__),
215
+ client_cert: File.read(File.expand_path("../../ssl/client.crt", __FILE__)),
216
+ client_key: File.read(File.expand_path("../../ssl/client.key", __FILE__)),
217
+ },
218
+ )
219
+ }
220
+
221
+ it "successfully auths requests" do
222
+ expect(client.get("https://localhost:55445/").body).to match("hello")
223
+ end
224
+ end
225
+
186
226
  context "when off" do
187
227
  let(:client) { Manticore::Client.new :ssl => {:verify => :disable} }
188
228
 
@@ -529,7 +569,7 @@ describe Manticore::Client do
529
569
  describe "#head" do
530
570
  it "works" do
531
571
  response = client.head(local_server)
532
- expect(JSON.load(response.body)).to be_nil
572
+ expect(response.body).to be_nil
533
573
  end
534
574
  end
535
575
 
@@ -730,11 +770,16 @@ describe Manticore::Client do
730
770
  ].join("\n"))
731
771
  client.close
732
772
  rescue IOError => e
773
+ break
733
774
  end
734
775
  end
735
776
  end
736
777
  end
737
778
 
779
+ after do
780
+ @server.kill
781
+ end
782
+
738
783
  let(:client) { Manticore::Client.new keepalive: true, pool_max: 1 }
739
784
 
740
785
  it "retries 3 times by default" do
@@ -791,7 +836,13 @@ describe Manticore::Client do
791
836
  let(:client) { Manticore::Client.new request_timeout: 1, connect_timeout: 1, socket_timeout: 1 }
792
837
 
793
838
  it "times out" do
794
- expect { client.get(local_server "/?sleep=2").body }.to raise_exception(Manticore::SocketTimeout)
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
795
846
  end
796
847
 
797
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 Fixnum }
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"
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  # encoding: utf-8
2
2
  require "rubygems"
3
3
  require "bundler/setup"
4
+ require "simplecov"
5
+
6
+ SimpleCov.start do
7
+ add_filter "spec/"
8
+ end
9
+
4
10
  require "manticore"
5
11
  require "zlib"
6
12
  require "json"
metadata CHANGED
@@ -1,38 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manticore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
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: 2018-05-28 00:00:00.000000000 Z
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
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '1.3'
19
- name: bundler
18
+ version: '0'
19
+ name: openssl_pkcs8_pure
20
+ type: :runtime
20
21
  prerelease: false
21
- type: :development
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '0'
33
- name: rake
34
- prerelease: false
33
+ name: bundler
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
@@ -44,14 +44,28 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
- name: jar-dependencies
48
- prerelease: false
47
+ name: rake
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.4.1
61
+ name: jar-dependencies
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.1
55
69
  description: Manticore is an HTTP client built on the Apache HttpCore components
56
70
  email:
57
71
  - cheald@mashable.com
@@ -60,6 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - ".gitignore"
77
+ - ".gitlab-ci.yml"
63
78
  - ".travis.yml"
64
79
  - APACHE-LICENSE-2.0.txt
65
80
  - CHANGELOG.md
@@ -109,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
124
  requirements:
110
125
  - - ">="
111
126
  - !ruby/object:Gem::Version
112
- version: '0'
127
+ version: '2.3'
113
128
  required_rubygems_version: !ruby/object:Gem::Requirement
114
129
  requirements:
115
130
  - - ">="
@@ -121,8 +136,7 @@ requirements:
121
136
  - jar commons-logging:commons-logging, '~> 1.2'
122
137
  - jar commons-codec:commons-codec, '~> 1.9'
123
138
  - jar org.apache.httpcomponents:httpcore, '~> 4.4.4'
124
- rubyforge_project:
125
- rubygems_version: 2.4.8
139
+ rubygems_version: 3.0.6
126
140
  signing_key:
127
141
  specification_version: 4
128
142
  summary: Manticore is an HTTP client built on the Apache HttpCore components