manticore 0.4.2-java → 0.4.3-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
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