rest 1.0.0 → 1.1.0

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.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rest (1.0.0)
5
+ rest-client (>= 0.3.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ffi (1.0.11)
11
+ mime-types (1.18)
12
+ net-http-persistent (2.7)
13
+ rake (0.9.2.2)
14
+ rest-client (1.6.7)
15
+ mime-types (>= 1.16)
16
+ test-unit (2.5.0)
17
+ typhoeus (0.4.2)
18
+ ffi (~> 1.0)
19
+ mime-types (~> 1.18)
20
+ uber_config (0.0.3)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ net-http-persistent
27
+ rake
28
+ rest!
29
+ test-unit
30
+ typhoeus
31
+ uber_config
@@ -0,0 +1,66 @@
1
+ Rest Wrapper
2
+ -------------
3
+
4
+ HTTP/REST client wrapper that provides a standard interface for making http requests using different http clients.
5
+ If no client is specified it will choose the best one you have installed.
6
+
7
+ Getting Started
8
+ ==============
9
+
10
+ Install the gem:
11
+
12
+ gem install rest
13
+
14
+ Create an Rest client:
15
+
16
+ @rest = Rest::Client.new()
17
+
18
+ To choose a specific underlying http client lib:
19
+
20
+ @rest = Rest::Client.new(:gem=>:typhoeus)
21
+
22
+ Supported http libraries are:
23
+
24
+ * rest-client
25
+ * net-http-persistent
26
+ * typhoeus
27
+
28
+ Then use it:
29
+
30
+ GET
31
+ =========
32
+
33
+ @rest.get(url, options...)
34
+
35
+ options:
36
+
37
+ - :params => query params for url
38
+ - :headers => headers
39
+
40
+ POST
41
+ ======
42
+
43
+ @rest.post(url, options...)
44
+
45
+ options:
46
+
47
+ - :body => POST body
48
+ - :headers => headers
49
+
50
+ PUT
51
+ ======
52
+
53
+ @rest.put(url, options...)
54
+
55
+ options:
56
+
57
+ - :body => POST body
58
+ - :headers => headers
59
+
60
+ DELETE
61
+ ======
62
+
63
+ @rest.delete(url, options...)
64
+
65
+
66
+
@@ -20,33 +20,12 @@ module Rest
20
20
  end
21
21
 
22
22
  def self.puts(s)
23
- Kernel.puts(s)
24
- end
25
-
26
-
27
- def self.gem=(g)
28
- @gem = g
29
- end
30
-
31
- def self.gem
32
- @gem
33
- end
34
-
35
- begin
36
- require 'typhoeus'
37
- Rest.gem = :typhoeus
38
- Rest.puts "Using typhoeus gem."
39
- require_relative 'wrappers/typhoeus_wrapper'
40
- rescue LoadError => ex
41
- Rest.puts "Please install 'typhoeus' gem for best performance."
42
- require 'rest_client'
43
- Rest.gem = :rest_client
44
- require_relative 'wrappers/rest_client_wrapper'
23
+ Kernel.puts("rest gem: #{s}")
45
24
  end
46
25
 
47
26
  class Client
48
27
 
49
- attr_accessor :options
28
+ attr_accessor :options, :logger, :gem
50
29
  # options:
51
30
  # - :gem => specify gem explicitly
52
31
  #
@@ -55,14 +34,43 @@ module Rest
55
34
  @logger.level=Logger::INFO
56
35
  @options = options
57
36
 
58
- Rest.gem = options[:gem] if options[:gem]
37
+ @gem = options[:gem] if options[:gem]
59
38
 
60
- if Rest.gem == :typhoeus
39
+ if @gem.nil?
40
+ choose_best_gem()
41
+ end
42
+
43
+ if @gem == :typhoeus
44
+ require_relative 'wrappers/typhoeus_wrapper'
61
45
  @wrapper = Rest::Wrappers::TyphoeusWrapper.new
46
+ Rest.puts "Using typhoeus gem."
47
+ elsif @gem == :net_http_persistent
48
+ require_relative 'wrappers/net_http_persistent_wrapper'
49
+ @wrapper = Rest::Wrappers::NetHttpPersistentWrapper.new(self)
50
+ Rest.puts "Using net-http-persistent gem."
62
51
  else
52
+ require_relative 'wrappers/rest_client_wrapper'
63
53
  @wrapper = Rest::Wrappers::RestClientWrapper.new
54
+ Rest.puts "Using rest-client gem. Please install 'typhoeus' or net-http-persistent gem for best performance."
64
55
  end
56
+ end
65
57
 
58
+ def choose_best_gem
59
+ begin
60
+ raise LoadError
61
+ require 'typhoeus'
62
+ @gem = :client
63
+ rescue LoadError => ex
64
+ begin
65
+ # try net-http-persistent
66
+ require 'net/http/persistent'
67
+ @gem = :net_http_persistent
68
+
69
+ rescue LoadError => ex
70
+ require 'rest_client'
71
+ @gem = :rest_client
72
+ end
73
+ end
66
74
  end
67
75
 
68
76
  def get(url, req_hash={})
@@ -84,11 +92,11 @@ module Rest
84
92
  #p res.code
85
93
  if res.code == 503
86
94
  pow = (4 ** (current_retry)) * 100 # milliseconds
87
- #puts 'pow=' + pow.to_s
95
+ #puts 'pow=' + pow.to_s
88
96
  s = Random.rand * pow
89
- #puts 's=' + s.to_s
97
+ #puts 's=' + s.to_s
90
98
  sleep_secs = 1.0 * s / 1000.0
91
- #puts 'sleep for ' + sleep_secs.to_s
99
+ #puts 'sleep for ' + sleep_secs.to_s
92
100
  current_retry += 1
93
101
  @logger.debug "503 Error. Retrying #{current_retry} out of #{max_retries} max."
94
102
  sleep sleep_secs
@@ -125,5 +133,10 @@ module Rest
125
133
  end
126
134
  return res
127
135
  end
136
+
137
+ def close
138
+ @wrapper.close
139
+ end
140
+
128
141
  end
129
142
  end
@@ -1,3 +1,3 @@
1
1
  module Rest
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,7 @@
1
+ class BaseWrapper
2
+
3
+ # if wrapper has a close/shutdown, override this
4
+ def close
5
+
6
+ end
7
+ end
@@ -0,0 +1,158 @@
1
+ require 'net/http/persistent'
2
+ require_relative 'base_wrapper'
3
+
4
+ module Rest
5
+
6
+ module Wrappers
7
+ class NetHttpPersistentExceptionWrapper < ClientError
8
+ def initialize(ex)
9
+ super(ex.message)
10
+ @ex = ex
11
+ end
12
+ end
13
+
14
+ class NetHttpPersistentResponseWrapper
15
+ def initialize(response)
16
+ @response = response
17
+ end
18
+
19
+ def code
20
+ @response.code.to_i
21
+ end
22
+
23
+ def body
24
+ @response.body
25
+ end
26
+
27
+ end
28
+
29
+ class NetHttpPersistentWrapper < BaseWrapper
30
+
31
+ attr_reader :http
32
+
33
+ def initialize(client)
34
+ @client = client
35
+ @http = Net::HTTP::Persistent.new 'rest_gem'
36
+ end
37
+
38
+ def default_headers
39
+ {}
40
+ end
41
+
42
+ def add_headers(post, req_hash, default_headers)
43
+ headers = {}
44
+ headers.merge!(default_headers)
45
+ headers.merge!(req_hash[:headers]) if req_hash[:headers]
46
+ headers.each_pair do |k, v|
47
+ post[k] = v
48
+ end
49
+ end
50
+
51
+ def get(url, req_hash={}, options={})
52
+ @client.logger.debug "limit #{options[:limit]}"
53
+ options[:limit] ||= 10
54
+ response = nil
55
+ begin
56
+
57
+ uri = URI(url)
58
+ #p uri
59
+ #p uri.path
60
+ post = Net::HTTP::Get.new fix_path(uri.path)
61
+ add_headers(post, req_hash, default_headers)
62
+ response = http.request uri, post
63
+ @client.logger.debug response.class.name
64
+ case response
65
+ when Net::HTTPRedirection
66
+ @client.logger.debug "moved to #{response['location']}"
67
+ response = get(response['location'], req_hash, {limit: options[:limit]-1})
68
+ when Net::HTTPMovedPermanently
69
+ @client.logger.debug "moved to #{response['location']}"
70
+ response = get(response['location'], req_hash, {limit: options[:limit]-1})
71
+ end
72
+ response = NetHttpPersistentResponseWrapper.new(response)
73
+ rescue Net::HTTPClientError => ex
74
+ if ex.code == 404
75
+ return NetHttpPersistentResponseWrapper.new(ex)
76
+ end
77
+ raise NetHttpPersistentExceptionWrapper.new(ex)
78
+ rescue Net::HTTPServerError => ex
79
+ if ex.code == 404
80
+ return NetHttpPersistentResponseWrapper.new(ex)
81
+ end
82
+ raise NetHttpPersistentExceptionWrapper.new(ex)
83
+ end
84
+ response
85
+ end
86
+
87
+ def fix_path(path)
88
+ return "/" if path.nil? || path == ""
89
+ path
90
+ end
91
+
92
+
93
+ def post(url, req_hash={})
94
+ response = nil
95
+ begin
96
+ uri = URI(url)
97
+ post = Net::HTTP::Post.new uri.path
98
+ add_headers(post, req_hash, default_headers)
99
+ post.body = stringed_body(req_hash[:body]) if req_hash[:body]
100
+ response = http.request uri, post
101
+ response = NetHttpPersistentResponseWrapper.new(response)
102
+ rescue Net::HTTPClientError => ex
103
+ raise NetHttpPersistentExceptionWrapper.new(ex)
104
+ rescue Net::HTTPServerError => ex
105
+ raise NetHttpPersistentExceptionWrapper.new(ex)
106
+ end
107
+ response
108
+ end
109
+
110
+ def stringed_body(body)
111
+ return nil unless body
112
+ if body.is_a?(Hash)
113
+ return body.to_json
114
+ end
115
+ body
116
+ end
117
+
118
+ def put(url, req_hash={})
119
+ response = nil
120
+ begin
121
+ uri = URI(url)
122
+ post = Net::HTTP::Put.new uri.path
123
+ add_headers(post, req_hash, default_headers)
124
+ post.body = stringed_body(req_hash[:body]) if req_hash[:body]
125
+ response = http.request uri, post
126
+ response = NetHttpPersistentResponseWrapper.new(response)
127
+ rescue Net::HTTPClientError => ex
128
+ raise NetHttpPersistentExceptionWrapper.new(ex)
129
+ rescue Net::HTTPServerError => ex
130
+ raise NetHttpPersistentExceptionWrapper.new(ex)
131
+ end
132
+ response
133
+ end
134
+
135
+ def delete(url, req_hash={})
136
+ response = nil
137
+ begin
138
+ uri = URI(url)
139
+ post = Net::HTTP::Delete.new uri.path
140
+ add_headers(post, req_hash, default_headers)
141
+ response = http.request uri, post
142
+ response = NetHttpPersistentResponseWrapper.new(response)
143
+ rescue Net::HTTPClientError => ex
144
+ raise NetHttpPersistentExceptionWrapper.new(ex)
145
+ rescue Net::HTTPServerError => ex
146
+ raise NetHttpPersistentExceptionWrapper.new(ex)
147
+ end
148
+ response
149
+ end
150
+
151
+ def close
152
+ http.shutdown
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ end
@@ -35,9 +35,17 @@ module Rest
35
35
  response
36
36
  end
37
37
 
38
+ # if body is a hash, it will convert it to json
39
+ def to_json_parts(h)
40
+ h[:body] = h[:body].to_json if h[:body] && h[:body].is_a?(Hash)
41
+ end
42
+
38
43
  def post(url, req_hash={})
39
44
  req_hash = default_typhoeus_options.merge(req_hash)
40
45
  # puts "REQ_HASH=" + req_hash.inspect
46
+
47
+ # Convert body to json - NEED TO TEST THIS MORE
48
+ to_json_parts(req_hash)
41
49
  response = Typhoeus::Request.post(url, req_hash)
42
50
  #p response
43
51
  if response.timed_out?
@@ -21,6 +21,8 @@ Gem::Specification.new do |gem|
21
21
  gem.add_development_dependency "test-unit"
22
22
  gem.add_development_dependency "rake"
23
23
  gem.add_development_dependency "uber_config"
24
+ gem.add_development_dependency "typhoeus"
25
+ gem.add_development_dependency "net-http-persistent"
24
26
 
25
27
  end
26
28
 
@@ -0,0 +1,43 @@
1
+ # Put config.yml file in ~/Dropbox/configs/ironmq_gem/test/config.yml
2
+
3
+ gem 'test-unit'
4
+ require 'test/unit'
5
+ require 'yaml'
6
+ require_relative 'test_base'
7
+
8
+ class TestTests < TestBase
9
+ def setup
10
+ super
11
+
12
+ end
13
+
14
+ def test_get_performance
15
+
16
+ times = 100
17
+
18
+ collector = []
19
+
20
+ collector << run_perf(times, :typhoeus)
21
+ collector << run_perf(times, :rest_client)
22
+ collector << run_perf(times, :net_http_persistent)
23
+
24
+ collector.each do |c|
25
+ p c
26
+ end
27
+
28
+ end
29
+
30
+ def run_perf(times, gem)
31
+ puts "Starting #{gem} test..."
32
+ t = Time.now
33
+ client = Rest::Client.new(:gem => gem)
34
+ times.times do |i|
35
+ client.get("http://requestb.in/ydyd4nyd")
36
+ end
37
+ duration = Time.now.to_f - t.to_f
38
+ puts "#{times} posts took #{duration}"
39
+ {:gem=>gem, :duration=>duration}
40
+ end
41
+
42
+ end
43
+
@@ -14,11 +14,35 @@ class TestTests < TestBase
14
14
 
15
15
  def test_basics
16
16
  response = @rest.get("http://www.github.com")
17
+ p response
18
+ p response.code
17
19
  assert response.code == 200
18
20
  #p response.body
19
21
  assert response.body.include?("Social Coding")
20
22
 
21
23
  end
22
24
 
25
+ def test_post_with_headers
26
+
27
+ @token = "abctoken"
28
+ headers = {
29
+ 'Content-Type' => 'application/json',
30
+ 'Authorization' => "OAuth #{@token}",
31
+ 'User-Agent' => "someagent"
32
+ }
33
+ body = {"foo" => "bar"}
34
+ response = @rest.post("http://requestb.in/ydyd4nyd",
35
+ :body => body,
36
+ :headers => headers)
37
+ p response
38
+
39
+ response = @rest.post("http://requestb.in/ydyd4nyd",
40
+ :body => "some string body",
41
+ :headers => headers)
42
+ p response
43
+
44
+
45
+ end
46
+
23
47
  end
24
48
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-25 00:00:00.000000000 Z
12
+ date: 2012-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -75,6 +75,38 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: typhoeus
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: net-http-persistent
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
78
110
  description: Rest client wrapper that chooses best installed client.
79
111
  email:
80
112
  - treeder@gmail.com
@@ -83,17 +115,21 @@ extensions: []
83
115
  extra_rdoc_files: []
84
116
  files:
85
117
  - .gitignore
118
+ - Gemfile
119
+ - Gemfile.lock
86
120
  - LICENSE
87
- - README.markdown
121
+ - README.md
88
122
  - Rakefile
89
- - VERSION.yml
90
123
  - lib/rest.rb
91
124
  - lib/rest/client.rb
92
125
  - lib/rest/version.rb
126
+ - lib/rest/wrappers/base_wrapper.rb
127
+ - lib/rest/wrappers/net_http_persistent_wrapper.rb
93
128
  - lib/rest/wrappers/rest_client_wrapper.rb
94
129
  - lib/rest/wrappers/typhoeus_wrapper.rb
95
130
  - rest.gemspec
96
131
  - test/test_base.rb
132
+ - test/test_performance.rb
97
133
  - test/test_rest.rb
98
134
  homepage: https://github.com/iron-io/rest
99
135
  licenses: []
@@ -121,4 +157,5 @@ specification_version: 3
121
157
  summary: Rest client wrapper that chooses best installed client.
122
158
  test_files:
123
159
  - test/test_base.rb
160
+ - test/test_performance.rb
124
161
  - test/test_rest.rb
@@ -1,43 +0,0 @@
1
- Rest Wrapper
2
- -------------
3
-
4
- Getting Started
5
- ==============
6
-
7
- Install the gem:
8
-
9
- gem install rest
10
-
11
- Create an IronMQ client object:
12
-
13
- @rest = Rest::Client.new()
14
-
15
- Then use it.
16
-
17
- GET
18
- =========
19
-
20
- @rest.get(url, options...)
21
-
22
- options:
23
-
24
- - :params => query params for url
25
- - :headers => headers
26
-
27
- POST
28
- ======
29
-
30
- @rest.post(url, options...)
31
-
32
- options:
33
-
34
- - :body => POST body
35
- - :headers => headers
36
-
37
- DELETE
38
- ======
39
-
40
- @rest.delete(url, options...)
41
-
42
-
43
-
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 3
4
- :patch: 0
5
- :build: