httparty 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of httparty might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/History +18 -0
- data/Rakefile +10 -2
- data/VERSION +1 -1
- data/bin/httparty +0 -1
- data/httparty.gemspec +7 -6
- data/lib/httparty.rb +47 -6
- data/lib/httparty/exceptions.rb +18 -2
- data/lib/httparty/parser.rb +3 -2
- data/lib/httparty/request.rb +27 -14
- data/spec/httparty/request_spec.rb +70 -28
- data/spec/httparty_spec.rb +37 -7
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +3 -12
- data/spec/support/stub_response.rb +30 -0
- metadata +6 -5
- data/lib/httparty/version.rb +0 -3
data/History
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
== 0.5.1 2010-01-30
|
2
|
+
* bug fixes
|
3
|
+
* Handle 304 response correctly by returning the HTTParty::Response object instead of redirecting (seth and hellvinz)
|
4
|
+
* Only redirect 300 responses if the header contains a Location
|
5
|
+
* Don't append empty query strings to the uri. Closes #31
|
6
|
+
* When no_follow is enabled, only raise the RedirectionTooDeep exception when a response tries redirecting. Closes #28
|
7
|
+
|
8
|
+
* major enhancements
|
9
|
+
* Removed rubygems dependency. I suggest adding rubygems to RUBYOPT if this causes problems for you.
|
10
|
+
$ export RUBYOPT='rubygems'
|
11
|
+
* HTTParty#debug_output prints debugging information for the current request (iwarshak)
|
12
|
+
* HTTParty#no_follow now available as a class-level option. Sets whether or not to follow redirects.
|
13
|
+
|
14
|
+
* minor enhancements
|
15
|
+
* HTTParty::VERSION now available
|
16
|
+
* Update crack requirement to version 0.1.5
|
17
|
+
|
1
18
|
== 0.5.0 2009-12-07
|
2
19
|
* bug fixes
|
3
20
|
* inheritable attributes no longer mutable by subclasses (yyyc514)
|
@@ -21,6 +38,7 @@
|
|
21
38
|
* Fixed class-level headers overwritten by cookie management code. Closes #19
|
22
39
|
* Fixed "superclass mismatch for class BlankSlate" error. Closes #20
|
23
40
|
* Fixed reading files as post data from the command line (vesan)
|
41
|
+
|
24
42
|
* minor enhancements
|
25
43
|
* Timeout option added; will raise a Timeout::Error after the timeout has elapsed (attack). Closes #17
|
26
44
|
HTTParty.get "http://github.com", :timeout => 1
|
data/Rakefile
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'rake'
|
3
2
|
|
4
3
|
begin
|
@@ -10,7 +9,7 @@ begin
|
|
10
9
|
gem.email = "nunemaker@gmail.com"
|
11
10
|
gem.homepage = "http://httparty.rubyforge.org"
|
12
11
|
gem.authors = ["John Nunemaker", "Sandro Turriate"]
|
13
|
-
gem.add_dependency 'crack', '
|
12
|
+
gem.add_dependency 'crack', '0.1.5'
|
14
13
|
gem.add_development_dependency "activesupport", "~>2.3"
|
15
14
|
gem.add_development_dependency "cucumber", "~>0.4"
|
16
15
|
gem.add_development_dependency "fakeweb", "~>1.2"
|
@@ -68,9 +67,18 @@ Rake::RDocTask.new do |rdoc|
|
|
68
67
|
rdoc.title = "httparty #{version}"
|
69
68
|
rdoc.rdoc_files.include('README*')
|
70
69
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
70
|
+
rdoc.rdoc_files.include('lib/httparty.rb')
|
71
71
|
end
|
72
72
|
|
73
73
|
desc 'Upload website files to rubyforge'
|
74
74
|
task :website do
|
75
75
|
sh %{rsync -av website/ jnunemaker@rubyforge.org:/var/www/gforge-projects/httparty}
|
76
76
|
end
|
77
|
+
|
78
|
+
begin
|
79
|
+
require 'yard'
|
80
|
+
YARD::Rake::YardocTask.new do |t|
|
81
|
+
t.options = ['--verbose']
|
82
|
+
end
|
83
|
+
rescue LoadError
|
84
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.1
|
data/bin/httparty
CHANGED
data/httparty.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{httparty}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Nunemaker", "Sandro Turriate"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-30}
|
13
13
|
s.default_executable = %q{httparty}
|
14
14
|
s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
15
15
|
s.email = %q{nunemaker@gmail.com}
|
@@ -55,7 +55,6 @@ Gem::Specification.new do |s|
|
|
55
55
|
"lib/httparty/parser.rb",
|
56
56
|
"lib/httparty/request.rb",
|
57
57
|
"lib/httparty/response.rb",
|
58
|
-
"lib/httparty/version.rb",
|
59
58
|
"spec/fixtures/delicious.xml",
|
60
59
|
"spec/fixtures/empty.xml",
|
61
60
|
"spec/fixtures/google.html",
|
@@ -69,6 +68,7 @@ Gem::Specification.new do |s|
|
|
69
68
|
"spec/httparty_spec.rb",
|
70
69
|
"spec/spec.opts",
|
71
70
|
"spec/spec_helper.rb",
|
71
|
+
"spec/support/stub_response.rb",
|
72
72
|
"website/css/common.css",
|
73
73
|
"website/index.html"
|
74
74
|
]
|
@@ -86,6 +86,7 @@ Gem::Specification.new do |s|
|
|
86
86
|
"spec/httparty/response_spec.rb",
|
87
87
|
"spec/httparty_spec.rb",
|
88
88
|
"spec/spec_helper.rb",
|
89
|
+
"spec/support/stub_response.rb",
|
89
90
|
"examples/aaws.rb",
|
90
91
|
"examples/basic.rb",
|
91
92
|
"examples/custom_parsers.rb",
|
@@ -101,14 +102,14 @@ Gem::Specification.new do |s|
|
|
101
102
|
s.specification_version = 3
|
102
103
|
|
103
104
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
104
|
-
s.add_runtime_dependency(%q<crack>, ["
|
105
|
+
s.add_runtime_dependency(%q<crack>, ["= 0.1.5"])
|
105
106
|
s.add_development_dependency(%q<activesupport>, ["~> 2.3"])
|
106
107
|
s.add_development_dependency(%q<cucumber>, ["~> 0.4"])
|
107
108
|
s.add_development_dependency(%q<fakeweb>, ["~> 1.2"])
|
108
109
|
s.add_development_dependency(%q<mongrel>, ["~> 1.1"])
|
109
110
|
s.add_development_dependency(%q<rspec>, ["= 1.2.9"])
|
110
111
|
else
|
111
|
-
s.add_dependency(%q<crack>, ["
|
112
|
+
s.add_dependency(%q<crack>, ["= 0.1.5"])
|
112
113
|
s.add_dependency(%q<activesupport>, ["~> 2.3"])
|
113
114
|
s.add_dependency(%q<cucumber>, ["~> 0.4"])
|
114
115
|
s.add_dependency(%q<fakeweb>, ["~> 1.2"])
|
@@ -116,7 +117,7 @@ Gem::Specification.new do |s|
|
|
116
117
|
s.add_dependency(%q<rspec>, ["= 1.2.9"])
|
117
118
|
end
|
118
119
|
else
|
119
|
-
s.add_dependency(%q<crack>, ["
|
120
|
+
s.add_dependency(%q<crack>, ["= 0.1.5"])
|
120
121
|
s.add_dependency(%q<activesupport>, ["~> 2.3"])
|
121
122
|
s.add_dependency(%q<cucumber>, ["~> 0.4"])
|
122
123
|
s.add_dependency(%q<fakeweb>, ["~> 1.2"])
|
data/lib/httparty.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'net/http'
|
3
3
|
require 'net/https'
|
4
|
-
require 'rubygems'
|
5
|
-
gem 'crack', '>= 0.1.1'
|
6
4
|
require 'crack'
|
7
5
|
|
6
|
+
if (Crack::const_defined?(:VERSION)) && Crack::VERSION != "0.1.5"
|
7
|
+
warn "warning: HTTParty depends on version 0.1.5 of crack, not #{Crack::VERSION}."
|
8
|
+
end
|
9
|
+
|
8
10
|
dir = Pathname(__FILE__).dirname.expand_path
|
9
11
|
|
10
12
|
require dir + 'httparty/module_inheritable_attributes'
|
11
13
|
require dir + 'httparty/cookie_hash'
|
12
14
|
|
13
15
|
module HTTParty
|
16
|
+
VERSION = "0.5.1".freeze
|
17
|
+
|
14
18
|
module AllowedFormatsDeprecation
|
15
19
|
def const_missing(const)
|
16
20
|
if const.to_s =~ /AllowedFormats$/
|
@@ -82,6 +86,17 @@ module HTTParty
|
|
82
86
|
default_options[:default_params].merge!(h)
|
83
87
|
end
|
84
88
|
|
89
|
+
# Set an output stream for debugging, defaults to $stderr.
|
90
|
+
# The output stream is passed on to Net::HTTP#set_debug_output.
|
91
|
+
#
|
92
|
+
# class Foo
|
93
|
+
# include HTTParty
|
94
|
+
# debug_output $stderr
|
95
|
+
# end
|
96
|
+
def debug_output(stream = $stderr)
|
97
|
+
default_options[:debug_output] = stream
|
98
|
+
end
|
99
|
+
|
85
100
|
# Allows setting a base uri to be used for each request.
|
86
101
|
#
|
87
102
|
# class Foo
|
@@ -116,6 +131,29 @@ module HTTParty
|
|
116
131
|
end
|
117
132
|
end
|
118
133
|
|
134
|
+
# Declare whether or not to follow redirects. When true, an
|
135
|
+
# {HTTParty::RedirectionTooDeep} error will raise upon encountering a
|
136
|
+
# redirect. You can then gain access to the response object via
|
137
|
+
# HTTParty::RedirectionTooDeep#response.
|
138
|
+
#
|
139
|
+
# @see HTTParty::ResponseError#response
|
140
|
+
#
|
141
|
+
# @example
|
142
|
+
# class Foo
|
143
|
+
# include HTTParty
|
144
|
+
# base_uri 'http://google.com'
|
145
|
+
# no_follow true
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# begin
|
149
|
+
# Foo.get('/')
|
150
|
+
# rescue HTTParty::RedirectionTooDeep => e
|
151
|
+
# puts e.response.body
|
152
|
+
# end
|
153
|
+
def no_follow(value = false)
|
154
|
+
default_options[:no_follow] = value
|
155
|
+
end
|
156
|
+
|
119
157
|
# Allows setting a PEM file to be used
|
120
158
|
#
|
121
159
|
# class Foo
|
@@ -132,11 +170,11 @@ module HTTParty
|
|
132
170
|
# include HTTParty
|
133
171
|
# parser Proc.new {|data| ...}
|
134
172
|
# end
|
135
|
-
def parser(
|
136
|
-
if
|
173
|
+
def parser(custom_parser = nil)
|
174
|
+
if custom_parser.nil?
|
137
175
|
default_options[:parser]
|
138
176
|
else
|
139
|
-
default_options[:parser] =
|
177
|
+
default_options[:parser] = custom_parser
|
140
178
|
validate_format
|
141
179
|
end
|
142
180
|
end
|
@@ -173,18 +211,22 @@ module HTTParty
|
|
173
211
|
perform_request Net::HTTP::Post, path, options
|
174
212
|
end
|
175
213
|
|
214
|
+
# Perform a PUT request to a path
|
176
215
|
def put(path, options={})
|
177
216
|
perform_request Net::HTTP::Put, path, options
|
178
217
|
end
|
179
218
|
|
219
|
+
# Perform a DELETE request to a path
|
180
220
|
def delete(path, options={})
|
181
221
|
perform_request Net::HTTP::Delete, path, options
|
182
222
|
end
|
183
223
|
|
224
|
+
# Perform a HEAD request to a path
|
184
225
|
def head(path, options={})
|
185
226
|
perform_request Net::HTTP::Head, path, options
|
186
227
|
end
|
187
228
|
|
229
|
+
# Perform an OPTIONS request to a path
|
188
230
|
def options(path, options={})
|
189
231
|
perform_request Net::HTTP::Options, path, options
|
190
232
|
end
|
@@ -260,4 +302,3 @@ require dir + 'httparty/exceptions'
|
|
260
302
|
require dir + 'httparty/parser'
|
261
303
|
require dir + 'httparty/request'
|
262
304
|
require dir + 'httparty/response'
|
263
|
-
|
data/lib/httparty/exceptions.rb
CHANGED
@@ -5,6 +5,22 @@ module HTTParty
|
|
5
5
|
# Exception raised when using a URI scheme other than HTTP or HTTPS
|
6
6
|
class UnsupportedURIScheme < StandardError; end
|
7
7
|
|
8
|
-
#
|
9
|
-
|
8
|
+
# @abstract Exceptions which inherit from ResponseError contain the Net::HTTP
|
9
|
+
# response object accessible via the {#response} method.
|
10
|
+
class ResponseError < StandardError
|
11
|
+
# Returns the response of the last request
|
12
|
+
# @return [Net::HTTPResponse] A subclass of Net::HTTPResponse, e.g.
|
13
|
+
# Net::HTTPOK
|
14
|
+
attr_reader :response
|
15
|
+
|
16
|
+
# Instantiate an instance of ResponseError with a Net::HTTPResponse object
|
17
|
+
# @param [Net::HTTPResponse]
|
18
|
+
def initialize(response)
|
19
|
+
@response = response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Exception that is raised when request has redirected too many times.
|
24
|
+
# Calling {#response} returns the Net:HTTP response object.
|
25
|
+
class RedirectionTooDeep < ResponseError; end
|
10
26
|
end
|
data/lib/httparty/parser.rb
CHANGED
@@ -58,6 +58,7 @@ module HTTParty
|
|
58
58
|
# @return [Symbol] e.g. :json
|
59
59
|
attr_reader :format
|
60
60
|
|
61
|
+
# Instantiate the parser and call {#parse}.
|
61
62
|
# @param [String] body the response body
|
62
63
|
# @param [Symbol] format the response format
|
63
64
|
# @return parsed response
|
@@ -133,8 +134,8 @@ module HTTParty
|
|
133
134
|
|
134
135
|
def parse_supported_format
|
135
136
|
send(format)
|
136
|
-
|
137
|
-
|
137
|
+
rescue NoMethodError
|
138
|
+
raise NotImplementedError, "#{self.class.name} has not implemented a parsing method for the #{format.inspect} format."
|
138
139
|
end
|
139
140
|
end
|
140
141
|
end
|
data/lib/httparty/request.rb
CHANGED
@@ -13,13 +13,13 @@ module HTTParty
|
|
13
13
|
|
14
14
|
SupportedURISchemes = [URI::HTTP, URI::HTTPS]
|
15
15
|
|
16
|
-
attr_accessor :http_method, :path, :options
|
16
|
+
attr_accessor :http_method, :path, :options, :last_response
|
17
17
|
|
18
18
|
def initialize(http_method, path, o={})
|
19
19
|
self.http_method = http_method
|
20
20
|
self.path = path
|
21
21
|
self.options = {
|
22
|
-
:limit => o.delete(:no_follow) ?
|
22
|
+
:limit => o.delete(:no_follow) ? 1 : 5,
|
23
23
|
:default_params => {},
|
24
24
|
:parser => Parser
|
25
25
|
}.merge(o)
|
@@ -56,7 +56,8 @@ module HTTParty
|
|
56
56
|
def perform
|
57
57
|
validate
|
58
58
|
setup_raw_request
|
59
|
-
|
59
|
+
get_response
|
60
|
+
handle_response
|
60
61
|
end
|
61
62
|
|
62
63
|
private
|
@@ -78,6 +79,10 @@ module HTTParty
|
|
78
79
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
79
80
|
end
|
80
81
|
|
82
|
+
if options[:debug_output]
|
83
|
+
http.set_debug_output(options[:debug_output])
|
84
|
+
end
|
85
|
+
|
81
86
|
http
|
82
87
|
end
|
83
88
|
|
@@ -109,9 +114,8 @@ module HTTParty
|
|
109
114
|
end
|
110
115
|
|
111
116
|
def get_response
|
112
|
-
|
113
|
-
options[:format] ||= format_from_mimetype(
|
114
|
-
response
|
117
|
+
self.last_response = perform_actual_request
|
118
|
+
options[:format] ||= format_from_mimetype(last_response['content-type'])
|
115
119
|
end
|
116
120
|
|
117
121
|
def query_string(uri)
|
@@ -121,7 +125,7 @@ module HTTParty
|
|
121
125
|
if options[:query].is_a?(Hash)
|
122
126
|
query_string_parts << options[:default_params].merge(options[:query]).to_params
|
123
127
|
else
|
124
|
-
query_string_parts << options[:default_params].to_params unless options[:default_params].
|
128
|
+
query_string_parts << options[:default_params].to_params unless options[:default_params].empty?
|
125
129
|
query_string_parts << options[:query] unless options[:query].nil?
|
126
130
|
end
|
127
131
|
|
@@ -129,18 +133,27 @@ module HTTParty
|
|
129
133
|
end
|
130
134
|
|
131
135
|
# Raises exception Net::XXX (http error code) if an http error occured
|
132
|
-
def handle_response
|
133
|
-
case
|
134
|
-
|
136
|
+
def handle_response
|
137
|
+
case last_response
|
138
|
+
when Net::HTTPMultipleChoice, # 300
|
139
|
+
Net::HTTPMovedPermanently, # 301
|
140
|
+
Net::HTTPFound, # 302
|
141
|
+
Net::HTTPSeeOther, # 303
|
142
|
+
Net::HTTPUseProxy, # 305
|
143
|
+
Net::HTTPTemporaryRedirect
|
144
|
+
if last_response.key?('location')
|
135
145
|
options[:limit] -= 1
|
136
|
-
self.path =
|
146
|
+
self.path = last_response['location']
|
137
147
|
@redirect = true
|
138
148
|
self.http_method = Net::HTTP::Get
|
139
|
-
capture_cookies(
|
149
|
+
capture_cookies(last_response)
|
140
150
|
perform
|
141
151
|
else
|
142
|
-
|
152
|
+
last_response
|
143
153
|
end
|
154
|
+
else
|
155
|
+
Response.new(parse_response(last_response.body), last_response.body, last_response.code, last_response.message, last_response.to_hash)
|
156
|
+
end
|
144
157
|
end
|
145
158
|
|
146
159
|
def parse_response(body)
|
@@ -166,7 +179,7 @@ module HTTParty
|
|
166
179
|
end
|
167
180
|
|
168
181
|
def validate
|
169
|
-
raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
|
182
|
+
raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
|
170
183
|
raise ArgumentError, 'only get, post, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
|
171
184
|
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
|
172
185
|
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
|
@@ -1,20 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
3
|
describe HTTParty::Request do
|
4
|
-
def stub_response(body, code = 200)
|
5
|
-
unless @http
|
6
|
-
@http = Net::HTTP.new('localhost', 80)
|
7
|
-
@request.stub!(:http).and_return(@http)
|
8
|
-
@request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
|
9
|
-
end
|
10
|
-
|
11
|
-
response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)
|
12
|
-
response.stub!(:body).and_return(body)
|
13
|
-
|
14
|
-
@http.stub!(:request).and_return(response)
|
15
|
-
response
|
16
|
-
end
|
17
|
-
|
18
4
|
before do
|
19
5
|
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
|
20
6
|
end
|
@@ -38,6 +24,23 @@ describe HTTParty::Request do
|
|
38
24
|
end
|
39
25
|
end
|
40
26
|
|
27
|
+
context "options" do
|
28
|
+
it "should use basic auth when configured" do
|
29
|
+
@request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'}
|
30
|
+
@request.send(:setup_raw_request)
|
31
|
+
@request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#uri" do
|
36
|
+
context "query strings" do
|
37
|
+
it "does not add an empty query string when default_params are blank" do
|
38
|
+
@request.options[:default_params] = {}
|
39
|
+
@request.uri.query.should be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
41
44
|
describe 'http' do
|
42
45
|
it "should use ssl for port 443" do
|
43
46
|
request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443')
|
@@ -111,12 +114,25 @@ describe HTTParty::Request do
|
|
111
114
|
http.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
|
112
115
|
end
|
113
116
|
end
|
114
|
-
end
|
115
117
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
context "debugging" do
|
119
|
+
before do
|
120
|
+
@http = Net::HTTP.new('google.com')
|
121
|
+
Net::HTTP.stub(:new => @http)
|
122
|
+
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
123
|
+
end
|
124
|
+
|
125
|
+
it "calls #set_debug_output when the option is provided" do
|
126
|
+
@request.options[:debug_output] = $stderr
|
127
|
+
@http.should_receive(:set_debug_output).with($stderr)
|
128
|
+
@request.send(:http)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "does not set_debug_output when the option is not provided" do
|
132
|
+
@http.should_not_receive(:set_debug_output)
|
133
|
+
@request.send(:http)
|
134
|
+
end
|
135
|
+
end
|
120
136
|
end
|
121
137
|
|
122
138
|
context "when setting timeout" do
|
@@ -213,6 +229,29 @@ describe HTTParty::Request do
|
|
213
229
|
end
|
214
230
|
|
215
231
|
describe 'with non-200 responses' do
|
232
|
+
context "3xx responses" do
|
233
|
+
it 'returns a valid object for 304 not modified' do
|
234
|
+
stub_response '', 304
|
235
|
+
resp = @request.perform
|
236
|
+
resp.code.should == 304
|
237
|
+
resp.body.should == ''
|
238
|
+
resp.should be_nil
|
239
|
+
end
|
240
|
+
|
241
|
+
it "redirects if a 300 contains a location header" do
|
242
|
+
redirect = stub_response '', 300
|
243
|
+
redirect['location'] = 'http://foo.com/foo'
|
244
|
+
ok = stub_response('<hash><foo>bar</foo></hash>', 200)
|
245
|
+
@http.stub!(:request).and_return(redirect, ok)
|
246
|
+
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
247
|
+
end
|
248
|
+
|
249
|
+
it "returns the Net::HTTP response if the 300 does not contain a location header" do
|
250
|
+
net_response = stub_response '', 300
|
251
|
+
@request.perform.should be_kind_of(Net::HTTPMultipleChoice)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
216
255
|
it 'should return a valid object for 4xx response' do
|
217
256
|
stub_response '<foo><bar>yes</bar></foo>', 401
|
218
257
|
resp = @request.perform
|
@@ -232,10 +271,12 @@ describe HTTParty::Request do
|
|
232
271
|
end
|
233
272
|
|
234
273
|
it "should not attempt to parse empty responses" do
|
235
|
-
|
274
|
+
[204, 304].each do |code|
|
275
|
+
stub_response "", code
|
236
276
|
|
237
|
-
|
238
|
-
|
277
|
+
@request.options[:format] = :xml
|
278
|
+
@request.perform.should be_nil
|
279
|
+
end
|
239
280
|
end
|
240
281
|
|
241
282
|
it "should not fail for missing mime type" do
|
@@ -324,12 +365,13 @@ describe HTTParty::Request do
|
|
324
365
|
end
|
325
366
|
end
|
326
367
|
end
|
327
|
-
end
|
328
368
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
369
|
+
context "with POST http method" do
|
370
|
+
it "should raise argument error if query is not a hash" do
|
371
|
+
lambda {
|
372
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform
|
373
|
+
}.should raise_error(ArgumentError)
|
374
|
+
end
|
334
375
|
end
|
335
376
|
end
|
377
|
+
|
data/spec/httparty_spec.rb
CHANGED
@@ -203,6 +203,18 @@ describe HTTParty do
|
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
|
+
describe "debug_output" do
|
207
|
+
it "stores the given stream as a default_option" do
|
208
|
+
@klass.debug_output $stdout
|
209
|
+
@klass.default_options[:debug_output].should == $stdout
|
210
|
+
end
|
211
|
+
|
212
|
+
it "stores the $stderr stream by default" do
|
213
|
+
@klass.debug_output
|
214
|
+
@klass.default_options[:debug_output].should == $stderr
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
206
218
|
describe "basic http authentication" do
|
207
219
|
it "should work" do
|
208
220
|
@klass.basic_auth 'foobar', 'secret'
|
@@ -292,42 +304,60 @@ describe HTTParty do
|
|
292
304
|
end
|
293
305
|
end
|
294
306
|
|
307
|
+
describe "#no_follow" do
|
308
|
+
it "sets no_follow to false by default" do
|
309
|
+
@klass.no_follow
|
310
|
+
@klass.default_options[:no_follow].should be_false
|
311
|
+
end
|
312
|
+
|
313
|
+
it "sets the no_follow option to true" do
|
314
|
+
@klass.no_follow true
|
315
|
+
@klass.default_options[:no_follow].should be_true
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
295
319
|
describe "with explicit override of automatic redirect handling" do
|
320
|
+
before do
|
321
|
+
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml, :no_follow => true)
|
322
|
+
@redirect = stub_response 'first redirect', 302
|
323
|
+
@redirect['location'] = 'http://foo.com/bar'
|
324
|
+
HTTParty::Request.stub(:new => @request)
|
325
|
+
end
|
296
326
|
|
297
327
|
it "should fail with redirected GET" do
|
298
328
|
lambda do
|
299
|
-
@klass.get('/foo', :no_follow => true)
|
300
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
329
|
+
@error = @klass.get('/foo', :no_follow => true)
|
330
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
301
331
|
end
|
302
332
|
|
303
333
|
it "should fail with redirected POST" do
|
304
334
|
lambda do
|
305
335
|
@klass.post('/foo', :no_follow => true)
|
306
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
336
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
307
337
|
end
|
308
338
|
|
309
339
|
it "should fail with redirected DELETE" do
|
310
340
|
lambda do
|
311
341
|
@klass.delete('/foo', :no_follow => true)
|
312
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
342
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
313
343
|
end
|
314
344
|
|
315
345
|
it "should fail with redirected PUT" do
|
316
346
|
lambda do
|
317
347
|
@klass.put('/foo', :no_follow => true)
|
318
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
348
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
319
349
|
end
|
320
350
|
|
321
351
|
it "should fail with redirected HEAD" do
|
322
352
|
lambda do
|
323
353
|
@klass.head('/foo', :no_follow => true)
|
324
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
354
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
325
355
|
end
|
326
356
|
|
327
357
|
it "should fail with redirected OPTIONS" do
|
328
358
|
lambda do
|
329
359
|
@klass.options('/foo', :no_follow => true)
|
330
|
-
end.should raise_error(HTTParty::RedirectionTooDeep)
|
360
|
+
end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
|
331
361
|
end
|
332
362
|
end
|
333
363
|
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'httparty')
|
2
|
-
gem 'rspec', '1.2.9'
|
3
|
-
gem 'fakeweb'
|
4
2
|
require 'spec/autorun'
|
5
3
|
require 'fakeweb'
|
6
4
|
|
@@ -10,15 +8,8 @@ def file_fixture(filename)
|
|
10
8
|
open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read
|
11
9
|
end
|
12
10
|
|
13
|
-
|
14
|
-
format = filename.split('.').last.intern
|
15
|
-
data = file_fixture(filename)
|
11
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format)
|
21
|
-
http_request.stub!(:perform_actual_request).and_return(response)
|
22
|
-
|
23
|
-
HTTParty::Request.should_receive(:new).and_return(http_request)
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
config.include HTTParty::StubResponse
|
24
15
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module HTTParty
|
2
|
+
module StubResponse
|
3
|
+
def stub_http_response_with(filename)
|
4
|
+
format = filename.split('.').last.intern
|
5
|
+
data = file_fixture(filename)
|
6
|
+
|
7
|
+
response = Net::HTTPOK.new("1.1", 200, "Content for you")
|
8
|
+
response.stub!(:body).and_return(data)
|
9
|
+
|
10
|
+
http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format)
|
11
|
+
http_request.stub!(:perform_actual_request).and_return(response)
|
12
|
+
|
13
|
+
HTTParty::Request.should_receive(:new).and_return(http_request)
|
14
|
+
end
|
15
|
+
|
16
|
+
def stub_response(body, code = 200)
|
17
|
+
unless @http
|
18
|
+
@http = Net::HTTP.new('localhost', 80)
|
19
|
+
@request.stub!(:http).and_return(@http)
|
20
|
+
@request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
|
21
|
+
end
|
22
|
+
|
23
|
+
response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)
|
24
|
+
response.stub!(:body).and_return(body)
|
25
|
+
|
26
|
+
@http.stub!(:request).and_return(response)
|
27
|
+
response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httparty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2010-01-30 00:00:00 -05:00
|
14
14
|
default_executable: httparty
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -19,9 +19,9 @@ dependencies:
|
|
19
19
|
version_requirement:
|
20
20
|
version_requirements: !ruby/object:Gem::Requirement
|
21
21
|
requirements:
|
22
|
-
- - "
|
22
|
+
- - "="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.1.
|
24
|
+
version: 0.1.5
|
25
25
|
version:
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: activesupport
|
@@ -119,7 +119,6 @@ files:
|
|
119
119
|
- lib/httparty/parser.rb
|
120
120
|
- lib/httparty/request.rb
|
121
121
|
- lib/httparty/response.rb
|
122
|
-
- lib/httparty/version.rb
|
123
122
|
- spec/fixtures/delicious.xml
|
124
123
|
- spec/fixtures/empty.xml
|
125
124
|
- spec/fixtures/google.html
|
@@ -133,6 +132,7 @@ files:
|
|
133
132
|
- spec/httparty_spec.rb
|
134
133
|
- spec/spec.opts
|
135
134
|
- spec/spec_helper.rb
|
135
|
+
- spec/support/stub_response.rb
|
136
136
|
- website/css/common.css
|
137
137
|
- website/index.html
|
138
138
|
has_rdoc: true
|
@@ -170,6 +170,7 @@ test_files:
|
|
170
170
|
- spec/httparty/response_spec.rb
|
171
171
|
- spec/httparty_spec.rb
|
172
172
|
- spec/spec_helper.rb
|
173
|
+
- spec/support/stub_response.rb
|
173
174
|
- examples/aaws.rb
|
174
175
|
- examples/basic.rb
|
175
176
|
- examples/custom_parsers.rb
|
data/lib/httparty/version.rb
DELETED