rest 1.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rest (1.2.1)
4
+ rest (1.2.2)
5
+ net-http-persistent
5
6
  rest-client (>= 0.3.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ excon (0.14.3)
10
12
  ffi (1.0.11)
11
13
  mime-types (1.19)
14
+ minitest (3.2.0)
12
15
  net-http-persistent (2.7)
13
16
  quicky (0.0.1)
14
17
  rake (0.9.2.2)
@@ -24,7 +27,8 @@ PLATFORMS
24
27
  ruby
25
28
 
26
29
  DEPENDENCIES
27
- net-http-persistent
30
+ excon
31
+ minitest
28
32
  quicky
29
33
  rake
30
34
  rest!
data/README.md CHANGED
@@ -1,8 +1,22 @@
1
1
  Rest Wrapper
2
2
  -------------
3
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.
4
+ HTTP/REST client wrapper that provides a standard interface for making http requests using different http
5
+ clients. If no client is specified **it will choose the best http client** you have installed based on
6
+ our performance tests.
7
+
8
+ Features
9
+ ========
10
+
11
+ * All clients behave exactly the same:
12
+ * Same error behavior
13
+ * Same 30X redirect behavior
14
+ * Same response object methods
15
+ * Same way to access and manipulate requests and responses such as body, headers, code, etc.
16
+ * Chooses best client you have installed on your system based on what we have found performs the best.
17
+ * Currently net_http_persistent and typhoeus are nearly the same, but since net_http_persistent doesn't have a binary
18
+ dependency, it wins.
19
+
6
20
 
7
21
  Getting Started
8
22
  ==============
@@ -70,3 +84,14 @@ The response object you get back will always be consistent and will have the fol
70
84
  response.code
71
85
  response.body
72
86
 
87
+
88
+ Exceptions
89
+ ======
90
+
91
+ If it didn't get a response for whatever reason, you will get a Rest::ClientError
92
+
93
+ If status code is 40X or 50X, it will raise an exception with the following methods.
94
+
95
+ err.code
96
+ err.response (which has body: err.response.body)
97
+
data/Rakefile CHANGED
@@ -6,6 +6,7 @@ Rake::TestTask.new(:test) do |test|
6
6
  test.libs << 'lib' << 'test'
7
7
  test.pattern = 'test/**/test_*.rb'
8
8
  test.verbose = true
9
+ p ENV['gem']
9
10
  end
10
11
 
11
12
  task :default => :test
@@ -5,26 +5,12 @@ require 'logger'
5
5
  # The purpose of this is so that users who can't install binaries easily (like windoze users)
6
6
  # can have fallbacks that work.
7
7
 
8
- module Rest
9
-
10
- class ClientError < StandardError
11
-
12
- end
8
+ require_relative 'errors'
13
9
 
14
-
15
- class TimeoutError < ClientError
16
- def initialize(msg=nil)
17
- msg ||= "HTTP Request Timed out."
18
- super(msg)
19
- end
20
- end
10
+ module Rest
21
11
 
22
12
  require_relative 'wrappers/base_wrapper'
23
13
 
24
- #def self.puts(s)
25
- # Kernel.puts("rest gem: #{s}")
26
- #end
27
-
28
14
  class Client
29
15
 
30
16
  attr_accessor :options, :logger, :gem
@@ -42,7 +28,11 @@ module Rest
42
28
  choose_best_gem()
43
29
  end
44
30
 
45
- if @gem == :typhoeus
31
+ if @gem == :excon
32
+ require_relative 'wrappers/excon_wrapper'
33
+ @wrapper = Rest::Wrappers::ExconWrapper.new(self)
34
+ @logger.debug "Using excon gem."
35
+ elsif @gem == :typhoeus
46
36
  require_relative 'wrappers/typhoeus_wrapper'
47
37
  @wrapper = Rest::Wrappers::TyphoeusWrapper.new
48
38
  @logger.debug "Using typhoeus gem."
@@ -60,13 +50,13 @@ module Rest
60
50
  def choose_best_gem
61
51
  begin
62
52
  raise LoadError
63
- #require 'typhoeus'
64
- #@gem = :client
53
+ require 'typhoeus'
54
+ @gem = :typhoeus
65
55
  rescue LoadError => ex
66
56
  begin
67
57
  # try net-http-persistent
68
- #require 'net/http/persistent'
69
- #@gem = :net_http_persistent
58
+ require 'net/http/persistent'
59
+ @gem = :net_http_persistent
70
60
  rescue LoadError => ex
71
61
  end
72
62
  end
@@ -78,7 +68,7 @@ module Rest
78
68
 
79
69
  def get(url, req_hash={})
80
70
  res = nil
81
- perform_op do
71
+ res = perform_op(:get, req_hash) do
82
72
  res = @wrapper.get(url, req_hash)
83
73
  end
84
74
  return res
@@ -86,38 +76,71 @@ module Rest
86
76
 
87
77
  # This will attempt to perform the operation with an exponential backoff on 503 errors.
88
78
  # Amazon services throw 503
89
- def perform_op(&blk)
90
- max_retries = @options[:max_retries] || 5
79
+ # todo: just make perform_op a method and have it call the wrapper. The block is a waste now.
80
+ def perform_op(method, req_hash, options={}, &blk)
81
+ set_defaults(options)
82
+ max_retries = options[:max_retries] || 5
83
+ max_follows = options[:max_follows] || 10
84
+ if options[:follow_count] && options[:follow_count] >= max_follows
85
+ raise Rest::RestError "Too many follows. #{options[:follow_count]}"
86
+ end
91
87
  current_retry = 0
88
+ current_follow = 0
92
89
  success = false
93
90
  res = nil
94
- while current_retry < max_retries do
95
- res = yield blk
96
- #p res
97
- #p res.code
98
- if res.code == 503
99
- pow = (4 ** (current_retry)) * 100 # milliseconds
100
- #puts 'pow=' + pow.to_s
101
- s = Random.rand * pow
102
- #puts 's=' + s.to_s
103
- sleep_secs = 1.0 * s / 1000.0
104
- puts 'sleep for ' + sleep_secs.to_s
105
- current_retry += 1
106
- @logger.debug "503 Received. Retrying #{current_retry} out of #{max_retries} max in #{sleep_secs} seconds."
107
- sleep sleep_secs
108
- else
91
+ while current_retry < max_retries && current_follow < max_follows do
92
+ begin
93
+ res = yield blk
94
+ res.tries = current_retry + 1
95
+ if res.code >= 300 && res.code < 400
96
+ # try new location
97
+ #p res.headers
98
+ loc = res.headers["location"]
99
+ @logger.debug "#{res.code} Received. Trying new location: #{loc}"
100
+ if loc.nil?
101
+ raise InvalidResponseError.new("No location header received with #{res.code} status code!")
102
+ end
103
+ # options.merge({:max_follows=>options[:max_follows-1]}
104
+ options[:follow_count] ||= 0
105
+ options[:follow_count] += 1
106
+ res = perform_op(method, req_hash, options) do
107
+ res = @wrapper.send(method, loc, req_hash)
108
+ end
109
+ #puts 'X: ' + res.inspect
110
+ return res
111
+ end
112
+ # If it's here, then it's all good
109
113
  break
114
+ rescue Rest::HttpError => ex
115
+ if ex.code == 503
116
+ pow = (4 ** (current_retry)) * 100 # milliseconds
117
+ #puts 'pow=' + pow.to_s
118
+ s = Random.rand * pow
119
+ #puts 's=' + s.to_s
120
+ sleep_secs = 1.0 * s / 1000.0
121
+ #puts 'sleep for ' + sleep_secs.to_s
122
+ current_retry += 1
123
+ @logger.debug "#{ex.code} Received. Retrying #{current_retry} out of #{max_retries} max in #{sleep_secs} seconds."
124
+ sleep sleep_secs
125
+ else
126
+ raise ex
127
+ end
110
128
  end
111
129
  end
112
130
  res
113
131
  end
114
132
 
133
+ def set_defaults(options)
134
+ options[:max_retries] ||= (@options[:max_retries] || 5)
135
+ options[:max_follows] ||= (@options[:max_follows] || 10)
136
+ end
137
+
115
138
  # req_hash options:
116
139
  # - :body => post body
117
140
  #
118
141
  def post(url, req_hash={})
119
142
  res = nil
120
- perform_op do
143
+ res = perform_op(:post, req_hash) do
121
144
  res = @wrapper.post(url, req_hash)
122
145
  end
123
146
  return res
@@ -125,7 +148,7 @@ module Rest
125
148
 
126
149
  def put(url, req_hash={})
127
150
  res = nil
128
- perform_op do
151
+ res = perform_op(:put, req_hash) do
129
152
  res = @wrapper.put(url, req_hash)
130
153
  end
131
154
  return res
@@ -133,7 +156,7 @@ module Rest
133
156
 
134
157
  def delete(url, req_hash={})
135
158
  res = nil
136
- perform_op do
159
+ res = perform_op(:delete, req_hash) do
137
160
  res = @wrapper.delete(url, req_hash)
138
161
  end
139
162
  return res
@@ -141,7 +164,7 @@ module Rest
141
164
 
142
165
  def post_file(url, req_hash={})
143
166
  res = nil
144
- perform_op do
167
+ res = perform_op(:post_file, req_hash) do
145
168
  res = @wrapper.post_file(url, req_hash)
146
169
  end
147
170
  return res
@@ -0,0 +1,43 @@
1
+
2
+ module Rest
3
+
4
+ # Base Rest error class
5
+ class RestError < StandardError
6
+
7
+ end
8
+
9
+ class HttpError < RestError
10
+ def initialize(response)
11
+ super("#{response.code} Error")
12
+ @response = response
13
+ end
14
+
15
+ def response
16
+ @response
17
+ end
18
+ def code
19
+ response.code
20
+ end
21
+
22
+ def to_s
23
+ "HTTP #{code} Error. #{response.body}"
24
+ end
25
+ end
26
+
27
+ # If it didn't even get a response, it will be a ClientError
28
+ class ClientError < RestError
29
+
30
+ end
31
+
32
+ class TimeoutError < ClientError
33
+ def initialize(msg=nil)
34
+ msg ||= "HTTP Request Timed out."
35
+ super(msg)
36
+ end
37
+ end
38
+
39
+ class InvalidResponseError < RestError
40
+
41
+ end
42
+ end
43
+
@@ -1,3 +1,3 @@
1
1
  module Rest
2
- VERSION = "1.2.2"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -1,29 +1,53 @@
1
- class BaseWrapper
2
-
3
- def post_file(url, req_hash={})
4
- response = nil
5
- begin
6
- if req_hash[:body]
7
- req_hash = req_hash.merge(req_hash[:body])
8
- req_hash.delete(:body)
9
- end
1
+ module Rest
2
+ class BaseWrapper
3
+
4
+ def post_file(url, req_hash={})
5
+ response = nil
6
+ begin
7
+ if req_hash[:body]
8
+ req_hash = req_hash.merge(req_hash[:body])
9
+ req_hash.delete(:body)
10
+ end
11
+
12
+ headers = {}
13
+ if req_hash[:headers]
14
+ headers = req_hash[:headers]
15
+ req_hash.delete(:headers)
16
+ end
10
17
 
11
- headers = {}
12
- if req_hash[:headers]
13
- headers = req_hash[:headers]
14
- req_hash.delete(:headers)
18
+ r2 = RestClient.post(url, req_hash, headers)
19
+ response = Rest::Wrappers::RestClientResponseWrapper.new(r2)
20
+ rescue RestClient::Exception => ex
21
+ raise Rest::Wrappers::RestClientExceptionWrapper.new(ex)
15
22
  end
23
+ response
24
+ end
25
+
26
+ # if body is a hash, it will convert it to json
27
+ def to_json_parts(h)
28
+ h[:body] = h[:body].to_json if h[:body] && h[:body].is_a?(Hash)
29
+ end
30
+
31
+ # if wrapper has a close/shutdown, override this
32
+ def close
16
33
 
17
- r2 = RestClient.post(url, req_hash, headers)
18
- response = Rest::Wrappers::RestClientResponseWrapper.new(r2)
19
- rescue RestClient::Exception => ex
20
- raise Rest::Wrappers::RestClientExceptionWrapper.new(ex)
21
34
  end
22
- response
23
35
  end
24
36
 
25
- # if wrapper has a close/shutdown, override this
26
- def close
37
+ class BaseResponseWrapper
38
+ attr_accessor :tries
39
+
40
+ # Provide a headers_orig method in your wrapper to allow this to work
41
+ def headers
42
+ new_h = {}
43
+ headers_orig.each_pair do |k,v|
44
+ if v.is_a?(Array) && v.size == 1
45
+ v = v[0]
46
+ end
47
+ new_h[k.downcase] = v
48
+ end
49
+ new_h
50
+ end
27
51
 
28
52
  end
29
53
  end
@@ -0,0 +1,111 @@
1
+ require 'excon'
2
+
3
+ module Rest
4
+
5
+ module Wrappers
6
+ class ExconExceptionWrapper < ClientError
7
+ def initialize(ex)
8
+ super(ex.message)
9
+ @ex = ex
10
+ end
11
+ end
12
+
13
+ class ExconResponseWrapper < BaseResponseWrapper
14
+ def initialize(response)
15
+ @response = response
16
+ end
17
+
18
+ def code
19
+ @response.status
20
+ end
21
+
22
+ def body
23
+ @response.body
24
+ end
25
+
26
+ def headers_orig
27
+ @response.headers
28
+ end
29
+
30
+ end
31
+
32
+ class ExconWrapper < BaseWrapper
33
+
34
+ def initialize(client)
35
+ @client = client
36
+ # Would need to pass in base url to use persistent connection.
37
+ #@http = Excon.new("")
38
+ end
39
+
40
+ def default_headers
41
+ {}
42
+ end
43
+
44
+ def get(url, req_hash={})
45
+ response = nil
46
+ begin
47
+ uri = URI(url)
48
+ req_hash[:method] = :get
49
+ req_hash[:url] = url
50
+ req_hash[:headers] ||= default_headers
51
+ req_hash[:query] = req_hash[:params] if req_hash[:params]
52
+ #p req_hash
53
+ response = excon_request(url, req_hash)
54
+ rescue RestClient::Exception => ex
55
+ #p ex
56
+ raise ExconExceptionWrapper.new(ex)
57
+ end
58
+ response
59
+ end
60
+
61
+ def excon_request(url, req_hash)
62
+ conn = Excon.new(url)
63
+ r2 = conn.request(req_hash)
64
+ response = ExconResponseWrapper.new(r2)
65
+ if response.code >= 400
66
+ raise HttpError.new(response)
67
+ end
68
+ response
69
+ end
70
+
71
+ def post(url, req_hash={})
72
+ response = nil
73
+ begin
74
+ req_hash[:method] = :post
75
+ req_hash[:url] = url
76
+ to_json_parts(req_hash)
77
+ response = excon_request(url, req_hash)
78
+ rescue RestClient::Exception => ex
79
+ raise HttpError.new(ex)
80
+ end
81
+ response
82
+ end
83
+
84
+ def put(url, req_hash={})
85
+ response = nil
86
+ begin
87
+ req_hash[:method] = :put
88
+ req_hash[:url] = url
89
+ response = excon_request(url, req_hash)
90
+ rescue RestClient::Exception => ex
91
+ raise RestClientExceptionWrapper.new(ex)
92
+ end
93
+ response
94
+ end
95
+
96
+ def delete(url, req_hash={})
97
+ response = nil
98
+ begin
99
+ req_hash[:method] = :delete
100
+ req_hash[:url] = url
101
+ response = excon_request(url, req_hash)
102
+ rescue RestClient::Exception => ex
103
+ raise RestClientExceptionWrapper.new(ex)
104
+ end
105
+ response
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
@@ -10,7 +10,7 @@ module Rest
10
10
  end
11
11
  end
12
12
 
13
- class NetHttpPersistentResponseWrapper
13
+ class NetHttpPersistentResponseWrapper < BaseResponseWrapper
14
14
  def initialize(response)
15
15
  @response = response
16
16
  end
@@ -23,6 +23,10 @@ module Rest
23
23
  @response.body
24
24
  end
25
25
 
26
+ def headers_orig
27
+ @response.to_hash
28
+ end
29
+
26
30
  end
27
31
 
28
32
  class NetHttpPersistentWrapper < BaseWrapper
@@ -36,7 +40,7 @@ module Rest
36
40
 
37
41
  def default_headers
38
42
  {
39
- "Accept-Encoding" => "gzip, deflate",
43
+ #"Accept-Encoding" => "gzip, deflate",
40
44
  #"Accept" => "*/*; q=0.5, application/xml"
41
45
  }
42
46
  end
@@ -53,37 +57,49 @@ module Rest
53
57
  def get(url, req_hash={}, options={})
54
58
  @client.logger.debug "limit #{options[:limit]}"
55
59
  options[:limit] ||= 10
56
- response = nil
60
+ r = nil
57
61
  begin
58
62
 
59
63
  uri = URI(url)
60
64
  #p uri
61
65
  #p uri.path
66
+ #p uri.request_uri
67
+ #puts "query: " + uri.query.inspect
68
+ #puts "fragment: " + uri.fragment.inspect
69
+ if req_hash[:params]
70
+ new_q = URI.encode_www_form(req_hash[:params])
71
+ if uri.query
72
+ new_q = uri.query + "&" + new_q
73
+ end
74
+ #puts "new_q: " + new_q
75
+ uri.query = new_q
76
+ end
77
+ #p uri.request_uri
62
78
  post = Net::HTTP::Get.new fix_path(uri.request_uri)
63
79
  add_headers(post, req_hash, default_headers)
64
80
  response = http.request uri, post
65
81
  @client.logger.debug response.class.name
82
+ r = NetHttpPersistentResponseWrapper.new(response)
66
83
  case response
67
- when Net::HTTPRedirection
68
- @client.logger.debug "moved to #{response['location']}"
69
- response = get(response['location'], req_hash, {limit: options[:limit]-1})
70
- when Net::HTTPMovedPermanently
71
- @client.logger.debug "moved to #{response['location']}"
72
- response = get(response['location'], req_hash, {limit: options[:limit]-1})
73
- end
74
- response = NetHttpPersistentResponseWrapper.new(response)
75
- rescue Net::HTTPClientError => ex
76
- if ex.code == 404
77
- return NetHttpPersistentResponseWrapper.new(ex)
78
- end
79
- raise NetHttpPersistentExceptionWrapper.new(ex)
80
- rescue Net::HTTPServerError => ex
81
- if ex.code == 404
82
- return NetHttpPersistentResponseWrapper.new(ex)
84
+ when Net::HTTPClientError, Net::HTTPServerError
85
+ raise Rest::HttpError.new(r)
83
86
  end
84
- raise NetHttpPersistentExceptionWrapper.new(ex)
87
+ # when Net::HTTPRedirection
88
+ # @client.logger.debug "moved to #{response['location']}"
89
+ # response = get(response['location'], req_hash, {limit: options[:limit]-1})
90
+ # when Net::HTTPMovedPermanently
91
+ # @client.logger.debug "moved to #{response['location']}"
92
+ # response = get(response['location'], req_hash, {limit: options[:limit]-1})
93
+ #end
94
+ #rescue Net::HTTPClientError, Net::HTTPServerError => ex
95
+ # raise NetHttpPersistentExceptionWrapper.new(ex)
96
+ #rescue Net::HTTPServerError => ex
97
+ # if ex.code == 404
98
+ # return NetHttpPersistentResponseWrapper.new(ex)
99
+ # end
100
+ # raise NetHttpPersistentExceptionWrapper.new(ex)
85
101
  end
86
- response
102
+ r
87
103
  end
88
104
 
89
105
  def fix_path(path)
@@ -3,14 +3,16 @@ require 'rest_client'
3
3
  module Rest
4
4
 
5
5
  module Wrappers
6
- class RestClientExceptionWrapper < ClientError
6
+ class RestClientExceptionWrapper < HttpError
7
+ attr_reader :ex
8
+
7
9
  def initialize(ex)
8
- super(ex.message)
10
+ super(ex.response)
9
11
  @ex = ex
10
12
  end
11
13
  end
12
14
 
13
- class RestClientResponseWrapper
15
+ class RestClientResponseWrapper < BaseResponseWrapper
14
16
  def initialize(response)
15
17
  @response = response
16
18
  end
@@ -23,6 +25,10 @@ module Rest
23
25
  @response.body
24
26
  end
25
27
 
28
+ def headers_orig
29
+ @response.headers
30
+ end
31
+
26
32
  end
27
33
 
28
34
  class RestClientWrapper < BaseWrapper
@@ -43,9 +49,9 @@ module Rest
43
49
  response = RestClientResponseWrapper.new(r2)
44
50
  rescue RestClient::Exception => ex
45
51
  #p ex
46
- if ex.http_code == 404
47
- return RestClientResponseWrapper.new(ex.response)
48
- end
52
+ #if ex.http_code == 404
53
+ # return RestClientResponseWrapper.new(ex.response)
54
+ #end
49
55
  raise RestClientExceptionWrapper.new(ex)
50
56
  end
51
57
  response
@@ -11,6 +11,26 @@ module Rest
11
11
  end
12
12
  end
13
13
 
14
+ class TyphoeusResponseWrapper < BaseResponseWrapper
15
+
16
+ def initialize(response)
17
+ @response = response
18
+ end
19
+
20
+ def code
21
+ @response.code
22
+ end
23
+
24
+ def body
25
+ @response.body
26
+ end
27
+
28
+ def headers_orig
29
+ @response.headers_hash
30
+ end
31
+
32
+ end
33
+
14
34
  class TyphoeusWrapper < BaseWrapper
15
35
 
16
36
  def default_typhoeus_options
@@ -28,29 +48,28 @@ module Rest
28
48
  # puts "REQ_HASH=" + req_hash.inspect
29
49
  response = Typhoeus::Request.get(url, req_hash)
30
50
  #p response
51
+ response = handle_response(response)
52
+ response
53
+ end
54
+
55
+ def handle_response(response)
31
56
  if response.timed_out?
32
57
  raise TyphoeusTimeoutError.new(response)
33
58
  end
34
-
35
- response
59
+ r = TyphoeusResponseWrapper.new(response)
60
+ if response.code >= 400
61
+ raise Rest::HttpError.new(r)
62
+ end
63
+ r
36
64
  end
37
65
 
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
66
+
42
67
 
43
68
  def post(url, req_hash={})
44
69
  req_hash = default_typhoeus_options.merge(req_hash)
45
- # puts "REQ_HASH=" + req_hash.inspect
46
-
47
- # Convert body to json - NEED TO TEST THIS MORE
48
70
  to_json_parts(req_hash)
49
71
  response = Typhoeus::Request.post(url, req_hash)
50
- #p response
51
- if response.timed_out?
52
- raise TyphoeusTimeoutError.new(response)
53
- end
72
+ response = handle_response(response)
54
73
  response
55
74
  end
56
75
 
@@ -58,19 +77,14 @@ module Rest
58
77
  req_hash = default_typhoeus_options.merge(req_hash)
59
78
  # puts "REQ_HASH=" + req_hash.inspect
60
79
  response = Typhoeus::Request.put(url, req_hash)
61
- #p response
62
- if response.timed_out?
63
- raise TyphoeusTimeoutError.new(response)
64
- end
80
+ response = handle_response(response)
65
81
  response
66
82
  end
67
83
 
68
84
  def delete(url, req_hash={})
69
85
  req_hash = default_typhoeus_options.merge(req_hash)
70
86
  response = Typhoeus::Request.delete(url, req_hash)
71
- if response.timed_out?
72
- raise TyphoeusTimeoutError.new(response)
73
- end
87
+ response = handle_response(response)
74
88
  response
75
89
  end
76
90
 
@@ -17,13 +17,15 @@ Gem::Specification.new do |gem|
17
17
  gem.required_rubygems_version = ">= 1.3.6"
18
18
  gem.required_ruby_version = Gem::Requirement.new(">= 1.9")
19
19
  gem.add_runtime_dependency "rest-client", ">= 0.3.0"
20
+ gem.add_runtime_dependency "net-http-persistent"
20
21
 
21
22
  gem.add_development_dependency "test-unit"
23
+ gem.add_development_dependency "minitest"
22
24
  gem.add_development_dependency "rake"
23
25
  gem.add_development_dependency "uber_config"
24
26
  gem.add_development_dependency "typhoeus"
25
27
  gem.add_development_dependency "quicky"
26
- gem.add_development_dependency "net-http-persistent"
28
+ gem.add_development_dependency "excon"
27
29
 
28
30
  end
29
31
 
@@ -8,13 +8,18 @@ rescue Exception => ex
8
8
  raise ex
9
9
  end
10
10
 
11
-
12
11
  class TestBase < Test::Unit::TestCase
13
- def setup
12
+
13
+ def setup
14
14
  puts 'setup'
15
- #@config = YAML::load_file(File.expand_path(File.join("~", "Dropbox", "configs", "rest", "test", "config.yml")))
16
- @rest = Rest::Client.new(:gem=>:rest_client)
15
+ @rest = Rest::Client.new(:gem => :net_http_persistent)
17
16
  @rest.logger.level = Logger::DEBUG
17
+ @request_bin = "http://requestb.in/13t6hs51"
18
18
 
19
19
  end
20
+
21
+ def bin
22
+ @request_bin
23
+ end
24
+
20
25
  end
@@ -5,19 +5,20 @@ require 'quicky'
5
5
 
6
6
  require_relative 'test_base'
7
7
 
8
- class TestTests < TestBase
8
+ class TestPerformance < TestBase
9
9
  def setup
10
10
  super
11
11
 
12
12
  end
13
13
 
14
14
  def test_get_performance
15
+ puts 'test_get_performance'
15
16
 
16
- times = 10
17
+ times = 100
17
18
 
18
19
  quicky = Quicky::Timer.new
19
20
 
20
- to_run = [:typhoeus, :rest_client, :net_http_persistent]
21
+ to_run = [:typhoeus, :rest_client, :net_http_persistent, :excon]
21
22
  to_run.each do |gem|
22
23
  run_perf(quicky, times, gem)
23
24
  end
@@ -32,7 +33,7 @@ class TestTests < TestBase
32
33
  puts "Starting #{gem} test..."
33
34
  client = Rest::Client.new(:gem => gem)
34
35
  quicky.loop(gem, times) do
35
- client.get("http://requestb.in/ydyd4nyd")
36
+ client.get("http://rest-test.iron.io/code/200")
36
37
  end
37
38
  end
38
39
 
@@ -5,7 +5,7 @@ require 'test/unit'
5
5
  require 'yaml'
6
6
  require_relative 'test_base'
7
7
 
8
- class TestTests < TestBase
8
+ class TestRest < TestBase
9
9
  def setup
10
10
  super
11
11
 
@@ -17,7 +17,7 @@ class TestTests < TestBase
17
17
  p response
18
18
  p response.code
19
19
  assert response.code == 200
20
- #p response.body
20
+ p response.body
21
21
  assert response.body.include?("Social Coding")
22
22
  end
23
23
 
@@ -25,6 +25,9 @@ class TestTests < TestBase
25
25
  response = @rest.get("http://rest-test.iron.io/code/503?switch_after=3&switch_to=200")
26
26
  p response
27
27
  p response.code
28
+ p response.tries == 3
29
+ assert response.code == 200
30
+
28
31
  end
29
32
 
30
33
  def test_gets
@@ -35,8 +38,64 @@ class TestTests < TestBase
35
38
  'User-Agent' => "someagent"
36
39
  }
37
40
  body = {"foo" => "bar"}
38
- response = @rest.get("http://requestb.in/16q6zwq1?param1=x")
41
+ response = @rest.get("#{bin}?param1=x")
42
+
43
+ # params as hash
44
+ response = @rest.get("#{bin}?x=y#frag", :params => {:param2 => "abc"})
45
+ response = @rest.get("#{bin}", :params => {param3: "xyz"})
46
+ response = @rest.get("#{bin}")
47
+
48
+ response = @rest.get("http://rest-test.iron.io/code/200")
49
+ assert response.code == 200
50
+ assert response.body.include?("200")
51
+ p response.headers
52
+ assert response.headers.is_a?(Hash)
53
+
54
+ end
39
55
 
56
+ def test_404
57
+ begin
58
+ response = @rest.get("http://rest-test.iron.io/code/404")
59
+ assert false, "shouldn't get here"
60
+ rescue Rest::HttpError => ex
61
+ puts "EX: " + ex.inspect
62
+ p ex.backtrace
63
+ assert ex.is_a?(Rest::HttpError)
64
+ assert ex.response
65
+ assert ex.response.body
66
+ assert ex.code == 404
67
+ assert ex.response.body.include?("404")
68
+ assert ex.to_s.include?("404")
69
+ end
70
+ end
71
+
72
+ def test_400
73
+ begin
74
+ response = @rest.get("http://rest-test.iron.io/code/400")
75
+ assert false, "shouldn't get here"
76
+ rescue Rest::HttpError => ex
77
+ puts "EX: #{ex}"
78
+ p ex.backtrace
79
+ assert ex.is_a?(Rest::HttpError)
80
+ assert ex.response
81
+ assert ex.response.body
82
+ assert ex.code == 400
83
+ end
84
+ end
85
+
86
+ def test_500
87
+ puts '500'
88
+ begin
89
+ response = @rest.get("http://rest-test.iron.io/code/500")
90
+ assert false, "shouldn't get here"
91
+ rescue Rest::HttpError => ex
92
+ puts "EX: " + ex.inspect
93
+ p ex.backtrace
94
+ assert ex.is_a?(Rest::HttpError)
95
+ assert ex.response
96
+ assert ex.response.body
97
+ assert ex.code == 500
98
+ end
40
99
  end
41
100
 
42
101
  def test_post_with_headers
@@ -48,12 +107,16 @@ class TestTests < TestBase
48
107
  'User-Agent' => "someagent"
49
108
  }
50
109
  body = {"foo" => "bar"}
51
- response = @rest.post("http://requestb.in/ydyd4nyd",
110
+ response = @rest.post("#{bin}",
111
+ :body => body,
112
+ :headers => headers)
113
+ p response
114
+ response = @rest.post("http://rest-test.iron.io/code/200",
52
115
  :body => body,
53
116
  :headers => headers)
54
117
  p response
55
118
 
56
- response = @rest.post("http://requestb.in/ydyd4nyd",
119
+ response = @rest.post("#{bin}",
57
120
  :body => "some string body",
58
121
  :headers => headers)
59
122
  p response
@@ -1,14 +1,27 @@
1
+ gem 'test-unit'
2
+ require 'test/unit'
1
3
  require 'yaml'
2
- begin
3
- require File.join(File.dirname(__FILE__), '../lib/rest')
4
- rescue Exception => ex
5
- puts "Could NOT load gem: " + ex.message
6
- raise ex
7
- end
4
+ require_relative 'test_base'
5
+
6
+ class TestTemp < TestBase
7
+ def setup
8
+ super
8
9
 
9
- @rest = Rest::Client.new # (:gem=>:rest_client)
10
- @rest.logger.level = Logger::DEBUG
10
+ end
11
+
12
+ def test_500
13
+ puts '500'
14
+ begin
15
+ puts 'in block'
16
+ response = @rest.get("http://rest-test.iron.io/code/500")
17
+ assert false, "shouldn't get here"
18
+ rescue => ex
19
+ p ex
20
+ assert ex.is_a?(Rest::HttpError)
21
+ assert ex.response
22
+ assert ex.response.body
23
+ assert ex.code == 500
24
+ end
25
+ end
26
+ end
11
27
 
12
- response = @rest.get("http://smooth-sword-1395.herokuapp.com/code/503?switch_after=3&switch_to=200")
13
- p response
14
- p response.code
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.2.2
4
+ version: 2.0.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-07-09 00:00:00.000000000 Z
12
+ date: 2012-07-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: 0.3.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-http-persistent
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: test-unit
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +59,22 @@ dependencies:
43
59
  - - ! '>='
44
60
  - !ruby/object:Gem::Version
45
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: rake
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +140,7 @@ dependencies:
108
140
  - !ruby/object:Gem::Version
109
141
  version: '0'
110
142
  - !ruby/object:Gem::Dependency
111
- name: net-http-persistent
143
+ name: excon
112
144
  requirement: !ruby/object:Gem::Requirement
113
145
  none: false
114
146
  requirements:
@@ -138,8 +170,10 @@ files:
138
170
  - Rakefile
139
171
  - lib/rest.rb
140
172
  - lib/rest/client.rb
173
+ - lib/rest/errors.rb
141
174
  - lib/rest/version.rb
142
175
  - lib/rest/wrappers/base_wrapper.rb
176
+ - lib/rest/wrappers/excon_wrapper.rb
143
177
  - lib/rest/wrappers/net_http_persistent_wrapper.rb
144
178
  - lib/rest/wrappers/rest_client_wrapper.rb
145
179
  - lib/rest/wrappers/typhoeus_wrapper.rb