httparty 0.8.0 → 0.9.0

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.

data/.gitignore CHANGED
@@ -7,3 +7,4 @@ log/
7
7
  pkg/
8
8
  *.swp
9
9
  /.bundle
10
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - ree
5
+ - 1.9.3
6
+ notifications:
7
+ email: false
8
+ bundler_args: --without development
data/Gemfile CHANGED
@@ -1,8 +1,15 @@
1
1
  source :rubygems
2
2
  gemspec
3
3
 
4
- gem 'rake', '~> 0.8.7'
4
+ gem 'rake'
5
5
  gem 'cucumber', '~> 0.7'
6
6
  gem 'fakeweb', '~> 1.2'
7
7
  gem 'rspec', '~> 1.3'
8
8
  gem 'mongrel', '1.2.0.pre2'
9
+ gem 'multi_json', '~> 1.3'
10
+
11
+ group :development do
12
+ gem 'guard'
13
+ gem 'guard-rspec'
14
+ gem 'guard-bundler'
15
+ end
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ rspec_options = {
2
+ :version => 1,
3
+ :all_after_pass => false,
4
+ :all_on_start => false,
5
+ }
6
+
7
+ guard 'rspec', rspec_options do
8
+ watch(%r{^spec/.+_spec\.rb$})
9
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
+ watch('spec/spec_helper.rb') { "spec" }
11
+ end
12
+
13
+ guard 'bundler' do
14
+ watch('Gemfile')
15
+ watch(/^.+\.gemspec/)
16
+ end
data/History CHANGED
@@ -1,3 +1,37 @@
1
+ == 0.9.0 2012-09-07
2
+ * new
3
+ * [support for connection adapters](https://github.com/jnunemaker/httparty/pull/157)
4
+ * [allow ssl_version on ruby 1.9](https://github.com/jnunemaker/httparty/pull/159)
5
+
6
+ * bug fixes
7
+ * [don't treat port 4430 as ssl](https://github.com/jnunemaker/httparty/commit/a296b1c97f83d7dcc6ef85720a43664c265685ac)
8
+ * [deep clone default options](https://github.com/jnunemaker/httparty/commit/f74227d30f9389b4b23a888c9af49fb9b8248e1f)
9
+ * a few net digest auth fixes
10
+
11
+ == 0.8.3 2012-04-21
12
+ * new
13
+ * [lazy parsing of responses](https://github.com/jnunemaker/httparty/commit/9fd5259c8dab00e426082b66af44ede2c9068f45)
14
+ * [add support for PATCH requests](https://github.com/jnunemaker/httparty/commit/7ab6641e37a9e31517e46f6124f38c615395d38a)
15
+ * bug fixes
16
+ * [subclasses no longer override superclass options](https://github.com/jnunemaker/httparty/commit/682af8fbf672e7b3009e650da776c85cdfe78d39)
17
+
18
+ == 0.8.2 2012-04-12
19
+ * new
20
+ * add -r to make CLI return failure code if status >= 400
21
+ * allow blank username from CLI
22
+ * bug fixes
23
+ * return nil for null body
24
+ * automatically deflate responses with a Content-Encoding: x-gzip header
25
+ * Do not HEAD on POST request with digest authentication
26
+ * add support for proxy authentication
27
+ * fix posting data with CLI
28
+ * require rexml/document if xml format from CLI
29
+ * support for fragmented responses
30
+
31
+ == 0.8.1 2011-10-05
32
+ * bug fixes
33
+ * content-encoding header should be removed when automatically inflating the body
34
+
1
35
  == 0.8.0 2011-09-13
2
36
  * new
3
37
  * switch to multi json/xml for parsing by default
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # httparty
2
+
3
+ Makes http fun again!
4
+
5
+ ## Install
6
+
7
+ ```
8
+ gem install httparty
9
+ ```
10
+
11
+ ## Requirements
12
+
13
+ * multi_json and multi_xml
14
+ * You like to party!
15
+
16
+ ## Examples
17
+
18
+ ```ruby
19
+ # Use the class methods to get down to business quickly
20
+ response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
21
+ puts response.body, response.code, response.message, response.headers.inspect
22
+
23
+ response.each do |item|
24
+ puts item['user']['screen_name']
25
+ end
26
+
27
+ # Or wrap things up in your own class
28
+ class Twitter
29
+ include HTTParty
30
+ base_uri 'twitter.com'
31
+
32
+ def initialize(u, p)
33
+ @auth = {:username => u, :password => p}
34
+ end
35
+
36
+ # which can be :friends, :user or :public
37
+ # options[:query] can be things like since, since_id, count, etc.
38
+ def timeline(which=:friends, options={})
39
+ options.merge!({:basic_auth => @auth})
40
+ self.class.get("/statuses/#{which}_timeline.json", options)
41
+ end
42
+
43
+ def post(text)
44
+ options = { :body => {:status => text}, :basic_auth => @auth }
45
+ self.class.post('/statuses/update.json', options)
46
+ end
47
+ end
48
+
49
+ twitter = Twitter.new(config['email'], config['password'])
50
+ pp twitter.timeline
51
+ ```
52
+
53
+ See the [examples directory](http://github.com/jnunemaker/httparty/tree/master/examples) for even more goodies.
54
+
55
+ ## Command Line Interface
56
+
57
+ httparty also includes the executable `httparty` which can be
58
+ used to query web services and examine the resulting output. By default
59
+ it will output the response as a pretty-printed Ruby object (useful for
60
+ grokking the structure of output). This can also be overridden to output
61
+ formatted XML or JSON. Execute `httparty --help` for all the
62
+ options. Below is an example of how easy it is.
63
+
64
+ ```
65
+ httparty "http://twitter.com/statuses/public_timeline.json"
66
+ ```
67
+
68
+ ## Help and Docs
69
+
70
+ * https://groups.google.com/forum/#!forum/httparty-gem
71
+ * http://rdoc.info/projects/jnunemaker/httparty
72
+
73
+ ## Contributing
74
+
75
+ * Fork the project.
76
+ * Make your feature addition or bug fix.
77
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
78
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
79
+ * Send me a pull request. Bonus points for topic branches.
data/bin/httparty CHANGED
@@ -32,13 +32,13 @@ OptionParser.new do |o|
32
32
  "--data [BODY]",
33
33
  "Data to put in request body (prefix with '@' for file)") do |d|
34
34
  if d =~ /^@/
35
- opts[:data] = open(d[1..-1]).read
35
+ opts[:body] = open(d[1..-1]).read
36
36
  else
37
- opts[:data] = d
37
+ opts[:body] = d
38
38
  end
39
39
  end
40
40
 
41
- o.on("-H", "--header [NAME=VALUE]", "Additional HTTP headers in NAME=VALUE form") do |h|
41
+ o.on("-H", "--header [NAME:VALUE]", "Additional HTTP headers in NAME:VALUE form") do |h|
42
42
  abort "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/
43
43
  name, value = h.split(':')
44
44
  opts[:headers][name.strip] = value.strip
@@ -49,11 +49,15 @@ OptionParser.new do |o|
49
49
  end
50
50
 
51
51
  o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u|
52
- abort "Invalid credentials format. Must be user:password" unless u =~ /.+:.+/
52
+ abort "Invalid credentials format. Must be user:password" unless u =~ /.*:.+/
53
53
  user, password = u.split(':')
54
54
  opts[:basic_auth] = { :username => user, :password => password }
55
55
  end
56
56
 
57
+ o.on("-r", "--response-code", "Command fails if response code >= 400") do
58
+ opts[:response_code] = true
59
+ end
60
+
57
61
  o.on("-h", "--help", "Show help documentation") do |h|
58
62
  puts o
59
63
  exit
@@ -100,9 +104,11 @@ else
100
104
  puts YAML.dump(response.delegate)
101
105
  end
102
106
  when :xml
107
+ require 'rexml/document'
103
108
  REXML::Document.new(response.body).write(STDOUT, 2)
104
109
  puts
105
110
  else
106
111
  puts response
107
112
  end
108
113
  end
114
+ exit false if opts[:response_code] && response.code >= 400
data/cucumber.yml CHANGED
@@ -1 +1 @@
1
- default: features
1
+ default: features --format progress
data/examples/crack.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'crack'
3
+
4
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require File.join(dir, 'httparty')
6
+ require 'pp'
7
+
8
+ class Rep
9
+ include HTTParty
10
+
11
+ parser(
12
+ Proc.new do |body, format|
13
+ Crack::XML.parse(body)
14
+ end
15
+ )
16
+ end
17
+
18
+ pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544')
19
+ pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php', :query => {:zip => 46544})
@@ -0,0 +1,6 @@
1
+ # To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below.
2
+
3
+ require 'httparty'
4
+
5
+ APPLICATION_NAME = "Httparty"
6
+ response = HTTParty.get('http://example.com', :headers => {"User-Agent" => APPLICATION_NAME})
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+
5
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require File.join(dir, 'httparty')
7
+ require 'pp'
8
+
9
+ class HtmlParserIncluded < HTTParty::Parser
10
+ SupportedFormats.merge!('text/html' => :html)
11
+
12
+ def html
13
+ Nokogiri::HTML(body)
14
+ end
15
+ end
16
+
17
+ class Page
18
+ include HTTParty
19
+ parser HtmlParserIncluded
20
+ end
21
+
22
+ pp Page.get('http://www.google.com')
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  Given /^that service takes (\d+) seconds to generate a response$/ do |time|
16
16
  @server_response_time = time.to_i
17
- @handler.preprocessor = lambda { sleep time.to_i }
17
+ @handler.preprocessor = Proc.new { sleep time.to_i }
18
18
  end
19
19
 
20
20
  Given /^a remote deflate service$/ do
data/httparty.gemspec CHANGED
@@ -8,11 +8,11 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["John Nunemaker", "Sandro Turriate"]
10
10
  s.email = ["nunemaker@gmail.com"]
11
- s.homepage = "http://httparty.rubyforge.org/"
11
+ s.homepage = "http://jnunemaker.github.com/httparty"
12
12
  s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
13
13
  s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
14
14
 
15
- s.add_dependency 'multi_json'
15
+ s.add_dependency 'multi_json', "~> 1.0"
16
16
  s.add_dependency 'multi_xml'
17
17
 
18
18
  s.post_install_message = "When you HTTParty, you must party hard!"
data/lib/httparty.rb CHANGED
@@ -10,6 +10,7 @@ require 'httparty/module_inheritable_attributes'
10
10
  require 'httparty/cookie_hash'
11
11
  require 'httparty/net_digest_auth'
12
12
  require 'httparty/version'
13
+ require 'httparty/connection_adapter'
13
14
 
14
15
  # @see HTTParty::ClassMethods
15
16
  module HTTParty
@@ -36,11 +37,13 @@ module HTTParty
36
37
  end
37
38
 
38
39
  # == Common Request Options
39
- # Request methods (get, post, put, delete, head, options) all take a common set of options. These are:
40
+ # Request methods (get, post, patch, put, delete, head, options) all take a common set of options. These are:
40
41
  #
41
42
  # [:+body+:] Body of the request. If passed a Hash, will try to normalize it first, by default passing it to ActiveSupport::to_params. Any other kind of object will get used as-is.
42
43
  # [:+http_proxyaddr+:] Address of proxy server to use.
43
44
  # [:+http_proxyport+:] Port of proxy server to use.
45
+ # [:+http_proxyuser+:] User for proxy server authentication.
46
+ # [:+http_proxypass+:] Password for proxy server authentication.
44
47
  # [:+limit+:] Maximum number of redirects to follow. Takes precedences over :+no_follow+.
45
48
  # [:+query+:] Query string, or a Hash representing it. Normalized according to the same rules as :+body+. If you specify this on a POST, you must use a Hash. See also HTTParty::ClassMethods.default_params.
46
49
  # [:+timeout+:] Timeout for opening connection and reading data.
@@ -55,9 +58,11 @@ module HTTParty
55
58
  # * :+maintain_method_across_redirects+: see HTTParty::ClassMethods.maintain_method_across_redirects.
56
59
  # * :+no_follow+: see HTTParty::ClassMethods.no_follow.
57
60
  # * :+parser+: see HTTParty::ClassMethods.parser.
61
+ # * :+connection_adapter+: see HTTParty::ClassMethods.connection_adapter.
58
62
  # * :+pem+: see HTTParty::ClassMethods.pem.
59
63
  # * :+query_string_normalizer+: see HTTParty::ClassMethods.query_string_normalizer
60
64
  # * :+ssl_ca_file+: see HTTParty::ClassMethods.ssl_ca_file.
65
+ # * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path.
61
66
 
62
67
  module ClassMethods
63
68
 
@@ -67,11 +72,13 @@ module HTTParty
67
72
  #
68
73
  # class Foo
69
74
  # include HTTParty
70
- # http_proxy 'http://foo.com', 80
75
+ # http_proxy 'http://foo.com', 80, 'user', 'pass'
71
76
  # end
72
- def http_proxy(addr=nil, port = nil)
77
+ def http_proxy(addr=nil, port=nil, user=nil, pass=nil)
73
78
  default_options[:http_proxyaddr] = addr
74
79
  default_options[:http_proxyport] = port
80
+ default_options[:http_proxyuser] = user
81
+ default_options[:http_proxypass] = pass
75
82
  end
76
83
 
77
84
  # Allows setting a base uri to be used for each request.
@@ -292,6 +299,17 @@ module HTTParty
292
299
  default_options[:query_string_normalizer] = normalizer
293
300
  end
294
301
 
302
+ # Allows setting of SSL version to use. This only works in Ruby 1.9.
303
+ # You can get a list of valid versions from OpenSSL::SSL::SSLContext::METHODS.
304
+ #
305
+ # class Foo
306
+ # include HTTParty
307
+ # ssl_version :SSLv3
308
+ # end
309
+ def ssl_version(version)
310
+ default_options[:ssl_version] = version
311
+ end
312
+
295
313
  # Allows setting an OpenSSL certificate authority file
296
314
  #
297
315
  # class Foo
@@ -327,6 +345,30 @@ module HTTParty
327
345
  end
328
346
  end
329
347
 
348
+ # Allows setting a custom connection_adapter for the http connections
349
+ #
350
+ # @example
351
+ # class Foo
352
+ # include HTTParty
353
+ # connection_adapter Proc.new {|uri, options| ... }
354
+ # end
355
+ #
356
+ # @example provide optional configuration for your connection_adapter
357
+ # class Foo
358
+ # include HTTParty
359
+ # connection_adapter Proc.new {|uri, options| ... }, {:foo => :bar}
360
+ # end
361
+ #
362
+ # @see HTTParty::ConnectionAdapter
363
+ def connection_adapter(custom_adapter = nil, options = nil)
364
+ if custom_adapter.nil?
365
+ default_options[:connection_adapter]
366
+ else
367
+ default_options[:connection_adapter] = custom_adapter
368
+ default_options[:connection_adapter_options] = options
369
+ end
370
+ end
371
+
330
372
  # Allows making a get request to a url.
331
373
  #
332
374
  # class Foo
@@ -339,8 +381,8 @@ module HTTParty
339
381
  # # Simple get with full url and query parameters
340
382
  # # ie: http://foo.com/resource.json?limit=10
341
383
  # Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
342
- def get(path, options={})
343
- perform_request Net::HTTP::Get, path, options
384
+ def get(path, options={}, &block)
385
+ perform_request Net::HTTP::Get, path, options, &block
344
386
  end
345
387
 
346
388
  # Allows making a post request to a url.
@@ -355,28 +397,33 @@ module HTTParty
355
397
  # # Simple post with full url using :query option,
356
398
  # # which gets set as form data on the request.
357
399
  # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
358
- def post(path, options={})
359
- perform_request Net::HTTP::Post, path, options
400
+ def post(path, options={}, &block)
401
+ perform_request Net::HTTP::Post, path, options, &block
402
+ end
403
+
404
+ # Perform a PATCH request to a path
405
+ def patch(path, options={}, &block)
406
+ perform_request Net::HTTP::Patch, path, options, &block
360
407
  end
361
408
 
362
409
  # Perform a PUT request to a path
363
- def put(path, options={})
364
- perform_request Net::HTTP::Put, path, options
410
+ def put(path, options={}, &block)
411
+ perform_request Net::HTTP::Put, path, options, &block
365
412
  end
366
413
 
367
414
  # Perform a DELETE request to a path
368
- def delete(path, options={})
369
- perform_request Net::HTTP::Delete, path, options
415
+ def delete(path, options={}, &block)
416
+ perform_request Net::HTTP::Delete, path, options, &block
370
417
  end
371
418
 
372
419
  # Perform a HEAD request to a path
373
- def head(path, options={})
374
- perform_request Net::HTTP::Head, path, options
420
+ def head(path, options={}, &block)
421
+ perform_request Net::HTTP::Head, path, options, &block
375
422
  end
376
423
 
377
424
  # Perform an OPTIONS request to a path
378
- def options(path, options={})
379
- perform_request Net::HTTP::Options, path, options
425
+ def options(path, options={}, &block)
426
+ perform_request Net::HTTP::Options, path, options, &block
380
427
  end
381
428
 
382
429
  def default_options #:nodoc:
@@ -385,10 +432,10 @@ module HTTParty
385
432
 
386
433
  private
387
434
 
388
- def perform_request(http_method, path, options) #:nodoc:
435
+ def perform_request(http_method, path, options, &block) #:nodoc:
389
436
  options = default_options.dup.merge(options)
390
437
  process_cookies(options)
391
- Request.new(http_method, path, options).perform
438
+ Request.new(http_method, path, options).perform(&block)
392
439
  end
393
440
 
394
441
  def process_cookies(options) #:nodoc:
@@ -406,7 +453,7 @@ module HTTParty
406
453
 
407
454
  def self.normalize_base_uri(url) #:nodoc:
408
455
  normalized_url = url.dup
409
- use_ssl = (normalized_url =~ /^https/) || normalized_url.include?(':443')
456
+ use_ssl = (normalized_url =~ /^https/) || (normalized_url =~ /:443\b/)
410
457
  ends_with_slash = normalized_url =~ /\/$/
411
458
 
412
459
  normalized_url.chop! if ends_with_slash
@@ -419,28 +466,32 @@ module HTTParty
419
466
  include HTTParty
420
467
  end
421
468
 
422
- def self.get(*args)
423
- Basement.get(*args)
469
+ def self.get(*args, &block)
470
+ Basement.get(*args, &block)
471
+ end
472
+
473
+ def self.post(*args, &block)
474
+ Basement.post(*args, &block)
424
475
  end
425
476
 
426
- def self.post(*args)
427
- Basement.post(*args)
477
+ def self.patch(*args, &block)
478
+ Basement.patch(*args, &block)
428
479
  end
429
480
 
430
- def self.put(*args)
431
- Basement.put(*args)
481
+ def self.put(*args, &block)
482
+ Basement.put(*args, &block)
432
483
  end
433
484
 
434
- def self.delete(*args)
435
- Basement.delete(*args)
485
+ def self.delete(*args, &block)
486
+ Basement.delete(*args, &block)
436
487
  end
437
488
 
438
- def self.head(*args)
439
- Basement.head(*args)
489
+ def self.head(*args, &block)
490
+ Basement.head(*args, &block)
440
491
  end
441
492
 
442
- def self.options(*args)
443
- Basement.options(*args)
493
+ def self.options(*args, &block)
494
+ Basement.options(*args, &block)
444
495
  end
445
496
  end
446
497