luigi-httparty 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+