manticore 0.4.2-java → 0.4.3-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e81862fe8dbfe629fdc9dbe09504e2214b3de702
4
- data.tar.gz: 5b840aa1a038b4eab593e248b3a679ec6d16fc67
3
+ metadata.gz: 1e663f9b19e305371f23a33ca105cf960255b53a
4
+ data.tar.gz: 6c0dd62a760f11460cf565949632e8dbfa77d117
5
5
  SHA512:
6
- metadata.gz: 9e5e970a68358d71776af2f4fd0b7e13bf3a13dac3d2beb2c860882301a4fe4cfbb1dae42fbff1ca4bc6ff8bff042237370e243fe804c0b1547f6f370c1d3f30
7
- data.tar.gz: 5f3122739a100067e60c2817476ec75af8af109e1ef4ece4b75fed4e695d51d39c018a1fedc3b71a663bcf21eedc36a1d50c614a4d9dbb749c33fcbbd6c54784
6
+ metadata.gz: f0f65941a497dfa2254d4859bf8528cfc0b299f280a6564556aa3a9f08de4d634a1ef3f488ac467b12ace46a5637a793a65a63ffa290300551019f7b49fd0d1f
7
+ data.tar.gz: 3e5766be83ff90fc7bab9b5becdc5801156a1fe06ead3f3dd679ee686c8b9c1994ba12c04f7bb450f6758b9d21b21f7e67f41f979b083ce421feecf721b8880e
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - jruby
3
+ - jruby-1.7
4
+ - jruby-9.0.0.0
4
5
  jdk:
5
6
  - oraclejdk8
6
7
  - oraclejdk7
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
+ ## v0.5
2
+
3
+ ### v0.5.0 (pending)
4
+
1
5
  ## v0.4
2
6
 
3
- ### v0.4.3 (pending)
7
+ ### v0.4.3
8
+
9
+ * Manticore no longer automatically retries all request types. Only non-idempotent requests will be automatically retried by default.
10
+ * added the `:retry_non_idempotent` [bool] option, which instructs Manticore to automatically retry all request types, rather than just idempotent request types
11
+ * .pfx files are automatically recognized as PKCS12 stores
12
+ * Improved StubbedResponse's mimicry of Response
13
+ * Minor improvments to the Faraday adapter
14
+ * Added an option for eager auth, which instructs Manticore to present basic auth credentials on initial request, rather than being challenged for them. You should
15
+ only use this if you have a specific need for it, as it may be a security concern otherwise.
16
+ * Manticore now cleans up the stale connection reaper thread at_exit. This may resolve memory leaks in servlet contexts.
4
17
 
5
18
  ### v0.4.2
6
19
 
@@ -10,7 +23,7 @@
10
23
 
11
24
  ### v0.4.1
12
25
 
13
- * Add support for ssl[:ca_file], ssl[:client_cert], and ssl[:client_key], to emulate OpenSSL features in other Ruby HTTP clients
26
+ * Add support for `ssl[:ca_file]`, `ssl[:client_cert]`, and `ssl[:client_key]`, to emulate OpenSSL features in other Ruby HTTP clients
14
27
  * Integrate Faraday adapter for Manticore
15
28
 
16
29
  ### v0.4.0
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem "net-http-server", "~> 0.2"
7
- gem "rspec", "~> 2.0"
7
+ gem "rspec", "~> 3.0"
8
8
  gem "rspec-its"
9
9
  gem "httpclient", "~> 2.3"
10
10
  gem "rack", "~> 1.5"
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -20,7 +20,7 @@ Or install it yourself as:
20
20
 
21
21
  ## Documentation
22
22
 
23
- Documentation is available [at rubydoc.info](http://rubydoc.info/github/cheald/manticore/master/frames).
23
+ Documentation is available [at rubydoc.info](http://www.rubydoc.info/github/cheald/manticore/master/Manticore/Client).
24
24
 
25
25
  ## Performance
26
26
 
@@ -66,7 +66,7 @@ end
66
66
  response_code = MyClient.get("http://www.google.com/").code
67
67
  ```
68
68
 
69
- Mixing the client into a class will create a new new pool. If you want to share a single pool between clients, specify the `shared_pool` option:
69
+ Mixing the client into a class will create a new pool. If you want to share a single pool between clients, specify the `shared_pool` option:
70
70
 
71
71
  ```ruby
72
72
  class MyClient
@@ -111,7 +111,7 @@ end
111
111
 
112
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
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:
114
+ per-route concurrency limits, and other neat things. In general, you should create one `Manticore::Client` instance per unique configuration needed. For example, you might have an app that performs 2 functions:
115
115
 
116
116
  1. General HTTP requesting from the internet-at-large
117
117
  2. Communication with a backend service over SSL, using a custom trust store
data/Rakefile CHANGED
File without changes
File without changes
@@ -20,6 +20,11 @@ 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
+
23
28
  def client(env)
24
29
  @client ||= begin
25
30
  opts = {}
@@ -30,6 +35,11 @@ module Faraday
30
35
  opts[:ssl][:client_cert] = ssl[:client_cert]
31
36
  opts[:ssl][:client_key] = ssl[:client_key]
32
37
  end
38
+ conn_opts = @connection_options.dup
39
+ if conn_opts.key?(:ssl)
40
+ (opts[:ssl] ||= {}).merge! conn_opts.delete(:ssl)
41
+ end
42
+ opts.merge! conn_opts
33
43
  ::Manticore::Client.new(opts)
34
44
  end
35
45
  end
@@ -78,7 +88,7 @@ module Faraday
78
88
  when ::Manticore::SocketException, ::Java::JavaUtilConcurrent::ExecutionException
79
89
  raise ConnectionFailed, err
80
90
  when ::Manticore::ClientProtocolException
81
- raise Faraday::SSLError, err
91
+ raise Faraday::ClientError, err
82
92
  else
83
93
  raise err
84
94
  end
@@ -1,4 +1,5 @@
1
1
  require 'thread'
2
+ require 'singleton'
2
3
  require 'base64'
3
4
 
4
5
  module Manticore
@@ -15,6 +16,12 @@ module Manticore
15
16
  # @option options [Integer] request_timeout Request-specific request timeout
16
17
  # @option options [Integer] max_redirects Request-specific maximum redirect limit
17
18
  # @option options [Boolean] follow_redirects Specify whether this request should follow redirects
19
+ # @option options [Hash] auth Specify authentication for the request
20
+ # @option options [String] auth[:user] Username to auth with
21
+ # @option options [String] auth[:password] Password to auth with
22
+ # @option options [Boolean] auth[:eager] Eagerly offer the Authorization header before the server challenges for it.
23
+ # You should not use this unless you know you specifically need it, as misuse
24
+ # of it can leak user credentials.
18
25
  #
19
26
  # @!macro [new] http_request_exceptions
20
27
  # @raise [Manticore::Timeout] on socket, connection, or response timeout
@@ -62,6 +69,7 @@ module Manticore
62
69
  include_package "org.apache.http.impl"
63
70
  include_package "org.apache.http.impl.client"
64
71
  include_package "org.apache.http.impl.conn"
72
+ include_package "org.apache.http.impl.auth"
65
73
  include_package "org.apache.http.entity"
66
74
  include_package "org.apache.http.message"
67
75
  include_package "org.apache.http.params"
@@ -119,15 +127,15 @@ module Manticore
119
127
  # @option options [integer] request_timeout (60) Sets the timeout for a given request. Raises Manticore::Timeout on failure.
120
128
  # @option options [integer] max_redirects (5) Sets the maximum number of redirects to follow.
121
129
  # @option options [integer] automatic_retries (3) Sets the number of times the client will automatically retry failed requests.
130
+ # @option options [boolean] retry_non_idempotent (false) If true, Manticore will automatically retry failed requests with non-idempotent verbs. Otherwise, it only automatically retries
131
+ # on GET, HEAD, PUT, DELETE, OPTIONS, and TRACE
122
132
  # @option options [boolean] expect_continue (false) Enable support for HTTP 100
123
133
  # @option options [boolean] stale_check (false) Enable support for stale connection checking. Adds overhead.
124
134
  # @option options [String] proxy Proxy host in form: http://proxy.org:1234
125
135
  # @option options [Hash] proxy Proxy host in form: {host: 'proxy.org'[, port: 80[, scheme: 'http'[, user: 'username@host', password: 'password']]]}
126
136
  # @option options [Hash] proxy Proxy host in form: {url: 'http://proxy.org:1234'[, user: 'username@host', password: 'password']]]}
127
137
  # @option options [URI] proxy Proxy host as a URI object
128
- # @option options [Boolean/Fixnum] keepalive (true) Whether to allow connections to be reused. Defaults to true. If an integer,
129
- # then connections will be kept alive for this long when Connection: keep-alive
130
- # is sent, but no Keep-Alive header is sent.
138
+ # @option options [Boolean] keepalive (true) Whether to allow connections to be reused. Defaults to true.
131
139
  # @option options [Hash] ssl Hash of options for configuring SSL
132
140
  # @option options [Array<String>] ssl[:protocols] (nil) A list of protocols that Manticore should accept
133
141
  # @option options [Array<String>] ssl[:cipher_suites] (nil) A list of cipher suites that Manticore should accept
@@ -155,19 +163,7 @@ module Manticore
155
163
  builder.disable_content_compression if options.fetch(:compression, true) == false
156
164
  builder.set_proxy get_proxy_host(options[:proxy]) if options.key?(:proxy)
157
165
 
158
- builder.set_retry_handler do |exception, executionCount, context|
159
- if (executionCount > options.fetch(:automatic_retries, 3))
160
- false
161
- else
162
- case exception
163
- when Java::OrgApacheHttp::NoHttpResponseException, Java::JavaNet::SocketException
164
- context.setAttribute "retryCount", executionCount
165
- true
166
- else
167
- false
168
- end
169
- end
170
- end
166
+ builder.set_retry_handler LoggingStandardRetryHandler.new options.fetch(:automatic_retries, 3), options.fetch(:retry_non_idempotent, false)
171
167
 
172
168
  # http://hc.apache.org/httpcomponents-client-ga/tutorial/html/advanced.html#stateful_conn
173
169
  # By default this is used to prevent different contexts from accessing SSL data
@@ -362,13 +358,7 @@ module Manticore
362
358
  cm = pool_builder options
363
359
  cm.set_default_max_per_route options.fetch(:pool_max_per_route, @max_pool_size)
364
360
  cm.set_max_total @max_pool_size
365
-
366
- Thread.new {
367
- loop {
368
- cm.closeExpiredConnections
369
- sleep 5000
370
- }
371
- }
361
+ IdleConnectionReaper.instance.monitor(cm)
372
362
  cm
373
363
  end
374
364
  end
@@ -468,7 +458,7 @@ module Manticore
468
458
 
469
459
  context = HttpClientContext.new
470
460
  proxy_user = req_options[:proxy].is_a?(Hash) && (req_options[:proxy][:user] || req_options[:proxy][:username])
471
- auth_from_options(req_options, context) if req_options.key?(:auth) || proxy_user
461
+ auth_from_options(req, req_options, context) if req_options.key?(:auth) || proxy_user
472
462
 
473
463
  if @use_cookies == :per_request
474
464
  store = BasicCookieStore.new
@@ -501,7 +491,7 @@ module Manticore
501
491
  end
502
492
  end
503
493
 
504
- def auth_from_options(options, context)
494
+ def auth_from_options(req, options, context)
505
495
  proxy = options.fetch(:proxy, {})
506
496
  if options[:auth] || proxy[:user] || proxy[:username]
507
497
  provider = BasicCredentialsProvider.new
@@ -509,6 +499,16 @@ module Manticore
509
499
  username = options[:auth][:user] || options[:auth][:username]
510
500
  password = options[:auth][:pass] || options[:auth][:password]
511
501
  provider.set_credentials AuthScope::ANY, UsernamePasswordCredentials.new(username, password)
502
+
503
+ if options[:auth][:eager]
504
+ uri = URI.parse req.uri.to_string
505
+ target = HttpHost.new(uri.host, uri.port, uri.scheme)
506
+ scheme = BasicScheme.new
507
+
508
+ cache = BasicAuthCache.new
509
+ cache.put target, scheme
510
+ context.set_auth_cache cache
511
+ end
512
512
  end
513
513
 
514
514
  if proxy[:user] || proxy[:username]
@@ -634,11 +634,43 @@ module Manticore
634
634
  end
635
635
 
636
636
  def guess_store_type(filename)
637
- if filename.end_with?(".p12")
637
+ if filename.end_with?(".p12") || filename.end_with?(".pfx")
638
638
  "pkcs12"
639
639
  else
640
640
  KeyStore.get_default_type
641
641
  end
642
642
  end
643
643
  end
644
+
645
+ class LoggingStandardRetryHandler < Java::OrgApacheHttpImplClient::StandardHttpRequestRetryHandler
646
+ def retryRequest(exception, executionCount, context)
647
+ context.setAttribute "retryCount", executionCount
648
+ super(exception, executionCount, context)
649
+ end
650
+ end
651
+
652
+ class IdleConnectionReaper
653
+ include Singleton
654
+ def initialize
655
+ @mutex = Mutex.new
656
+ @pools = []
657
+ @running = Java::JavaUtilConcurrentAtomic::AtomicBoolean.new(true)
658
+ @thread = Thread.new do
659
+ while @running.get
660
+ @mutex.synchronize { @pools.each(&:closeExpiredConnections) }
661
+ sleep 5000
662
+ end
663
+ end
664
+ at_exit { shutdown }
665
+ end
666
+
667
+ def monitor(pool)
668
+ @mutex.synchronize { @pools << pool }
669
+ end
670
+
671
+ def shutdown
672
+ @running.set(false)
673
+ @thread.wakeup
674
+ end
675
+ end
644
676
  end
@@ -40,7 +40,7 @@ module Manticore
40
40
 
41
41
  stubs[:headers] ||= {}
42
42
  stubs[:headers] = Hash[*stubs[:headers].flat_map {|k, v| [k.downcase, v] }]
43
- stubs[:headers]["content-length"] = stubs[:body].length if stubs.key?(:body)
43
+ stubs[:headers]["content-length"] = stubs[:body].length.to_s if stubs.key?(:body)
44
44
  @stubs = stubs
45
45
 
46
46
  self
@@ -57,13 +57,17 @@ module Manticore
57
57
  # @return [String] The final URL
58
58
  def final_url
59
59
  call_once
60
- @headers["location"]
60
+ @headers["location"] || @request.getURI.to_string
61
61
  end
62
62
 
63
63
  # Returns the stubbed body of this response.
64
- def body
64
+ def body(&block)
65
65
  call_once
66
- @body
66
+ if block_given?
67
+ yield body
68
+ else
69
+ @body
70
+ end
67
71
  end
68
72
  alias_method :read_body, :body
69
73
 
@@ -87,7 +91,7 @@ module Manticore
87
91
  @cookies[c.name] ||= []
88
92
  @cookies[c.name] << c
89
93
  end
90
- @handlers[:success].call(self)
94
+ @callback_result = @handlers[:success].call(self)
91
95
  self
92
96
  end
93
97
 
@@ -1,3 +1,3 @@
1
1
  module Manticore
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
data/manticore.gemspec CHANGED
File without changes
@@ -4,38 +4,38 @@ describe Manticore::Client do
4
4
 
5
5
  describe Manticore::Client::StubProxy do
6
6
  describe "#respond_with" do
7
- it "should respond with a stubbed response" do
7
+ it "responds with a stubbed response" do
8
8
  client.respond_with(body: "body", code: 200).get(local_server).on_success do |response|
9
- response.should be_a Manticore::StubbedResponse
10
- response.body.should == "body"
11
- response.code.should == 200
9
+ expect(response).to be_a Manticore::StubbedResponse
10
+ expect(response.body).to eq "body"
11
+ expect(response.code).to eq 200
12
12
  end
13
13
  end
14
14
 
15
15
  context "for synchronous requests" do
16
- it "should respond only stub the next subsequent response" do
16
+ it "responds only stub the next subsequent response" do
17
17
  stub = client.respond_with(body: "body", code: 200)
18
18
 
19
19
  stub.get(local_server) do |response|
20
- response.should be_a Manticore::StubbedResponse
20
+ expect(response).to be_a Manticore::StubbedResponse
21
21
  end
22
22
 
23
23
  stub.get(local_server) do |response|
24
- response.should be_a Manticore::Response
24
+ expect(response).to be_a Manticore::Response
25
25
  end
26
26
  end
27
27
  end
28
28
 
29
29
  context "for synchronous requests" do
30
- it "should respond only stub the next subsequent response" do
30
+ it "responds only stub the next subsequent response" do
31
31
  stub = client.respond_with(body: "body", code: 200)
32
32
 
33
33
  stub.async.get(local_server).on_success do |response|
34
- response.should be_a Manticore::StubbedResponse
34
+ expect(response).to be_a Manticore::StubbedResponse
35
35
  end
36
36
 
37
37
  stub.async.get(local_server).on_success do |response|
38
- response.should be_a Manticore::Response
38
+ expect(response).to be_a Manticore::Response
39
39
  end
40
40
 
41
41
  client.execute!
@@ -45,17 +45,17 @@ describe Manticore::Client do
45
45
  end
46
46
 
47
47
  describe Manticore::Client::AsyncProxy do
48
- it "should not make a request until execute is called" do
48
+ it "does not make a request until execute is called" do
49
49
  anchor = Time.now.to_f
50
50
  client.async.get("http://localhost:55441/?sleep=1.6")
51
- (Time.now.to_f - anchor).should < 1.0
51
+ expect(Time.now.to_f - anchor).to be < 1.0
52
52
 
53
53
  anchor = Time.now.to_f
54
54
  client.execute!
55
- (Time.now.to_f - anchor).should > 1.0
55
+ expect(Time.now.to_f - anchor).to be > 1.0
56
56
  end
57
57
 
58
- it "should return the response object, which may then have handlers attached" do
58
+ it "returns the response object, which may then have handlers attached" do
59
59
  response = client.async.get("http://localhost:55441/")
60
60
  success = false
61
61
  response.on_success do
@@ -63,29 +63,29 @@ describe Manticore::Client do
63
63
  end
64
64
 
65
65
  client.execute!
66
- success.should == true
66
+ expect(success).to eq true
67
67
  end
68
68
 
69
69
  it "can chain handlers" do
70
70
  client.async.get("http://localhost:55441/").on_success {|r| r.code }
71
- client.execute!.map(&:callback_result).should == [200]
71
+ expect(client.execute!.map(&:callback_result)).to eq [200]
72
72
  end
73
73
  end
74
74
 
75
75
  describe Manticore::Client::BackgroundProxy do
76
- it "should not block execution" do
76
+ it "does not block execution" do
77
77
  anchor = Time.now.to_f
78
78
  future = client.background.get("http://localhost:55441/?sleep=1.5")
79
- (Time.now.to_f - anchor).should < 1.0
79
+ expect(Time.now.to_f - anchor).to be < 1.0
80
80
 
81
81
  response = future.get
82
- (Time.now.to_f - anchor).should > 1.0
83
- response.body.should match(/sleep=1.5/)
82
+ expect(Time.now.to_f - anchor).to be > 1.0
83
+ expect(response.body).to match(/sleep=1.5/)
84
84
  end
85
85
 
86
- it "should return a future" do
86
+ it "returns a future" do
87
87
  response = client.background.get("http://localhost:55441/")
88
- response.should be_a Java::JavaUtilConcurrent::FutureTask
88
+ expect(response).to be_a Java::JavaUtilConcurrent::FutureTask
89
89
  response.get
90
90
  end
91
91
  end