jnunemaker-httparty 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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