jnunemaker-httparty 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,5 +1,10 @@
1
+ == 0.1.5 2008-11-14
2
+ * 2 major enhancements
3
+ * Refactored send request method out into its own object.
4
+ * Added :html format if you just want to do that.
5
+
1
6
  == 0.1.4 2008-11-08
2
- * 2 major enhancements:
7
+ * 3 major enhancements:
3
8
  * Removed some cruft
4
9
  * Added ability to follow redirects automatically and turn that off (Alex Vollmer)
5
10
 
data/Manifest.txt CHANGED
@@ -13,13 +13,14 @@ examples/twitter.rb
13
13
  examples/whoismyrep.rb
14
14
  httparty.gemspec
15
15
  lib/httparty.rb
16
+ lib/httparty/request.rb
16
17
  lib/httparty/version.rb
17
18
  script/console
18
19
  script/destroy
19
20
  script/generate
20
21
  script/txt2html
21
22
  setup.rb
22
- spec/hash_spec.rb
23
+ spec/httparty/request_spec.rb
23
24
  spec/httparty_spec.rb
24
25
  spec/spec.opts
25
26
  spec/spec_helper.rb
data/examples/google.rb CHANGED
@@ -4,6 +4,7 @@ require 'pp'
4
4
 
5
5
  class Google
6
6
  include HTTParty
7
+ format :html
7
8
  end
8
9
 
9
10
  # google.com redirects to www.google.com so this is live test for redirection
data/httparty.gemspec CHANGED
@@ -1,28 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = %q{httparty}
3
- s.version = "0.1.4"
5
+ s.version = "0.1.5"
4
6
 
5
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
8
  s.authors = ["John Nunemaker"]
7
- s.date = %q{2008-11-08}
9
+ s.date = %q{2008-11-14}
8
10
  s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
9
11
  s.email = ["nunemaker@gmail.com"]
10
12
  s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt"]
11
- s.files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt", "Rakefile", "config/hoe.rb", "config/requirements.rb", "examples/aaws.rb", "examples/delicious.rb", "examples/google.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "httparty.gemspec", "lib/httparty.rb", "lib/httparty/version.rb", "script/console", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/hash_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake", "website/css/common.css", "website/index.html"]
13
+ s.files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt", "Rakefile", "config/hoe.rb", "config/requirements.rb", "examples/aaws.rb", "examples/delicious.rb", "examples/google.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "httparty.gemspec", "lib/httparty.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "script/console", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake", "website/css/common.css", "website/index.html"]
12
14
  s.has_rdoc = true
13
15
  s.homepage = %q{http://httparty.rubyforge.org}
14
16
  s.post_install_message = %q{When you HTTParty, you must party hard!}
15
17
  s.rdoc_options = ["--main", "README.txt"]
16
18
  s.require_paths = ["lib"]
17
19
  s.rubyforge_project = %q{httparty}
18
- s.rubygems_version = %q{1.2.0}
20
+ s.rubygems_version = %q{1.3.1}
19
21
  s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
20
22
 
21
23
  if s.respond_to? :specification_version then
22
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
25
  s.specification_version = 2
24
26
 
25
- if current_version >= 3 then
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
28
  s.add_runtime_dependency(%q<activesupport>, [">= 2.1"])
27
29
  s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
28
30
  else
data/lib/httparty.rb CHANGED
@@ -8,162 +8,88 @@ require 'active_support'
8
8
  directory = File.dirname(__FILE__)
9
9
  $:.unshift(directory) unless $:.include?(directory) || $:.include?(File.expand_path(directory))
10
10
 
11
+ require 'httparty/request'
12
+
11
13
  module HTTParty
12
14
  class UnsupportedFormat < StandardError; end
13
15
  class RedirectionTooDeep < StandardError; end
16
+
17
+ AllowedFormats = {:xml => 'text/xml', :json => 'application/json', :html => 'text/html'}
14
18
 
15
19
  def self.included(base)
16
20
  base.extend ClassMethods
17
21
  end
18
22
 
19
- AllowedFormats = {:xml => 'text/xml', :json => 'application/json'}
20
-
21
- module ClassMethods
23
+ module ClassMethods
24
+ def default_options
25
+ @@default_options ||= {}
26
+ end
27
+
22
28
  #
23
29
  # Set an http proxy
24
30
  #
25
31
  # class Twitter
26
32
  # include HTTParty
27
- # http_proxy http://myProxy, 1080
33
+ # http_proxy 'http://myProxy', 1080
28
34
  # ....
29
35
  def http_proxy(addr=nil, port = nil)
30
- @http_proxyaddr = addr
31
- @http_proxyport = port
36
+ default_options[:http_proxyaddr] = addr
37
+ default_options[:http_proxyport] = port
32
38
  end
33
39
 
34
- def base_uri(base_uri=nil)
35
- return @base_uri unless base_uri
36
- @base_uri = normalize_base_uri(base_uri)
40
+ def base_uri(uri=nil)
41
+ return default_options[:base_uri] unless uri
42
+ default_options[:base_uri] = normalize_base_uri(uri)
37
43
  end
38
-
39
- # Warning: This is not thread safe most likely and
40
- # only works if you use one set of credentials. I
41
- # leave it because it is convenient on some occasions.
44
+
42
45
  def basic_auth(u, p)
43
- @auth = {:username => u, :password => p}
46
+ default_options[:basic_auth] = {:username => u, :password => p}
44
47
  end
45
48
 
46
- # Updates the default query string parameters
47
- # that should be appended to each request.
48
49
  def default_params(h={})
49
50
  raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash)
50
- @default_params ||= {}
51
- return @default_params if h.blank?
52
- @default_params.merge!(h)
51
+ default_options[:default_params] ||= {}
52
+ default_options[:default_params].merge!(h)
53
53
  end
54
54
 
55
55
  def headers(h={})
56
56
  raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash)
57
- @headers ||= {}
58
- return @headers if h.blank?
59
- @headers.merge!(h)
57
+ default_options[:headers] ||= {}
58
+ default_options[:headers].merge!(h)
60
59
  end
61
60
 
62
61
  def format(f)
63
62
  raise UnsupportedFormat, "Must be one of: #{AllowedFormats.keys.join(', ')}" unless AllowedFormats.key?(f)
64
- @format = f
63
+ default_options[:format] = f
65
64
  end
66
65
 
67
- # TODO: spec out this
68
66
  def get(path, options={})
69
- send_request 'get', path, options
67
+ perform_request Net::HTTP::Get, path, options
70
68
  end
71
69
 
72
- # TODO: spec out this
73
70
  def post(path, options={})
74
- send_request 'post', path, options
71
+ perform_request Net::HTTP::Post, path, options
75
72
  end
76
73
 
77
- # TODO: spec out this
78
74
  def put(path, options={})
79
- send_request 'put', path, options
75
+ perform_request Net::HTTP::Put, path, options
80
76
  end
81
77
 
82
- # TODO: spec out this
83
78
  def delete(path, options={})
84
- send_request 'delete', path, options
79
+ perform_request Net::HTTP::Delete, path, options
85
80
  end
86
-
87
- private
88
- def http(uri) #:nodoc:
89
- http = Net::HTTP.new(uri.host, uri.port, @http_proxyaddr, @http_proxyport)
90
- http.use_ssl = (uri.port == 443)
91
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
92
- http
93
- end
94
-
95
- # FIXME: this method is doing way to much and needs to be split up
96
- # options can be any or all of:
97
- # query => hash of keys/values or a query string (foo=bar&baz=poo)
98
- # body => hash of keys/values or a query string (foo=bar&baz=poo)
99
- # headers => hash of headers to send request with
100
- # basic_auth => :username and :password to use as basic http authentication (overrides @auth class instance variable)
101
- # Raises exception Net::XXX (http error code) if an http error occured
102
- def send_request(method, path, options={}) #:nodoc:
103
- options = {:limit => 5}.merge(options)
104
- options[:limit] = 0 if options.delete(:no_follow)
105
-
106
- raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
107
- raise ArgumentError, 'only get, post, put and delete methods are supported' unless %w[get post put delete].include?(method.to_s)
108
- raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
109
- raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
110
-
111
- path = URI.parse(path)
112
- uri = path.relative? ? URI.parse("#{base_uri}#{path}") : path
113
- existing_query = uri.query ? "#{uri.query}&" : ''
114
- uri.query = if options[:query].blank?
115
- existing_query + default_params.to_query
116
- else
117
- existing_query + (options[:query].is_a?(Hash) ? default_params.merge(options[:query]).to_query : options[:query])
118
- end
119
-
120
- klass = Net::HTTP.const_get method.to_s.downcase.capitalize
121
- request = klass.new(uri.request_uri)
122
- request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
123
- basic_auth = options.delete(:basic_auth) || @auth
124
- request.initialize_http_header headers.merge(options[:headers] || {})
125
- request.basic_auth(basic_auth[:username], basic_auth[:password]) if basic_auth
126
- response = http(uri).request(request)
127
- @format ||= format_from_mimetype(response['content-type'])
128
-
129
- case response
130
- when Net::HTTPSuccess
131
- parse_response(response.body)
132
- when Net::HTTPRedirection
133
- options[:limit] -= 1
134
- send_request(method, response['location'], options)
135
- else
136
- response.instance_eval { class << self; attr_accessor :body_parsed; end }
137
- begin; response.body_parsed = parse_response(response.body); rescue; end
138
- response.error! # raises exception corresponding to http error Net::XXX
139
- end
140
81
 
141
- end
142
-
143
- def parse_response(body) #:nodoc:
144
- return nil if body.nil? or body.empty?
145
- case @format
146
- when :xml
147
- Hash.from_xml(body)
148
- when :json
149
- ActiveSupport::JSON.decode(body)
150
- else
151
- body
152
- end
82
+ private
83
+ def perform_request(http_method, path, options) #:nodoc:
84
+ Request.new(http_method, path, default_options.merge(options)).perform
153
85
  end
154
86
 
155
- # Makes it so uri is sure to parse stuff like google.com with the http
87
+ # Makes it so uri is sure to parse stuff like google.com without the http
156
88
  def normalize_base_uri(url) #:nodoc:
157
89
  use_ssl = (url =~ /^https/) || url.include?(':443')
158
90
  url.chop! if url.ends_with?('/')
159
91
  url.gsub!(/^https?:\/\//i, '')
160
92
  "http#{'s' if use_ssl}://#{url}"
161
93
  end
162
-
163
- # Uses the HTTP Content-Type header to determine the format of the response
164
- # It compares the MIME type returned to the types stored in the AllowedFormats hash
165
- def format_from_mimetype(mimetype) #:nodoc:
166
- AllowedFormats.each { |k, v| return k if mimetype.include?(v) }
167
- end
168
94
  end
169
- end
95
+ end
@@ -0,0 +1,104 @@
1
+ module HTTParty
2
+ class Request
3
+ SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
4
+
5
+ attr_accessor :http_method, :path, :options
6
+
7
+ def initialize(http_method, path, options={})
8
+ self.http_method = http_method
9
+ self.path = path
10
+ self.options = {
11
+ :limit => options.delete(:no_follow) ? 0 : 5,
12
+ :default_params => {},
13
+ }.merge(options.dup)
14
+ end
15
+
16
+ def path=(uri)
17
+ @path = URI.parse(uri)
18
+ end
19
+
20
+ def uri
21
+ uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
22
+ uri.query = query_string(uri)
23
+ uri
24
+ end
25
+
26
+ def perform
27
+ validate!
28
+ handle_response!(get_response(uri))
29
+ end
30
+
31
+ private
32
+ def http(uri) #:nodoc:
33
+ http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
34
+ http.use_ssl = (uri.port == 443)
35
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
36
+ http
37
+ end
38
+
39
+ def get_response(uri) #:nodoc:
40
+ request = http_method.new(uri.request_uri)
41
+ request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
42
+ request.initialize_http_header options[:headers]
43
+ request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) if options[:basic_auth]
44
+ response = http(uri).request(request)
45
+ options[:format] ||= format_from_mimetype(response['content-type'])
46
+ response
47
+ end
48
+
49
+ def query_string(uri) #:nodoc:
50
+ query_string_parts = []
51
+ query_string_parts << uri.query unless uri.query.blank?
52
+
53
+ if options[:query].is_a?(Hash)
54
+ query_string_parts << options[:default_params].merge(options[:query]).to_query
55
+ else
56
+ query_string_parts << options[:default_params].to_query unless options[:default_params].blank?
57
+ query_string_parts << options[:query] unless options[:query].blank?
58
+ end
59
+
60
+ query_string_parts.size > 0 ? query_string_parts.join('&') : nil
61
+ end
62
+
63
+ # Raises exception Net::XXX (http error code) if an http error occured
64
+ def handle_response!(response) #:nodoc:
65
+ case response
66
+ when Net::HTTPSuccess
67
+ parse_response(response.body)
68
+ when Net::HTTPRedirection
69
+ options[:limit] -= 1
70
+ self.path = response['location']
71
+ perform
72
+ else
73
+ response.instance_eval { class << self; attr_accessor :body_parsed; end }
74
+ begin; response.body_parsed = parse_response(response.body); rescue; end
75
+ response.error! # raises exception corresponding to http error Net::XXX
76
+ end
77
+ end
78
+
79
+ def parse_response(body) #:nodoc:
80
+ return nil if body.nil? or body.empty?
81
+ case options[:format]
82
+ when :xml
83
+ Hash.from_xml(body)
84
+ when :json
85
+ ActiveSupport::JSON.decode(body)
86
+ else
87
+ body
88
+ end
89
+ end
90
+
91
+ # Uses the HTTP Content-Type header to determine the format of the response
92
+ # It compares the MIME type returned to the types stored in the AllowedFormats hash
93
+ def format_from_mimetype(mimetype) #:nodoc:
94
+ AllowedFormats.each { |k, v| return k if mimetype.include?(v) }
95
+ end
96
+
97
+ def validate! #:nodoc:
98
+ raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
99
+ raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
100
+ raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
101
+ raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
102
+ end
103
+ end
104
+ end
@@ -2,7 +2,7 @@ module HTTParty
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -0,0 +1,107 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe HTTParty::Request do
4
+ before do
5
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
6
+ end
7
+
8
+ describe 'http' do
9
+ it "should use ssl for port 443" do
10
+ @request.send(:http, URI.parse('https://api.foo.com/v1:443')).use_ssl?.should == true
11
+ end
12
+
13
+ it 'should not use ssl for port 80' do
14
+ @request.send(:http, URI.parse('http://foobar.com')).use_ssl?.should == false
15
+ end
16
+ end
17
+
18
+ describe 'parsing responses' do
19
+ it 'should handle xml automatically' do
20
+ xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
21
+ @request.options[:format] = :xml
22
+ @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
23
+ end
24
+
25
+ it 'should handle json automatically' do
26
+ json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
27
+ @request.options[:format] = :json
28
+ @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
29
+ end
30
+ end
31
+
32
+ it "should not attempt to parse empty responses" do
33
+ http = Net::HTTP.new('localhost', 80)
34
+ @request.stub!(:http).and_return(http)
35
+ response = Net::HTTPNoContent.new("1.1", 204, "No content for you")
36
+ response.stub!(:body).and_return(nil)
37
+ http.stub!(:request).and_return(response)
38
+
39
+ @request.options[:format] = :xml
40
+ @request.perform.should be_nil
41
+
42
+ response.stub!(:body).and_return("")
43
+ @request.perform.should be_nil
44
+ end
45
+
46
+ describe "that respond with redirects" do
47
+ def setup_redirect
48
+ @http = Net::HTTP.new('localhost', 80)
49
+ @request.stub!(:http).and_return(@http)
50
+ @request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
51
+ @redirect = Net::HTTPFound.new("1.1", 302, "")
52
+ @redirect['location'] = '/foo'
53
+ end
54
+
55
+ def setup_ok_response
56
+ @ok = Net::HTTPOK.new("1.1", 200, "Content for you")
57
+ @ok.stub!(:body).and_return({"foo" => "bar"}.to_xml)
58
+ @http.should_receive(:request).and_return(@redirect, @ok)
59
+ @request.options[:format] = :xml
60
+ end
61
+
62
+ def setup_redirect_response
63
+ @http.stub!(:request).and_return(@redirect)
64
+ end
65
+
66
+ def setup_successful_redirect
67
+ setup_redirect
68
+ setup_ok_response
69
+ end
70
+
71
+ def setup_infinite_redirect
72
+ setup_redirect
73
+ setup_redirect_response
74
+ end
75
+
76
+ it "should handle redirects for GET transparently" do
77
+ setup_successful_redirect
78
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
79
+ end
80
+
81
+ it "should handle redirects for POST transparently" do
82
+ setup_successful_redirect
83
+ @request.http_method = Net::HTTP::Post
84
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
85
+ end
86
+
87
+ it "should handle redirects for DELETE transparently" do
88
+ setup_successful_redirect
89
+ @request.http_method = Net::HTTP::Delete
90
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
91
+ end
92
+
93
+ it "should handle redirects for PUT transparently" do
94
+ setup_successful_redirect
95
+ @request.http_method = Net::HTTP::Put
96
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
97
+ end
98
+
99
+ it "should prevent infinite loops" do
100
+ setup_infinite_redirect
101
+
102
+ lambda do
103
+ @request.perform
104
+ end.should raise_error(HTTParty::RedirectionTooDeep)
105
+ end
106
+ end
107
+ end
@@ -13,6 +13,10 @@ end
13
13
  describe HTTParty do
14
14
 
15
15
  describe "base uri" do
16
+ before do
17
+ Foo.base_uri('api.foo.com/v1')
18
+ end
19
+
16
20
  it "should have reader" do
17
21
  Foo.base_uri.should == 'http://api.foo.com/v1'
18
22
  end
@@ -65,19 +69,19 @@ describe HTTParty do
65
69
  describe "basic http authentication" do
66
70
  it "should work" do
67
71
  Foo.basic_auth 'foobar', 'secret'
68
- Foo.instance_variable_get("@auth").should == {:username => 'foobar', :password => 'secret'}
72
+ Foo.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'}
69
73
  end
70
74
  end
71
75
 
72
76
  describe "format" do
73
77
  it "should allow xml" do
74
78
  Foo.format :xml
75
- Foo.instance_variable_get("@format").should == :xml
79
+ Foo.default_options[:format].should == :xml
76
80
  end
77
81
 
78
82
  it "should allow json" do
79
83
  Foo.format :json
80
- Foo.instance_variable_get("@format").should == :json
84
+ Foo.default_options[:format].should == :json
81
85
  end
82
86
 
83
87
  it 'should not allow funky format' do
@@ -86,136 +90,31 @@ describe HTTParty do
86
90
  end.should raise_error(HTTParty::UnsupportedFormat)
87
91
  end
88
92
  end
89
-
90
- describe 'http' do
91
- it "should use ssl for port 443" do
92
- FooWithHttps.send(:http, URI.parse('https://api.foo.com/v1:443')).use_ssl?.should == true
93
- end
94
-
95
- it 'should not use ssl for port 80' do
96
- Foo.send(:http, URI.parse('http://foobar.com')).use_ssl?.should == false
97
- end
98
- end
99
-
100
- describe 'parsing responses' do
101
- it 'should handle xml automatically' do
102
- xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
103
- Foo.format :xml
104
- Foo.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
105
- end
106
-
107
- it 'should handle json automatically' do
108
- json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
109
- Foo.format :json
110
- Foo.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
111
- end
112
- end
113
-
114
- describe "sending requests" do
115
- it "should not work with request method other than get, post, put, delete" do
116
- lambda do
117
- Foo.send(:send_request, 'foo', '/foo')
118
- end.should raise_error(ArgumentError)
119
- end
120
-
121
- it 'should require that :headers is a hash if present' do
93
+
94
+ describe "with explicit override of automatic redirect handling" do
95
+
96
+ it "should fail with redirected GET" do
122
97
  lambda do
123
- Foo.send(:send_request, 'get', '/foo', :headers => 'string')
124
- end.should raise_error(ArgumentError)
98
+ Foo.get('/foo', :no_follow => true)
99
+ end.should raise_error(HTTParty::RedirectionTooDeep)
125
100
  end
126
-
127
- it 'should require that :basic_auth is a hash if present' do
101
+
102
+ it "should fail with redirected POST" do
128
103
  lambda do
129
- Foo.send(:send_request, 'get', '/foo', :basic_auth => 'string')
130
- end.should raise_error(ArgumentError)
104
+ Foo.post('/foo', :no_follow => true)
105
+ end.should raise_error(HTTParty::RedirectionTooDeep)
131
106
  end
132
107
 
133
- it "should not attempt to parse empty responses" do
134
- http = Net::HTTP.new('localhost', 80)
135
- Foo.stub!(:http).and_return(http)
136
- response = Net::HTTPNoContent.new("1.1", 204, "No content for you")
137
- response.stub!(:body).and_return(nil)
138
- http.stub!(:request).and_return(response)
139
-
140
- Foo.headers.clear # clear out bogus settings from other specs
141
- Foo.format :xml
142
- Foo.send(:send_request, 'get', '/bar').should be_nil
143
-
144
- response.stub!(:body).and_return("")
145
- Foo.send(:send_request, 'get', 'bar').should be_nil
108
+ it "should fail with redirected DELETE" do
109
+ lambda do
110
+ Foo.delete('/foo', :no_follow => true)
111
+ end.should raise_error(HTTParty::RedirectionTooDeep)
146
112
  end
147
113
 
148
- describe "that respond with redirects" do
149
- def setup_http
150
- @http = Net::HTTP.new('localhost', 80)
151
- Foo.stub!(:http).and_return(@http)
152
- @redirect = Net::HTTPFound.new("1.1", 302, "")
153
- @redirect.stub!(:[]).with('location').and_return('/foo')
154
- @ok = Net::HTTPOK.new("1.1", 200, "Content for you")
155
- @ok.stub!(:body).and_return({"foo" => "bar"}.to_xml)
156
- @http.should_receive(:request).and_return(@redirect, @ok)
157
- Foo.headers.clear
158
- Foo.format :xml
159
- end
160
-
161
- it "should handle redirects for GET transparently" do
162
- setup_http
163
- Foo.get('/foo/').should == {"hash" => {"foo" => "bar"}}
164
- end
165
-
166
- it "should handle redirects for POST transparently" do
167
- setup_http
168
- Foo.post('/foo/', {:foo => :bar}).should == {"hash" => {"foo" => "bar"}}
169
- end
170
-
171
- it "should handle redirects for DELETE transparently" do
172
- setup_http
173
- Foo.delete('/foo/').should == {"hash" => {"foo" => "bar"}}
174
- end
175
-
176
- it "should handle redirects for PUT transparently" do
177
- setup_http
178
- Foo.put('/foo/').should == {"hash" => {"foo" => "bar"}}
179
- end
180
-
181
- it "should prevent infinite loops" do
182
- http = Net::HTTP.new('localhost', 80)
183
- Foo.stub!(:http).and_return(http)
184
- redirect = Net::HTTPFound.new("1.1", "302", "Look, over there!")
185
- redirect.stub!(:[]).with('location').and_return('/foo')
186
- http.stub!(:request).and_return(redirect)
187
-
188
- lambda do
189
- Foo.send(:send_request, 'get', '/foo')
190
- end.should raise_error(HTTParty::RedirectionTooDeep)
191
- end
192
-
193
- describe "with explicit override of automatic redirect handling" do
194
-
195
- it "should fail with redirected GET" do
196
- lambda do
197
- Foo.get('/foo', :no_follow => true)
198
- end.should raise_error(HTTParty::RedirectionTooDeep)
199
- end
200
-
201
- it "should fail with redirected POST" do
202
- lambda do
203
- Foo.post('/foo', :no_follow => true)
204
- end.should raise_error(HTTParty::RedirectionTooDeep)
205
- end
206
-
207
- it "should fail with redirected DELETE" do
208
- lambda do
209
- Foo.delete('/foo', :no_follow => true)
210
- end
211
- end
212
-
213
- it "should fail with redirected PUT" do
214
- lambda do
215
- Foo.put('/foo', :no_follow => true)
216
- end
217
- end
218
- end
114
+ it "should fail with redirected PUT" do
115
+ lambda do
116
+ Foo.put('/foo', :no_follow => true)
117
+ end.should raise_error(HTTParty::RedirectionTooDeep)
219
118
  end
220
119
  end
221
- end
120
+ end
data/spec/spec.opts CHANGED
@@ -1 +1,3 @@
1
- --colour
1
+ --format
2
+ progress
3
+ --colour
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jnunemaker-httparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-08 00:00:00 -08:00
12
+ date: 2008-11-14 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -59,13 +59,14 @@ files:
59
59
  - examples/whoismyrep.rb
60
60
  - httparty.gemspec
61
61
  - lib/httparty.rb
62
+ - lib/httparty/request.rb
62
63
  - lib/httparty/version.rb
63
64
  - script/console
64
65
  - script/destroy
65
66
  - script/generate
66
67
  - script/txt2html
67
68
  - setup.rb
68
- - spec/hash_spec.rb
69
+ - spec/httparty/request_spec.rb
69
70
  - spec/httparty_spec.rb
70
71
  - spec/spec.opts
71
72
  - spec/spec_helper.rb