voxdolo-httparty 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/History +108 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest +55 -0
  4. data/README +35 -0
  5. data/Rakefile +47 -0
  6. data/bin/httparty +98 -0
  7. data/cucumber.yml +1 -0
  8. data/examples/aaws.rb +32 -0
  9. data/examples/basic.rb +11 -0
  10. data/examples/delicious.rb +37 -0
  11. data/examples/google.rb +16 -0
  12. data/examples/rubyurl.rb +14 -0
  13. data/examples/twitter.rb +31 -0
  14. data/examples/whoismyrep.rb +10 -0
  15. data/features/basic_authentication.feature +20 -0
  16. data/features/command_line.feature +7 -0
  17. data/features/deals_with_http_error_codes.feature +26 -0
  18. data/features/handles_multiple_formats.feature +34 -0
  19. data/features/steps/env.rb +15 -0
  20. data/features/steps/httparty_response_steps.rb +26 -0
  21. data/features/steps/httparty_steps.rb +15 -0
  22. data/features/steps/mongrel_helper.rb +55 -0
  23. data/features/steps/remote_service_steps.rb +47 -0
  24. data/features/supports_redirection.feature +22 -0
  25. data/httparty.gemspec +37 -0
  26. data/lib/core_extensions.rb +175 -0
  27. data/lib/httparty/cookie_hash.rb +9 -0
  28. data/lib/httparty/exceptions.rb +7 -0
  29. data/lib/httparty/module_inheritable_attributes.rb +25 -0
  30. data/lib/httparty/parsers/json.rb +74 -0
  31. data/lib/httparty/parsers/xml.rb +209 -0
  32. data/lib/httparty/parsers.rb +4 -0
  33. data/lib/httparty/request.rb +139 -0
  34. data/lib/httparty/response.rb +17 -0
  35. data/lib/httparty/version.rb +3 -0
  36. data/lib/httparty.rb +201 -0
  37. data/setup.rb +1585 -0
  38. data/spec/fixtures/delicious.xml +23 -0
  39. data/spec/fixtures/empty.xml +0 -0
  40. data/spec/fixtures/google.html +3 -0
  41. data/spec/fixtures/twitter.json +1 -0
  42. data/spec/fixtures/twitter.xml +403 -0
  43. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  44. data/spec/hash_spec.rb +49 -0
  45. data/spec/httparty/cookie_hash_spec.rb +38 -0
  46. data/spec/httparty/parsers/json_spec.rb +42 -0
  47. data/spec/httparty/parsers/xml_spec.rb +445 -0
  48. data/spec/httparty/request_spec.rb +205 -0
  49. data/spec/httparty/response_spec.rb +53 -0
  50. data/spec/httparty_spec.rb +259 -0
  51. data/spec/spec.opts +3 -0
  52. data/spec/spec_helper.rb +21 -0
  53. data/spec/string_spec.rb +27 -0
  54. data/website/css/common.css +47 -0
  55. data/website/index.html +74 -0
  56. metadata +133 -0
@@ -0,0 +1,4 @@
1
+ Dir[File.dirname(__FILE__) + "/parsers/*.rb"].sort.each do |path|
2
+ filename = File.basename(path)
3
+ require "httparty/parsers/#{filename}"
4
+ end
@@ -0,0 +1,139 @@
1
+ require 'uri'
2
+
3
+ module HTTParty
4
+ class Request #:nodoc:
5
+ SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
6
+
7
+ attr_accessor :http_method, :path, :options
8
+
9
+ def initialize(http_method, path, o={})
10
+ self.http_method = http_method
11
+ self.path = path
12
+ self.options = {
13
+ :limit => o.delete(:no_follow) ? 0 : 5,
14
+ :default_params => {},
15
+ }.merge(o)
16
+ end
17
+
18
+ def path=(uri)
19
+ @path = URI.parse(uri)
20
+ end
21
+
22
+ def uri
23
+ new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
24
+
25
+ # avoid double query string on redirects [#12]
26
+ unless @redirect
27
+ new_uri.query = query_string(new_uri)
28
+ end
29
+
30
+ new_uri
31
+ end
32
+
33
+ def format
34
+ options[:format]
35
+ end
36
+
37
+ def perform
38
+ validate
39
+ setup_raw_request
40
+ handle_response(get_response)
41
+ end
42
+
43
+ private
44
+ def http
45
+ http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
46
+ http.use_ssl = (uri.port == 443)
47
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
48
+ http
49
+ end
50
+
51
+ def configure_basic_auth
52
+ @raw_request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password])
53
+ end
54
+
55
+ def setup_raw_request
56
+ @raw_request = http_method.new(uri.request_uri)
57
+
58
+ if post? && options[:query]
59
+ @raw_request.set_form_data(options[:query])
60
+ end
61
+
62
+ @raw_request.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] unless options[:body].blank?
63
+ @raw_request.initialize_http_header options[:headers]
64
+
65
+ configure_basic_auth if options[:basic_auth]
66
+ end
67
+
68
+ def perform_actual_request
69
+ http.request(@raw_request)
70
+ end
71
+
72
+ def get_response
73
+ response = perform_actual_request
74
+ options[:format] ||= format_from_mimetype(response['content-type'])
75
+ response
76
+ end
77
+
78
+ def query_string(uri)
79
+ query_string_parts = []
80
+ query_string_parts << uri.query unless uri.query.blank?
81
+
82
+ if options[:query].is_a?(Hash)
83
+ query_string_parts << options[:default_params].merge(options[:query]).to_params
84
+ else
85
+ query_string_parts << options[:default_params].to_params unless options[:default_params].blank?
86
+ query_string_parts << options[:query] unless options[:query].blank?
87
+ end
88
+
89
+ query_string_parts.size > 0 ? query_string_parts.join('&') : nil
90
+ end
91
+
92
+ # Raises exception Net::XXX (http error code) if an http error occured
93
+ def handle_response(response)
94
+ case response
95
+ when Net::HTTPRedirection
96
+ options[:limit] -= 1
97
+ self.path = response['location']
98
+ @redirect = true
99
+ perform
100
+ else
101
+ parsed_response = parse_response(response.body)
102
+ Response.new(parsed_response, response.body, response.code, response.to_hash)
103
+ end
104
+ end
105
+
106
+ def parse_response(body)
107
+ return nil if body.nil? or body.empty? or body =~ /^\s+$/
108
+ case format
109
+ when :xml
110
+ HTTParty::Parsers::XML.parse(body)
111
+ when :json
112
+ HTTParty::Parsers::JSON.decode(body)
113
+ when :yaml
114
+ YAML::load(body)
115
+ else
116
+ body
117
+ end
118
+ end
119
+
120
+ # Uses the HTTP Content-Type header to determine the format of the response
121
+ # It compares the MIME type returned to the types stored in the AllowedFormats hash
122
+ def format_from_mimetype(mimetype)
123
+ return nil if mimetype.nil?
124
+ AllowedFormats.each { |k, v| return v if mimetype.include?(k) }
125
+ end
126
+
127
+ def validate
128
+ raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
129
+ raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
130
+ raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
131
+ raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
132
+ raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash)
133
+ end
134
+
135
+ def post?
136
+ Net::HTTP::Post == http_method
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,17 @@
1
+ module HTTParty
2
+ class Response < BlankSlate #:nodoc:
3
+ attr_accessor :body, :code, :headers
4
+ attr_reader :delegate
5
+
6
+ def initialize(delegate, body, code, headers={})
7
+ @delegate = delegate
8
+ @body = body
9
+ @code = code
10
+ @headers = headers
11
+ end
12
+
13
+ def method_missing(name, *args, &block)
14
+ @delegate.send(name, *args, &block)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module HTTParty #:nodoc:
2
+ Version = '0.3.1'
3
+ end
data/lib/httparty.rb ADDED
@@ -0,0 +1,201 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'net/http'
4
+ require 'net/https'
5
+ require 'core_extensions'
6
+ require 'httparty/module_inheritable_attributes'
7
+
8
+ module HTTParty
9
+
10
+ AllowedFormats = {
11
+ 'text/xml' => :xml,
12
+ 'application/xml' => :xml,
13
+ 'application/json' => :json,
14
+ 'text/json' => :json,
15
+ 'application/javascript' => :json,
16
+ 'text/javascript' => :json,
17
+ 'text/html' => :html,
18
+ 'application/x-yaml' => :yaml,
19
+ 'text/yaml' => :yaml
20
+ } unless defined?(AllowedFormats)
21
+
22
+ def self.included(base)
23
+ base.extend ClassMethods
24
+ base.send :include, HTTParty::ModuleInheritableAttributes
25
+ base.send(:mattr_inheritable, :default_options)
26
+ base.instance_variable_set("@default_options", {})
27
+ end
28
+
29
+ module ClassMethods
30
+ # Allows setting http proxy information to be used
31
+ #
32
+ # class Foo
33
+ # include HTTParty
34
+ # http_proxy 'http://foo.com', 80
35
+ # end
36
+ def http_proxy(addr=nil, port = nil)
37
+ default_options[:http_proxyaddr] = addr
38
+ default_options[:http_proxyport] = port
39
+ end
40
+
41
+ # Allows setting a base uri to be used for each request.
42
+ # Will normalize uri to include http, etc.
43
+ #
44
+ # class Foo
45
+ # include HTTParty
46
+ # base_uri 'twitter.com'
47
+ # end
48
+ def base_uri(uri=nil)
49
+ return default_options[:base_uri] unless uri
50
+ default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
51
+ end
52
+
53
+ # Allows setting basic authentication username and password.
54
+ #
55
+ # class Foo
56
+ # include HTTParty
57
+ # basic_auth 'username', 'password'
58
+ # end
59
+ def basic_auth(u, p)
60
+ default_options[:basic_auth] = {:username => u, :password => p}
61
+ end
62
+
63
+ # Allows setting default parameters to be appended to each request.
64
+ # Great for api keys and such.
65
+ #
66
+ # class Foo
67
+ # include HTTParty
68
+ # default_params :api_key => 'secret', :another => 'foo'
69
+ # end
70
+ def default_params(h={})
71
+ raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash)
72
+ default_options[:default_params] ||= {}
73
+ default_options[:default_params].merge!(h)
74
+ end
75
+
76
+ # Allows setting a base uri to be used for each request.
77
+ #
78
+ # class Foo
79
+ # include HTTParty
80
+ # headers 'Accept' => 'text/html'
81
+ # end
82
+ def headers(h={})
83
+ raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash)
84
+ default_options[:headers] ||= {}
85
+ default_options[:headers].merge!(h)
86
+ end
87
+
88
+ def cookies(h={})
89
+ raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash)
90
+ default_options[:cookies] ||= CookieHash.new
91
+ default_options[:cookies].add_cookies(h)
92
+ end
93
+
94
+ # Allows setting the format with which to parse.
95
+ # Must be one of the allowed formats ie: json, xml
96
+ #
97
+ # class Foo
98
+ # include HTTParty
99
+ # format :json
100
+ # end
101
+ def format(f)
102
+ raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.join(', ')}" unless AllowedFormats.value?(f)
103
+ default_options[:format] = f
104
+ end
105
+
106
+ # Allows making a get request to a url.
107
+ #
108
+ # class Foo
109
+ # include HTTParty
110
+ # end
111
+ #
112
+ # # Simple get with full url
113
+ # Foo.get('http://foo.com/resource.json')
114
+ #
115
+ # # Simple get with full url and query parameters
116
+ # # ie: http://foo.com/resource.json?limit=10
117
+ # Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
118
+ def get(path, options={})
119
+ perform_request Net::HTTP::Get, path, options
120
+ end
121
+
122
+ # Allows making a post request to a url.
123
+ #
124
+ # class Foo
125
+ # include HTTParty
126
+ # end
127
+ #
128
+ # # Simple post with full url and setting the body
129
+ # Foo.post('http://foo.com/resources', :body => {:bar => 'baz'})
130
+ #
131
+ # # Simple post with full url using :query option,
132
+ # # which gets set as form data on the request.
133
+ # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
134
+ def post(path, options={})
135
+ perform_request Net::HTTP::Post, path, options
136
+ end
137
+
138
+ def put(path, options={})
139
+ perform_request Net::HTTP::Put, path, options
140
+ end
141
+
142
+ def delete(path, options={})
143
+ perform_request Net::HTTP::Delete, path, options
144
+ end
145
+
146
+ def default_options #:nodoc:
147
+ @default_options
148
+ end
149
+
150
+ private
151
+ def perform_request(http_method, path, options) #:nodoc:
152
+ process_cookies(options)
153
+ Request.new(http_method, path, default_options.dup.merge(options)).perform
154
+ end
155
+
156
+ def process_cookies(options) #:nodoc:
157
+ return unless options[:cookies] || default_options[:cookies]
158
+ options[:headers] ||= {}
159
+ options[:headers]["cookie"] = cookies(options[:cookies] || {}).to_cookie_string
160
+
161
+ default_options.delete(:cookies)
162
+ options.delete(:cookies)
163
+ end
164
+ end
165
+
166
+ def self.normalize_base_uri(url) #:nodoc:
167
+ use_ssl = (url =~ /^https/) || url.include?(':443')
168
+ ends_with_slash = url =~ /\/$/
169
+
170
+ url.chop! if ends_with_slash
171
+ url.gsub!(/^https?:\/\//i, '')
172
+
173
+ "http#{'s' if use_ssl}://#{url}"
174
+ end
175
+
176
+ class Basement #:nodoc:
177
+ include HTTParty
178
+ end
179
+
180
+ def self.get(*args)
181
+ Basement.get(*args)
182
+ end
183
+
184
+ def self.post(*args)
185
+ Basement.post(*args)
186
+ end
187
+
188
+ def self.put(*args)
189
+ Basement.put(*args)
190
+ end
191
+
192
+ def self.delete(*args)
193
+ Basement.delete(*args)
194
+ end
195
+ end
196
+
197
+ require 'httparty/cookie_hash'
198
+ require 'httparty/exceptions'
199
+ require 'httparty/request'
200
+ require 'httparty/response'
201
+ require 'httparty/parsers'