luigi-httparty 0.4.6 → 0.5.0

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.
@@ -2,38 +2,57 @@ require 'uri'
2
2
 
3
3
  module HTTParty
4
4
  class Request #:nodoc:
5
- SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
6
-
5
+ SupportedHTTPMethods = [
6
+ Net::HTTP::Get,
7
+ Net::HTTP::Post,
8
+ Net::HTTP::Put,
9
+ Net::HTTP::Delete,
10
+ Net::HTTP::Head,
11
+ Net::HTTP::Options
12
+ ]
13
+
14
+ SupportedURISchemes = [URI::HTTP, URI::HTTPS]
15
+
7
16
  attr_accessor :http_method, :path, :options
8
-
17
+
9
18
  def initialize(http_method, path, o={})
10
19
  self.http_method = http_method
11
20
  self.path = path
12
21
  self.options = {
13
- :limit => o.delete(:no_follow) ? 0 : 5,
22
+ :limit => o.delete(:no_follow) ? 0 : 5,
14
23
  :default_params => {},
24
+ :parser => Parser
15
25
  }.merge(o)
16
26
  end
17
27
 
18
28
  def path=(uri)
19
29
  @path = URI.parse(uri)
20
30
  end
21
-
31
+
22
32
  def uri
23
33
  new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
24
-
34
+
25
35
  # avoid double query string on redirects [#12]
26
36
  unless @redirect
27
37
  new_uri.query = query_string(new_uri)
28
38
  end
29
-
39
+
40
+ unless SupportedURISchemes.include? new_uri.class
41
+ raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP or HTTPS"
42
+ end
43
+
30
44
  new_uri
31
45
  end
32
-
46
+
33
47
  def format
34
48
  options[:format]
35
49
  end
36
-
50
+
51
+ def parser
52
+ options[:parser]
53
+ end
54
+
55
+
37
56
  def perform
38
57
  validate
39
58
  setup_raw_request
@@ -44,23 +63,36 @@ module HTTParty
44
63
 
45
64
  def http
46
65
  http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
47
- http.use_ssl = (uri.port == 443)
48
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
66
+ http.use_ssl = ssl_implied?
67
+
49
68
  if options[:timeout] && options[:timeout].is_a?(Integer)
50
69
  http.open_timeout = options[:timeout]
51
70
  http.read_timeout = options[:timeout]
52
71
  end
72
+
73
+ if options[:pem] && http.use_ssl?
74
+ http.cert = OpenSSL::X509::Certificate.new(options[:pem])
75
+ http.key = OpenSSL::PKey::RSA.new(options[:pem])
76
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
77
+ else
78
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
79
+ end
80
+
53
81
  http
54
82
  end
55
83
 
84
+ def ssl_implied?
85
+ uri.port == 443 || uri.instance_of?(URI::HTTPS)
86
+ end
87
+
56
88
  def body
57
89
  options[:body].is_a?(Hash) ? options[:body].to_params : options[:body]
58
90
  end
59
-
91
+
60
92
  def username
61
93
  options[:basic_auth][:username]
62
94
  end
63
-
95
+
64
96
  def password
65
97
  options[:basic_auth][:password]
66
98
  end
@@ -81,7 +113,7 @@ module HTTParty
81
113
  options[:format] ||= format_from_mimetype(response['content-type'])
82
114
  response
83
115
  end
84
-
116
+
85
117
  def query_string(uri)
86
118
  query_string_parts = []
87
119
  query_string_parts << uri.query unless uri.query.nil?
@@ -92,10 +124,10 @@ module HTTParty
92
124
  query_string_parts << options[:default_params].to_params unless options[:default_params].nil?
93
125
  query_string_parts << options[:query] unless options[:query].nil?
94
126
  end
95
-
127
+
96
128
  query_string_parts.size > 0 ? query_string_parts.join('&') : nil
97
129
  end
98
-
130
+
99
131
  # Raises exception Net::XXX (http error code) if an http error occured
100
132
  def handle_response(response)
101
133
  case response
@@ -107,43 +139,14 @@ module HTTParty
107
139
  capture_cookies(response)
108
140
  perform
109
141
  else
110
- parsed_response = parse_response(response.body)
111
- Response.new(parsed_response, response.body, response.code, response.message, response.to_hash)
142
+ Response.new(parse_response(response.body), response.body, response.code, response.message, response.to_hash)
112
143
  end
113
144
  end
114
-
115
- # HTTParty.const_get((self.format.to_s || 'text').capitalize)
145
+
116
146
  def parse_response(body)
117
- return nil if body.nil? or body.empty?
118
- if options[:parser].blank?
119
- case format
120
- when :xml
121
- Crack::XML.parse(body)
122
- when :json
123
- Crack::JSON.parse(body)
124
- when :yaml
125
- YAML::load(body)
126
- else
127
- body
128
- end
129
- else
130
- if options[:parser].is_a?(Proc)
131
- options[:parser].call(body)
132
- else
133
- body
134
- end
135
- end
136
- end
137
-
138
- def capture_cookies(response)
139
- return unless response['Set-Cookie']
140
- cookies_hash = HTTParty::CookieHash.new()
141
- cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie']
142
- cookies_hash.add_cookies(response['Set-Cookie'])
143
- options[:headers] ||= {}
144
- options[:headers]['Cookie'] = cookies_hash.to_cookie_string
147
+ parser.call(body, format)
145
148
  end
146
-
149
+
147
150
  def capture_cookies(response)
148
151
  return unless response['Set-Cookie']
149
152
  cookies_hash = HTTParty::CookieHash.new()
@@ -152,24 +155,27 @@ module HTTParty
152
155
  options[:headers] ||= {}
153
156
  options[:headers]['Cookie'] = cookies_hash.to_cookie_string
154
157
  end
155
-
156
- # Uses the HTTP Content-Type header to determine the format of the response
157
- # It compares the MIME type returned to the types stored in the AllowedFormats hash
158
+
159
+ # Uses the HTTP Content-Type header to determine the format of the
160
+ # response It compares the MIME type returned to the types stored in the
161
+ # SupportedFormats hash
158
162
  def format_from_mimetype(mimetype)
159
- return nil if mimetype.nil?
160
- AllowedFormats.each { |k, v| return v if mimetype.include?(k) }
163
+ if mimetype && parser.respond_to?(:format_from_mimetype)
164
+ parser.format_from_mimetype(mimetype)
165
+ end
161
166
  end
162
-
167
+
163
168
  def validate
164
169
  raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
165
- raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
170
+ raise ArgumentError, 'only get, post, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
166
171
  raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
167
172
  raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
168
173
  raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash)
169
174
  end
170
-
175
+
171
176
  def post?
172
177
  Net::HTTP::Post == http_method
173
178
  end
174
179
  end
175
180
  end
181
+
@@ -1,5 +1,6 @@
1
1
  module HTTParty
2
- class Response < BasicObject #:nodoc:
2
+
3
+ class Response < HTTParty::BasicObject #:nodoc:
3
4
  RESPONDS_TO = /^((body|code|message|headers)=?|delegate)$/
4
5
  attr_accessor :body, :code, :message, :headers
5
6
  attr_reader :delegate
@@ -1,3 +1,3 @@
1
1
  module HTTParty #:nodoc:
2
- Version = '0.4.4'
2
+ Version = '0.5.0'
3
3
  end
data/lib/httparty.rb CHANGED
@@ -11,20 +11,19 @@ require dir + 'httparty/module_inheritable_attributes'
11
11
  require dir + 'httparty/cookie_hash'
12
12
 
13
13
  module HTTParty
14
-
15
- AllowedFormats = {
16
- 'text/xml' => :xml,
17
- 'application/xml' => :xml,
18
- 'application/json' => :json,
19
- 'text/json' => :json,
20
- 'application/javascript' => :json,
21
- 'text/javascript' => :json,
22
- 'text/html' => :html,
23
- 'application/x-yaml' => :yaml,
24
- 'text/yaml' => :yaml,
25
- 'text/plain' => :plain
26
- } unless defined?(AllowedFormats)
27
-
14
+ module AllowedFormatsDeprecation
15
+ def const_missing(const)
16
+ if const.to_s =~ /AllowedFormats$/
17
+ Kernel.warn("Deprecated: Use HTTParty::Parser::SupportedFormats")
18
+ HTTParty::Parser::SupportedFormats
19
+ else
20
+ super
21
+ end
22
+ end
23
+ end
24
+
25
+ extend AllowedFormatsDeprecation
26
+
28
27
  def self.included(base)
29
28
  base.extend ClassMethods
30
29
  base.send :include, HTTParty::ModuleInheritableAttributes
@@ -33,8 +32,10 @@ module HTTParty
33
32
  base.instance_variable_set("@default_options", {})
34
33
  base.instance_variable_set("@default_cookies", CookieHash.new)
35
34
  end
36
-
35
+
37
36
  module ClassMethods
37
+ extend AllowedFormatsDeprecation
38
+
38
39
  # Allows setting http proxy information to be used
39
40
  #
40
41
  # class Foo
@@ -45,7 +46,7 @@ module HTTParty
45
46
  default_options[:http_proxyaddr] = addr
46
47
  default_options[:http_proxyport] = port
47
48
  end
48
-
49
+
49
50
  # Allows setting a base uri to be used for each request.
50
51
  # Will normalize uri to include http, etc.
51
52
  #
@@ -57,7 +58,7 @@ module HTTParty
57
58
  return default_options[:base_uri] unless uri
58
59
  default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
59
60
  end
60
-
61
+
61
62
  # Allows setting basic authentication username and password.
62
63
  #
63
64
  # class Foo
@@ -67,7 +68,7 @@ module HTTParty
67
68
  def basic_auth(u, p)
68
69
  default_options[:basic_auth] = {:username => u, :password => p}
69
70
  end
70
-
71
+
71
72
  # Allows setting default parameters to be appended to each request.
72
73
  # Great for api keys and such.
73
74
  #
@@ -80,7 +81,7 @@ module HTTParty
80
81
  default_options[:default_params] ||= {}
81
82
  default_options[:default_params].merge!(h)
82
83
  end
83
-
84
+
84
85
  # Allows setting a base uri to be used for each request.
85
86
  #
86
87
  # class Foo
@@ -97,7 +98,7 @@ module HTTParty
97
98
  raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash)
98
99
  default_cookies.add_cookies(h)
99
100
  end
100
-
101
+
101
102
  # Allows setting the format with which to parse.
102
103
  # Must be one of the allowed formats ie: json, xml
103
104
  #
@@ -105,47 +106,67 @@ module HTTParty
105
106
  # include HTTParty
106
107
  # format :json
107
108
  # end
108
- def format(f)
109
- raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.map { |v| v.to_s }.uniq.sort.join(', ')}" unless AllowedFormats.value?(f)
110
- default_options[:format] = f
109
+ def format(f = nil)
110
+ if f.nil?
111
+ default_options[:format]
112
+ else
113
+ parser(Parser) if parser.nil?
114
+ default_options[:format] = f
115
+ validate_format
116
+ end
111
117
  end
112
-
118
+
119
+ # Allows setting a PEM file to be used
120
+ #
121
+ # class Foo
122
+ # include HTTParty
123
+ # pem File.read('/home/user/my.pem')
124
+ # end
125
+ def pem(pem_contents)
126
+ default_options[:pem] = pem_contents
127
+ end
128
+
113
129
  # Allows setting a custom parser for the response.
114
130
  #
115
131
  # class Foo
116
132
  # include HTTParty
117
133
  # parser Proc.new {|data| ...}
118
134
  # end
119
- def parser(customer_parser)
120
- default_options[:parser] = customer_parser
135
+ def parser(customer_parser = nil)
136
+ if customer_parser.nil?
137
+ default_options[:parser]
138
+ else
139
+ default_options[:parser] = customer_parser
140
+ validate_format
141
+ end
121
142
  end
122
-
143
+
123
144
  # Allows making a get request to a url.
124
145
  #
125
146
  # class Foo
126
147
  # include HTTParty
127
148
  # end
128
- #
149
+ #
129
150
  # # Simple get with full url
130
151
  # Foo.get('http://foo.com/resource.json')
131
- #
152
+ #
132
153
  # # Simple get with full url and query parameters
133
154
  # # ie: http://foo.com/resource.json?limit=10
134
155
  # Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
135
156
  def get(path, options={})
136
157
  perform_request Net::HTTP::Get, path, options
137
158
  end
138
-
159
+
139
160
  # Allows making a post request to a url.
140
161
  #
141
162
  # class Foo
142
163
  # include HTTParty
143
164
  # end
144
- #
165
+ #
145
166
  # # Simple post with full url and setting the body
146
167
  # Foo.post('http://foo.com/resources', :body => {:bar => 'baz'})
147
168
  #
148
- # # Simple post with full url using :query option,
169
+ # # Simple post with full url using :query option,
149
170
  # # which gets set as form data on the request.
150
171
  # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
151
172
  def post(path, options={})
@@ -159,12 +180,21 @@ module HTTParty
159
180
  def delete(path, options={})
160
181
  perform_request Net::HTTP::Delete, path, options
161
182
  end
162
-
183
+
184
+ def head(path, options={})
185
+ perform_request Net::HTTP::Head, path, options
186
+ end
187
+
188
+ def options(path, options={})
189
+ perform_request Net::HTTP::Options, path, options
190
+ end
191
+
163
192
  def default_options #:nodoc:
164
193
  @default_options
165
194
  end
166
195
 
167
196
  private
197
+
168
198
  def perform_request(http_method, path, options) #:nodoc:
169
199
  options = default_options.dup.merge(options)
170
200
  process_cookies(options)
@@ -176,27 +206,33 @@ module HTTParty
176
206
  options[:headers] ||= headers.dup
177
207
  options[:headers]["cookie"] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string
178
208
  end
209
+
210
+ def validate_format
211
+ if format && parser.respond_to?(:supports_format?) && !parser.supports_format?(format)
212
+ raise UnsupportedFormat, "'#{format.inspect}' Must be one of: #{parser.supported_formats.map{|f| f.to_s}.sort.join(', ')}"
213
+ end
214
+ end
179
215
  end
180
216
 
181
217
  def self.normalize_base_uri(url) #:nodoc:
182
218
  normalized_url = url.dup
183
219
  use_ssl = (normalized_url =~ /^https/) || normalized_url.include?(':443')
184
220
  ends_with_slash = normalized_url =~ /\/$/
185
-
221
+
186
222
  normalized_url.chop! if ends_with_slash
187
223
  normalized_url.gsub!(/^https?:\/\//i, '')
188
-
224
+
189
225
  "http#{'s' if use_ssl}://#{normalized_url}"
190
226
  end
191
-
227
+
192
228
  class Basement #:nodoc:
193
229
  include HTTParty
194
230
  end
195
-
231
+
196
232
  def self.get(*args)
197
233
  Basement.get(*args)
198
234
  end
199
-
235
+
200
236
  def self.post(*args)
201
237
  Basement.post(*args)
202
238
  end
@@ -208,9 +244,20 @@ module HTTParty
208
244
  def self.delete(*args)
209
245
  Basement.delete(*args)
210
246
  end
247
+
248
+ def self.head(*args)
249
+ Basement.head(*args)
250
+ end
251
+
252
+ def self.options(*args)
253
+ Basement.options(*args)
254
+ end
255
+
211
256
  end
212
257
 
213
258
  require dir + 'httparty/core_extensions'
214
259
  require dir + 'httparty/exceptions'
260
+ require dir + 'httparty/parser'
215
261
  require dir + 'httparty/request'
216
262
  require dir + 'httparty/response'
263
+
@@ -0,0 +1,128 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{luigi-httparty}
8
+ s.version = "0.5.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["John Nunemaker", "Sandro Turriate"]
12
+ s.date = %q{2009-12-08}
13
+ s.default_executable = %q{httparty}
14
+ s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
15
+ s.email = %q{nunemaker@gmail.com}
16
+ s.executables = ["httparty"]
17
+ s.extra_rdoc_files = [
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "History",
23
+ "MIT-LICENSE",
24
+ "Manifest",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/httparty",
29
+ "cucumber.yml",
30
+ "examples/aaws.rb",
31
+ "examples/basic.rb",
32
+ "examples/custom_parsers.rb",
33
+ "examples/delicious.rb",
34
+ "examples/google.rb",
35
+ "examples/rubyurl.rb",
36
+ "examples/twitter.rb",
37
+ "examples/whoismyrep.rb",
38
+ "features/basic_authentication.feature",
39
+ "features/command_line.feature",
40
+ "features/deals_with_http_error_codes.feature",
41
+ "features/handles_multiple_formats.feature",
42
+ "features/steps/env.rb",
43
+ "features/steps/httparty_response_steps.rb",
44
+ "features/steps/httparty_steps.rb",
45
+ "features/steps/mongrel_helper.rb",
46
+ "features/steps/remote_service_steps.rb",
47
+ "features/supports_redirection.feature",
48
+ "features/supports_timeout_option.feature",
49
+ "httparty.gemspec",
50
+ "lib/httparty.rb",
51
+ "lib/httparty/cookie_hash.rb",
52
+ "lib/httparty/core_extensions.rb",
53
+ "lib/httparty/exceptions.rb",
54
+ "lib/httparty/module_inheritable_attributes.rb",
55
+ "lib/httparty/parser.rb",
56
+ "lib/httparty/request.rb",
57
+ "lib/httparty/response.rb",
58
+ "lib/httparty/version.rb",
59
+ "luigi-httparty.gemspec",
60
+ "spec/fixtures/delicious.xml",
61
+ "spec/fixtures/empty.xml",
62
+ "spec/fixtures/google.html",
63
+ "spec/fixtures/twitter.json",
64
+ "spec/fixtures/twitter.xml",
65
+ "spec/fixtures/undefined_method_add_node_for_nil.xml",
66
+ "spec/httparty/cookie_hash_spec.rb",
67
+ "spec/httparty/parser_spec.rb",
68
+ "spec/httparty/request_spec.rb",
69
+ "spec/httparty/response_spec.rb",
70
+ "spec/httparty_spec.rb",
71
+ "spec/spec.opts",
72
+ "spec/spec_helper.rb",
73
+ "website/css/common.css",
74
+ "website/index.html"
75
+ ]
76
+ s.homepage = %q{http://httparty.rubyforge.org}
77
+ s.post_install_message = %q{When you HTTParty, you must party hard!}
78
+ s.rdoc_options = ["--charset=UTF-8"]
79
+ s.require_paths = ["lib"]
80
+ s.rubyforge_project = %q{httparty}
81
+ s.rubygems_version = %q{1.3.5}
82
+ s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
83
+ s.test_files = [
84
+ "spec/httparty/cookie_hash_spec.rb",
85
+ "spec/httparty/parser_spec.rb",
86
+ "spec/httparty/request_spec.rb",
87
+ "spec/httparty/response_spec.rb",
88
+ "spec/httparty_spec.rb",
89
+ "spec/spec_helper.rb",
90
+ "examples/aaws.rb",
91
+ "examples/basic.rb",
92
+ "examples/custom_parsers.rb",
93
+ "examples/delicious.rb",
94
+ "examples/google.rb",
95
+ "examples/rubyurl.rb",
96
+ "examples/twitter.rb",
97
+ "examples/whoismyrep.rb"
98
+ ]
99
+
100
+ if s.respond_to? :specification_version then
101
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
102
+ s.specification_version = 3
103
+
104
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
105
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
106
+ s.add_development_dependency(%q<activesupport>, ["~> 2.3"])
107
+ s.add_development_dependency(%q<cucumber>, ["~> 0.4"])
108
+ s.add_development_dependency(%q<fakeweb>, ["~> 1.2"])
109
+ s.add_development_dependency(%q<mongrel>, ["~> 1.1"])
110
+ s.add_development_dependency(%q<rspec>, ["= 1.2.9"])
111
+ else
112
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
113
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
114
+ s.add_dependency(%q<cucumber>, ["~> 0.4"])
115
+ s.add_dependency(%q<fakeweb>, ["~> 1.2"])
116
+ s.add_dependency(%q<mongrel>, ["~> 1.1"])
117
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
118
+ end
119
+ else
120
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
121
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
122
+ s.add_dependency(%q<cucumber>, ["~> 0.4"])
123
+ s.add_dependency(%q<fakeweb>, ["~> 1.2"])
124
+ s.add_dependency(%q<mongrel>, ["~> 1.1"])
125
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
126
+ end
127
+ end
128
+