public
Rubygem
Description: Makes http fun! Also, makes consuming restful web services dead easy.
Homepage:
Clone URL: git://github.com/jnunemaker/httparty.git
Click here to lend your support to: httparty and make a donation at www.pledgie.com !
Fixed weird uri normalizing issue that occurred when I was doing normalization 
in request object. Also caught a piece of ActiveSupport Hash#to_query that I was 
using. Added Hash#to_params to fix that bug.
jnunemaker (author)
Sat Dec 06 20:41:28 -0800 2008
commit  411340826ba683397df84e611956b34eae398d93
tree    b818ae68c30a2946a91f7968cae9333cc55e6476
parent  7fab301eb592353311a064c76e93c2363f8b7658
...
6
7
8
9
 
 
10
11
12
 
13
14
15
16
17
 
 
 
 
18
19
20
...
6
7
8
 
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0
@@ -6,15 +6,21 @@ examples/rubyurl.rb
0
 examples/twitter.rb
0
 examples/whoismyrep.rb
0
 History
0
-httparty.gemspec
0
+lib/core_extensions.rb
0
+lib/httparty/exceptions.rb
0
 lib/httparty/request.rb
0
 lib/httparty/version.rb
0
 lib/httparty.rb
0
+lib/module_level_inheritable_attributes.rb
0
 Manifest
0
 MIT-LICENSE
0
 Rakefile
0
 README
0
 setup.rb
0
+spec/fixtures/delicious.xml
0
+spec/fixtures/google.html
0
+spec/fixtures/twitter.json
0
+spec/fixtures/twitter.xml
0
 spec/httparty/request_spec.rb
0
 spec/httparty_spec.rb
0
 spec/spec.opts
...
 
 
 
1
2
3
...
1
2
3
4
5
6
0
@@ -1,3 +1,6 @@
0
+require 'rubygems'
0
+require 'activesupport'
0
+
0
 dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
0
 require File.join(dir, 'httparty')
0
 require 'pp'
...
18
19
20
21
22
23
24
...
33
34
35
 
36
...
18
19
20
 
21
22
23
...
32
33
34
35
36
0
@@ -18,7 +18,6 @@ class Delicious
0
   #   ie: posts(:query => {:tag => 'ruby'})
0
   def posts(options={})
0
     options.merge!({:basic_auth => @auth})
0
-    # get posts and convert to structs so we can do .key instead of ['key'] with results
0
     self.class.get('/posts/get', options)
0
   end
0
   
0
@@ -33,4 +32,5 @@ end
0
 
0
 delicious = Delicious.new(config['username'], config['password'])
0
 pp delicious.posts(:query => {:tag => 'ruby'})
0
+pp delicious.recent
0
 
...
28
29
30
31
32
 
33
...
28
29
30
 
31
32
33
0
@@ -28,4 +28,4 @@ twitter = Twitter.new(config['email'], config['password'])
0
 pp twitter.timeline
0
 # pp twitter.timeline(:friends, :query => {:since_id => 868482746})
0
 # pp twitter.timeline(:friends, :query => 'since_id=868482746')
0
-# pp twitter.post('this is a test')
0
\ No newline at end of file
0
+pp twitter.post('this is a test of 0.2.0')
0
\ No newline at end of file
...
2
3
4
5
 
6
7
8
9
 
10
11
12
13
 
 
14
15
16
...
25
26
27
28
 
29
30
31
 
32
33
34
35
 
36
37
38
...
2
3
4
 
5
6
7
8
 
9
10
11
 
 
12
13
14
15
16
...
25
26
27
 
28
29
30
 
31
32
33
34
 
35
36
37
38
0
@@ -2,15 +2,15 @@
0
 
0
 Gem::Specification.new do |s|
0
   s.name = %q{httparty}
0
-  s.version = "0.1.8"
0
+  s.version = "0.2.0"
0
 
0
   s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
0
   s.authors = ["John Nunemaker"]
0
-  s.date = %q{2008-12-05}
0
+  s.date = %q{2008-12-06}
0
   s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
0
   s.email = %q{nunemaker@gmail.com}
0
-  s.extra_rdoc_files = ["lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "README"]
0
-  s.files = ["examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "History", "httparty.gemspec", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "website/css/common.css", "website/index.html"]
0
+  s.extra_rdoc_files = ["lib/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "lib/module_level_inheritable_attributes.rb", "README"]
0
+  s.files = ["examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "History", "httparty.gemspec", "lib/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/request.rb", "lib/httparty/version.rb", "lib/httparty.rb", "lib/module_level_inheritable_attributes.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "spec/fixtures/delicious.xml", "spec/fixtures/google.html", "spec/fixtures/twitter.json", "spec/fixtures/twitter.xml", "spec/httparty/request_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "website/css/common.css", "website/index.html"]
0
   s.has_rdoc = true
0
   s.homepage = %q{http://httparty.rubyforge.org}
0
   s.post_install_message = %q{When you HTTParty, you must party hard!}
0
@@ -25,14 +25,14 @@ Gem::Specification.new do |s|
0
     s.specification_version = 2
0
 
0
     if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
0
-      s.add_runtime_dependency(%q<activesupport>, [">= 2.1"])
0
+      s.add_runtime_dependency(%q<json>, ["~> 1.1"])
0
       s.add_development_dependency(%q<echoe>, [">= 0"])
0
     else
0
-      s.add_dependency(%q<activesupport>, [">= 2.1"])
0
+      s.add_dependency(%q<json>, ["~> 1.1"])
0
       s.add_dependency(%q<echoe>, [">= 0"])
0
     end
0
   else
0
-    s.add_dependency(%q<activesupport>, [">= 2.1"])
0
+    s.add_dependency(%q<json>, ["~> 1.1"])
0
     s.add_dependency(%q<echoe>, [">= 0"])
0
   end
0
 end
...
289
290
291
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
293
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
0
@@ -289,4 +289,52 @@ class Hash
0
   def self.from_xml(xml)
0
     ToHashParser.from_xml(xml)
0
   end
0
+  
0
+  # @return <String> This hash as a query string
0
+  #
0
+  # @example
0
+  #   { :name => "Bob",
0
+  #     :address => {
0
+  #       :street => '111 Ruby Ave.',
0
+  #       :city => 'Ruby Central',
0
+  #       :phones => ['111-111-1111', '222-222-2222']
0
+  #     }
0
+  #   }.to_params
0
+  #     #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
0
+  def to_params
0
+    params = self.map { |k,v| normalize_param(k,v) }.join
0
+    params.chop! # trailing &
0
+    params
0
+  end
0
+
0
+  # @param key<Object> The key for the param.
0
+  # @param value<Object> The value for the param.
0
+  #
0
+  # @return <String> This key value pair as a param
0
+  #
0
+  # @example normalize_param(:name, "Bob") #=> "name=Bob&"
0
+  def normalize_param(key, value)
0
+    param = ''
0
+    stack = []
0
+
0
+    if value.is_a?(Array)
0
+      param << value.map { |element| normalize_param("#{key}[]", element) }.join
0
+    elsif value.is_a?(Hash)
0
+      stack << [key,value]
0
+    else
0
+      param << "#{key}=#{value}&"
0
+    end
0
+
0
+    stack.each do |parent, hash|
0
+      hash.each do |key, value|
0
+        if value.is_a?(Hash)
0
+          stack << ["#{parent}[#{key}]", value]
0
+        else
0
+          param << normalize_param("#{parent}[#{key}]", value)
0
+        end
0
+      end
0
+    end
0
+
0
+    param
0
+  end
0
 end
0
\ No newline at end of file
...
31
32
33
34
 
35
36
37
...
73
74
75
76
 
77
78
79
 
 
 
 
 
 
 
 
 
 
80
81
82
...
31
32
33
 
34
35
36
37
...
73
74
75
 
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
0
@@ -31,7 +31,7 @@ module HTTParty
0
 
0
     def base_uri(uri=nil)
0
       return default_options[:base_uri] unless uri
0
-      default_options[:base_uri] = uri
0
+      default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
0
     end
0
 
0
     def basic_auth(u, p)
0
@@ -73,10 +73,20 @@ module HTTParty
0
 
0
     private
0
       def perform_request(http_method, path, options) #:nodoc:
0
-        Request.new(http_method, path, default_options.merge(options)).perform
0
+        Request.new(http_method, path, default_options.dup.merge(options)).perform
0
       end
0
   end
0
 
0
+  def self.normalize_base_uri(url) #:nodoc:
0
+    use_ssl = (url =~ /^https/) || url.include?(':443')
0
+    ends_with_slash = url =~ /\/$/
0
+    
0
+    url.chop! if ends_with_slash
0
+    url.gsub!(/^https?:\/\//i, '')
0
+    
0
+    "http#{'s' if use_ssl}://#{url}"
0
+  end
0
+  
0
   class Basement
0
     include HTTParty
0
   end
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
16
17
18
19
20
 
21
22
23
24
 
25
26
 
27
28
29
...
31
32
33
34
35
36
37
...
61
62
63
64
 
65
66
67
...
78
79
80
81
 
82
83
 
84
85
86
...
1
2
3
 
 
 
 
 
 
 
 
 
 
 
 
4
5
6
7
8
 
9
10
11
12
 
13
14
 
15
16
17
18
...
20
21
22
 
23
24
25
...
49
50
51
 
52
53
54
55
...
66
67
68
 
69
70
 
71
72
73
74
0
@@ -1,29 +1,18 @@
0
 require 'uri'
0
 
0
 module HTTParty
0
-  class Request
0
-    # Makes it so uri is sure to parse stuff like google.com without the http
0
-    def self.normalize_base_uri(url) #:nodoc:
0
-      use_ssl = (url =~ /^https/) || url.include?(':443')
0
-      ends_with_slash = url =~ /\/$/
0
-      
0
-      url.chop! if ends_with_slash
0
-      url.gsub!(/^https?:\/\//i, '')
0
-      
0
-      "http#{'s' if use_ssl}://#{url}"
0
-    end
0
-    
0
+  class Request    
0
     SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
0
     
0
     attr_accessor :http_method, :path, :options
0
     
0
-    def initialize(http_method, path, options={})
0
+    def initialize(http_method, path, o={})
0
       self.http_method = http_method
0
       self.path = path
0
       self.options = {
0
-        :limit => options.delete(:no_follow) ? 0 : 5, 
0
+        :limit => o.delete(:no_follow) ? 0 : 5, 
0
         :default_params => {},
0
-      }.merge(options.dup)
0
+      }.merge(o)
0
     end
0
 
0
     def path=(uri)
0
@@ -31,7 +20,6 @@ module HTTParty
0
     end
0
     
0
     def uri
0
-      options[:base_uri] = self.class.normalize_base_uri(options[:base_uri]) unless options[:base_uri].nil?
0
       uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
0
       uri.query = query_string(uri)
0
       uri
0
@@ -61,7 +49,7 @@ module HTTParty
0
           request.set_form_data(options[:query])
0
         end
0
         
0
-        request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
0
+        request.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] unless options[:body].blank?
0
         request.initialize_http_header options[:headers]
0
         
0
         if options[:basic_auth]
0
@@ -78,9 +66,9 @@ module HTTParty
0
         query_string_parts << uri.query unless uri.query.blank?
0
 
0
         if options[:query].is_a?(Hash)
0
-          query_string_parts << options[:default_params].merge(options[:query]).to_query
0
+          query_string_parts << options[:default_params].merge(options[:query]).to_params
0
         else
0
-          query_string_parts << options[:default_params].to_query unless options[:default_params].blank?
0
+          query_string_parts << options[:default_params].to_params unless options[:default_params].blank?
0
           query_string_parts << options[:query] unless options[:query].blank?
0
         end
0
         
...
1
2
 
3
4
...
1
 
2
3
4
0
@@ -1,3 +1,3 @@
0
 module HTTParty
0
-  Version = '0.1.8'
0
+  Version = '0.2.0'
0
 end
0
\ No newline at end of file
...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
5
6
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
9
10
11
12
 
 
 
 
 
 
 
13
14
15
0
@@ -5,35 +5,11 @@ describe HTTParty::Request do
0
     @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
0
   end
0
   
0
-  describe "#normalize_base_uri" do
0
-    it "should add http if not present for non ssl requests" do
0
-      uri = HTTParty::Request.normalize_base_uri('api.foobar.com')
0
-      uri.should == 'http://api.foobar.com'
0
-    end
0
-    
0
-    it "should add https if not present for ssl requests" do
0
-      uri = HTTParty::Request.normalize_base_uri('api.foo.com/v1:443')
0
-      uri.should == 'https://api.foo.com/v1:443'
0
-    end
0
-    
0
-    it "should not remove https for ssl requests" do
0
-      uri = HTTParty::Request.normalize_base_uri('https://api.foo.com/v1:443')
0
-      uri.should == 'https://api.foo.com/v1:443'
0
-    end
0
-  end
0
-  
0
   describe "#format" do
0
     it "should return the correct parsing format" do
0
       @request.format.should == :xml
0
     end
0
   end
0
-  
0
-  describe "uri" do
0
-    it "should be normalized" do
0
-      request = HTTParty::Request.new(Net::HTTP::Get, '', :base_uri => 'api.foo.com')
0
-      request.uri.to_s.should == 'http://api.foo.com'
0
-    end
0
-  end
0
 
0
   describe 'http' do
0
     it "should use ssl for port 443" do
...
25
26
27
28
 
29
30
31
...
34
35
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
38
39
...
112
113
114
115
116
 
 
117
118
119
...
25
26
27
 
28
29
30
31
...
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
129
130
131
 
 
132
133
134
135
136
0
@@ -25,7 +25,7 @@ describe HTTParty do
0
     end
0
 
0
     it "should have reader" do
0
-      Foo.base_uri.should == 'api.foo.com/v1'
0
+      Foo.base_uri.should == 'http://api.foo.com/v1'
0
     end
0
     
0
     it 'should have writer' do
0
@@ -34,6 +34,23 @@ describe HTTParty do
0
     end
0
   end
0
   
0
+  describe "#normalize_base_uri" do
0
+    it "should add http if not present for non ssl requests" do
0
+      uri = HTTParty.normalize_base_uri('api.foobar.com')
0
+      uri.should == 'http://api.foobar.com'
0
+    end
0
+    
0
+    it "should add https if not present for ssl requests" do
0
+      uri = HTTParty.normalize_base_uri('api.foo.com/v1:443')
0
+      uri.should == 'https://api.foo.com/v1:443'
0
+    end
0
+    
0
+    it "should not remove https for ssl requests" do
0
+      uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443')
0
+      uri.should == 'https://api.foo.com/v1:443'
0
+    end
0
+  end
0
+  
0
   describe "headers" do
0
     it "should default to empty hash" do
0
       Foo.headers.should == {}
0
@@ -112,8 +129,8 @@ describe HTTParty do
0
   
0
   describe "with multiple class definitions" do
0
     it "should not run over each others options" do
0
-      HRest.default_options.should == {:base_uri => 'hrest.com', :default_params => {:two => 'three'}}
0
-      GRest.default_options.should == {:base_uri => 'grest.com', :default_params => {:one => 'two'}}
0
+      HRest.default_options.should == {:base_uri => 'http://hrest.com', :default_params => {:two => 'three'}}
0
+      GRest.default_options.should == {:base_uri => 'http://grest.com', :default_params => {:one => 'two'}}
0
     end
0
   end
0
   

Comments