httparty 0.1.3 → 0.1.5

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.

@@ -1,3 +1,13 @@
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
+
6
+ == 0.1.4 2008-11-08
7
+ * 3 major enhancements:
8
+ * Removed some cruft
9
+ * Added ability to follow redirects automatically and turn that off (Alex Vollmer)
10
+
1
11
  == 0.1.3 2008-08-22
2
12
 
3
13
  * 3 major enhancements:
@@ -8,19 +8,19 @@ config/hoe.rb
8
8
  config/requirements.rb
9
9
  examples/aaws.rb
10
10
  examples/delicious.rb
11
+ examples/google.rb
11
12
  examples/twitter.rb
12
13
  examples/whoismyrep.rb
13
14
  httparty.gemspec
14
15
  lib/httparty.rb
15
- lib/httparty/core_ext.rb
16
- lib/httparty/core_ext/hash.rb
16
+ lib/httparty/request.rb
17
17
  lib/httparty/version.rb
18
18
  script/console
19
19
  script/destroy
20
20
  script/generate
21
21
  script/txt2html
22
22
  setup.rb
23
- spec/hash_spec.rb
23
+ spec/httparty/request_spec.rb
24
24
  spec/httparty_spec.rb
25
25
  spec/spec.opts
26
26
  spec/spec_helper.rb
data/README.txt CHANGED
@@ -43,6 +43,20 @@ That works and all but what if you don't want to embed your username and passwor
43
43
 
44
44
  Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")
45
45
 
46
+ === REQUEST OPTIONS
47
+
48
+ Each of the HTTP method (get, post, put and delete) each take a hash of options.
49
+ The following keys can be specified in the options:
50
+
51
+ headers:: A <tt>Hash</tt> of header key/value pairs
52
+ query:: A <tt>Hash</tt> of query key/value pairs
53
+ body:: The body of the request. If it's a <tt>Hash</tt>, it is
54
+ converted into query-string format, otherwise it is sent
55
+ as-is.
56
+ basic_auth:: A <tt>Hash</tt> containing keys for <tt>:username</tt> and
57
+ <tt>:password</tt>.
58
+ no_follow:: Turns off automatic redirect following
59
+
46
60
  == REQUIREMENTS:
47
61
 
48
62
  * Active Support >= 2.1
data/Rakefile CHANGED
@@ -1,4 +1,11 @@
1
1
  require 'config/requirements'
2
2
  require 'config/hoe' # setup Hoe + all gem configuration
3
+ require "spec/rake/spectask"
3
4
 
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
5
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
6
+
7
+ task :default => :spec
8
+
9
+ Spec::Rake::SpecTask.new do |t|
10
+ t.spec_files = FileList["spec/**/*_spec.rb"]
11
+ end
@@ -0,0 +1,16 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Google
6
+ include HTTParty
7
+ format :html
8
+ end
9
+
10
+ # google.com redirects to www.google.com so this is live test for redirection
11
+ pp Google.get('http://google.com')
12
+
13
+ puts '', '*'*70, ''
14
+
15
+ # check that ssl is requesting right
16
+ pp Google.get('https://www.google.com')
@@ -1,33 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = %q{httparty}
3
- s.version = "0.1.3"
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-08-22}
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/twitter.rb", "examples/whoismyrep.rb", "httparty.gemspec", "lib/httparty.rb", "lib/httparty/core_ext.rb", "lib/httparty/core_ext/hash.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"])
29
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
27
30
  else
28
31
  s.add_dependency(%q<activesupport>, [">= 2.1"])
32
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
29
33
  end
30
34
  else
31
35
  s.add_dependency(%q<activesupport>, [">= 2.1"])
36
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
32
37
  end
33
38
  end
@@ -5,160 +5,91 @@ require 'ostruct'
5
5
  require 'rubygems'
6
6
  require 'active_support'
7
7
 
8
- $:.unshift(File.dirname(__FILE__)) unless
9
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
8
+ directory = File.dirname(__FILE__)
9
+ $:.unshift(directory) unless $:.include?(directory) || $:.include?(File.expand_path(directory))
10
+
11
+ require 'httparty/request'
10
12
 
11
- dir = File.expand_path(File.join(File.dirname(__FILE__), 'httparty'))
12
- require dir + '/core_ext'
13
-
14
13
  module HTTParty
15
14
  class UnsupportedFormat < StandardError; end
15
+ class RedirectionTooDeep < StandardError; end
16
+
17
+ AllowedFormats = {:xml => 'text/xml', :json => 'application/json', :html => 'text/html'}
16
18
 
17
19
  def self.included(base)
18
20
  base.extend ClassMethods
19
21
  end
20
22
 
21
- AllowedFormats = {:xml => 'text/xml', :json => 'application/json'}
22
-
23
- module ClassMethods
23
+ module ClassMethods
24
+ def default_options
25
+ @@default_options ||= {}
26
+ end
27
+
24
28
  #
25
29
  # Set an http proxy
26
30
  #
27
31
  # class Twitter
28
32
  # include HTTParty
29
- # http_proxy http://myProxy, 1080
33
+ # http_proxy 'http://myProxy', 1080
30
34
  # ....
31
35
  def http_proxy(addr=nil, port = nil)
32
- @http_proxyaddr = addr
33
- @http_proxyport = port
36
+ default_options[:http_proxyaddr] = addr
37
+ default_options[:http_proxyport] = port
34
38
  end
35
39
 
36
- def base_uri(base_uri=nil)
37
- return @base_uri unless base_uri
38
- # don't want this to ever end with /
39
- base_uri = base_uri.ends_with?('/') ? base_uri.chop : base_uri
40
- @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)
41
43
  end
42
-
43
- # Warning: This is not thread safe most likely and
44
- # only works if you use one set of credentials. I
45
- # leave it because it is convenient on some occasions.
44
+
46
45
  def basic_auth(u, p)
47
- @auth = {:username => u, :password => p}
46
+ default_options[:basic_auth] = {:username => u, :password => p}
48
47
  end
49
48
 
50
- # Updates the default query string parameters
51
- # that should be appended to each request.
52
49
  def default_params(h={})
53
50
  raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash)
54
- @default_params ||= {}
55
- return @default_params if h.blank?
56
- @default_params.merge!(h)
51
+ default_options[:default_params] ||= {}
52
+ default_options[:default_params].merge!(h)
57
53
  end
58
54
 
59
55
  def headers(h={})
60
56
  raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash)
61
- @headers ||= {}
62
- return @headers if h.blank?
63
- @headers.merge!(h)
57
+ default_options[:headers] ||= {}
58
+ default_options[:headers].merge!(h)
64
59
  end
65
60
 
66
61
  def format(f)
67
62
  raise UnsupportedFormat, "Must be one of: #{AllowedFormats.keys.join(', ')}" unless AllowedFormats.key?(f)
68
- @format = f
63
+ default_options[:format] = f
69
64
  end
70
65
 
71
- # TODO: spec out this
72
66
  def get(path, options={})
73
- send_request 'get', path, options
67
+ perform_request Net::HTTP::Get, path, options
74
68
  end
75
69
 
76
- # TODO: spec out this
77
70
  def post(path, options={})
78
- send_request 'post', path, options
71
+ perform_request Net::HTTP::Post, path, options
79
72
  end
80
73
 
81
- # TODO: spec out this
82
74
  def put(path, options={})
83
- send_request 'put', path, options
75
+ perform_request Net::HTTP::Put, path, options
84
76
  end
85
77
 
86
- # TODO: spec out this
87
78
  def delete(path, options={})
88
- send_request 'delete', path, options
79
+ perform_request Net::HTTP::Delete, path, options
89
80
  end
90
-
91
- private
92
- def http(uri) #:nodoc:
93
- if @http.blank?
94
- @http = Net::HTTP.new(uri.host, uri.port, @http_proxyaddr, @http_proxyport)
95
- @http.use_ssl = (uri.port == 443)
96
- # so we can avoid ssl warnings
97
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
98
- end
99
- @http
100
- end
101
-
102
- # FIXME: this method is doing way to much and needs to be split up
103
- # options can be any or all of:
104
- # query => hash of keys/values or a query string (foo=bar&baz=poo)
105
- # body => hash of keys/values or a query string (foo=bar&baz=poo)
106
- # headers => hash of headers to send request with
107
- # basic_auth => :username and :password to use as basic http authentication (overrides @auth class instance variable)
108
- # Raises exception Net::XXX (http error code) if an http error occured
109
- def send_request(method, path, options={}) #:nodoc:
110
- raise ArgumentError, 'only get, post, put and delete methods are supported' unless %w[get post put delete].include?(method.to_s)
111
- raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
112
- raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
113
- uri = URI.parse("#{base_uri}#{path}")
114
- existing_query = uri.query ? "#{uri.query}&" : ''
115
- uri.query = if options[:query].blank?
116
- existing_query + default_params.to_query
117
- else
118
- existing_query + (options[:query].is_a?(Hash) ? default_params.merge(options[:query]).to_query : options[:query])
119
- end
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
- # note to self: self, do not put basic auth above headers because it removes basic auth
126
- request.basic_auth(basic_auth[:username], basic_auth[:password]) if basic_auth
127
- response = http(uri).request(request)
128
- @format ||= format_from_mimetype(response['content-type'])
129
-
130
- case response
131
- when Net::HTTPSuccess
132
- parse_response(response.body)
133
- else
134
- response.instance_eval { class << self; attr_accessor :body_parsed; end }
135
- begin; response.body_parsed = parse_response(response.body); rescue; end
136
- response.error! # raises exception corresponding to http error Net::XXX
137
- end
138
81
 
139
- end
140
-
141
- def parse_response(body) #:nodoc:
142
- case @format
143
- when :xml
144
- Hash.from_xml(body)
145
- when :json
146
- ActiveSupport::JSON.decode(body)
147
- else
148
- # just return the response if no format
149
- body
150
- end
82
+ private
83
+ def perform_request(http_method, path, options) #:nodoc:
84
+ Request.new(http_method, path, default_options.merge(options)).perform
151
85
  end
152
86
 
153
- # Makes it so uri is sure to parse stuff like google.com with the http
154
- def normalize_base_uri(str) #:nodoc:
155
- str =~ /^https?:\/\// ? str : "http#{'s' if str.include?(':443')}://#{str}"
156
- end
157
-
158
- # Uses the HTTP Content-Type header to determine the format of the response
159
- # It compares the MIME type returned to the types stored in the AllowedFormats hash
160
- def format_from_mimetype(mimetype) #:nodoc:
161
- AllowedFormats.each { |k, v| return k if mimetype.include?(v) }
87
+ # Makes it so uri is sure to parse stuff like google.com without the http
88
+ def normalize_base_uri(url) #:nodoc:
89
+ use_ssl = (url =~ /^https/) || url.include?(':443')
90
+ url.chop! if url.ends_with?('/')
91
+ url.gsub!(/^https?:\/\//i, '')
92
+ "http#{'s' if use_ssl}://#{url}"
162
93
  end
163
94
  end
164
- 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 = 3
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,11 +13,15 @@ end
13
13
  describe HTTParty do
14
14
 
15
15
  describe "base uri" do
16
- it "should be gettable" do
16
+ before do
17
+ Foo.base_uri('api.foo.com/v1')
18
+ end
19
+
20
+ it "should have reader" do
17
21
  Foo.base_uri.should == 'http://api.foo.com/v1'
18
22
  end
19
23
 
20
- it 'should be setable' do
24
+ it 'should have writer' do
21
25
  Foo.base_uri('http://api.foobar.com')
22
26
  Foo.base_uri.should == 'http://api.foobar.com'
23
27
  end
@@ -28,7 +32,13 @@ describe HTTParty do
28
32
  end
29
33
 
30
34
  it "should add https if not present for ssl requests" do
31
- FooWithHttps.base_uri.should == 'https://api.foo.com/v1:443'
35
+ Foo.base_uri('api.foo.com/v1:443')
36
+ Foo.base_uri.should == 'https://api.foo.com/v1:443'
37
+ end
38
+
39
+ it "should not remove https for ssl requests" do
40
+ Foo.base_uri('https://api.foo.com/v1:443')
41
+ Foo.base_uri.should == 'https://api.foo.com/v1:443'
32
42
  end
33
43
  end
34
44
 
@@ -59,19 +69,19 @@ describe HTTParty do
59
69
  describe "basic http authentication" do
60
70
  it "should work" do
61
71
  Foo.basic_auth 'foobar', 'secret'
62
- Foo.instance_variable_get("@auth").should == {:username => 'foobar', :password => 'secret'}
72
+ Foo.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'}
63
73
  end
64
74
  end
65
75
 
66
76
  describe "format" do
67
77
  it "should allow xml" do
68
78
  Foo.format :xml
69
- Foo.instance_variable_get("@format").should == 'xml'
79
+ Foo.default_options[:format].should == :xml
70
80
  end
71
81
 
72
82
  it "should allow json" do
73
83
  Foo.format :json
74
- Foo.instance_variable_get("@format").should == 'json'
84
+ Foo.default_options[:format].should == :json
75
85
  end
76
86
 
77
87
  it 'should not allow funky format' do
@@ -80,66 +90,31 @@ describe HTTParty do
80
90
  end.should raise_error(HTTParty::UnsupportedFormat)
81
91
  end
82
92
  end
83
-
84
- describe 'http' do
85
- it "should use ssl for port 443" do
86
- FooWithHttps.send(:http, URI.parse('https://api.foo.com/v1:443')).use_ssl?.should == true
87
- end
88
-
89
- it 'should not use ssl for port 80' do
90
- Foo.send(:http, URI.parse('http://foobar.com')).use_ssl?.should == false
91
- end
92
- end
93
-
94
- describe "deriving format from path" do
95
- it "should work if there is extension and extension is an allowed format" do
96
- %w[xml json].each do |ext|
97
- Foo.send(:format_from_path, "/foo/bar.#{ext}").should == ext
98
- end
99
- end
100
-
101
- it "should NOT work if there is extension but extention is not allow format" do
102
- Foo.send(:format_from_path, '/foo/bar.php').should == nil
103
- end
104
-
105
- it 'should NOT work if there is no extension' do
106
- ['', '.'].each do |ext|
107
- Foo.send(:format_from_path, "/foo/bar#{ext}").should == nil
108
- end
109
- end
110
- end
111
-
112
- describe 'parsing responses' do
113
- it 'should handle xml automatically' do
114
- xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
115
- Foo.format :xml
116
- Foo.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
117
- end
118
-
119
- it 'should handle json automatically' do
120
- json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
121
- Foo.format :json
122
- Foo.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
93
+
94
+ describe "with explicit override of automatic redirect handling" do
95
+
96
+ it "should fail with redirected GET" do
97
+ lambda do
98
+ Foo.get('/foo', :no_follow => true)
99
+ end.should raise_error(HTTParty::RedirectionTooDeep)
123
100
  end
124
- end
125
-
126
- describe "sending requests" do
127
- it "should not work with request method other than get, post, put, delete" do
101
+
102
+ it "should fail with redirected POST" do
128
103
  lambda do
129
- Foo.send(:send_request, 'foo', '/foo')
130
- end.should raise_error(ArgumentError)
104
+ Foo.post('/foo', :no_follow => true)
105
+ end.should raise_error(HTTParty::RedirectionTooDeep)
131
106
  end
132
-
133
- it 'should require that :headers is a hash if present' do
107
+
108
+ it "should fail with redirected DELETE" do
134
109
  lambda do
135
- Foo.send(:send_request, 'get', '/foo', :headers => 'string')
136
- end.should raise_error(ArgumentError)
110
+ Foo.delete('/foo', :no_follow => true)
111
+ end.should raise_error(HTTParty::RedirectionTooDeep)
137
112
  end
138
-
139
- it 'should require that :basic_auth is a hash if present' do
113
+
114
+ it "should fail with redirected PUT" do
140
115
  lambda do
141
- Foo.send(:send_request, 'get', '/foo', :basic_auth => 'string')
142
- end.should raise_error(ArgumentError)
116
+ Foo.put('/foo', :no_follow => true)
117
+ end.should raise_error(HTTParty::RedirectionTooDeep)
143
118
  end
144
119
  end
145
- end
120
+ end
@@ -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: httparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
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-08-22 00:00:00 -04:00
12
+ date: 2008-11-14 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "2.1"
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
25
35
  description: Makes http fun! Also, makes consuming restful web services dead easy.
26
36
  email:
27
37
  - nunemaker@gmail.com
@@ -46,19 +56,19 @@ files:
46
56
  - config/requirements.rb
47
57
  - examples/aaws.rb
48
58
  - examples/delicious.rb
59
+ - examples/google.rb
49
60
  - examples/twitter.rb
50
61
  - examples/whoismyrep.rb
51
62
  - httparty.gemspec
52
63
  - lib/httparty.rb
53
- - lib/httparty/core_ext.rb
54
- - lib/httparty/core_ext/hash.rb
64
+ - lib/httparty/request.rb
55
65
  - lib/httparty/version.rb
56
66
  - script/console
57
67
  - script/destroy
58
68
  - script/generate
59
69
  - script/txt2html
60
70
  - setup.rb
61
- - spec/hash_spec.rb
71
+ - spec/httparty/request_spec.rb
62
72
  - spec/httparty_spec.rb
63
73
  - spec/spec.opts
64
74
  - spec/spec_helper.rb
@@ -90,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
100
  requirements: []
91
101
 
92
102
  rubyforge_project: httparty
93
- rubygems_version: 1.2.0
103
+ rubygems_version: 1.3.1
94
104
  signing_key:
95
105
  specification_version: 2
96
106
  summary: Makes http fun! Also, makes consuming restful web services dead easy.
@@ -1,2 +0,0 @@
1
- dir = File.expand_path(File.join(File.dirname(__FILE__), 'core_ext'))
2
- require File.join(dir, 'hash')
@@ -1,21 +0,0 @@
1
- module HTTParty
2
- module CoreExt
3
- module HashConversions
4
- def to_struct
5
- o = OpenStruct.new
6
- self.each do |k, v|
7
- # if id, we create an accessor so we don't get warning about id deprecation
8
- if k.to_s == 'id'
9
- o.class.class_eval "attr_accessor :id"
10
- o.id = v
11
- else
12
- o.send("#{k}=", v.is_a?(Hash) ? v.to_struct : v)
13
- end
14
- end
15
- o
16
- end
17
- end
18
- end
19
- end
20
-
21
- Hash.send :include, HTTParty::CoreExt::HashConversions
@@ -1,11 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- describe HTTParty::CoreExt::HashConversions do
4
- it "should convert hash to struct" do
5
- {'foo' => 'bar'}.to_struct.should == OpenStruct.new(:foo => 'bar')
6
- end
7
-
8
- it 'should convert nested hash to struct' do
9
- {'foo' => {'bar' => 'baz'}}.to_struct.should == OpenStruct.new(:foo => OpenStruct.new(:bar => 'baz'))
10
- end
11
- end