rest 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: