httparty 0.8.0 → 0.8.3
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 +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +8 -1
- data/Guardfile +16 -0
- data/History +24 -0
- data/README.rdoc +11 -18
- data/bin/httparty +9 -3
- data/cucumber.yml +1 -1
- data/examples/crack.rb +19 -0
- data/examples/headers_and_user_agents.rb +6 -0
- data/examples/nokogiri_html_parser.rb +22 -0
- data/features/steps/remote_service_steps.rb +1 -1
- data/httparty.gemspec +1 -1
- data/lib/httparty.rb +42 -29
- data/lib/httparty/cookie_hash.rb +2 -2
- data/lib/httparty/core_extensions.rb +23 -0
- data/lib/httparty/hash_conversions.rb +1 -1
- data/lib/httparty/module_inheritable_attributes.rb +1 -1
- data/lib/httparty/parser.rb +8 -4
- data/lib/httparty/request.rb +30 -10
- data/lib/httparty/response.rb +17 -40
- data/lib/httparty/response/headers.rb +31 -0
- data/lib/httparty/version.rb +1 -1
- data/spec/httparty/cookie_hash_spec.rb +3 -4
- data/spec/httparty/net_digest_auth_spec.rb +8 -11
- data/spec/httparty/parser_spec.rb +16 -0
- data/spec/httparty/request_spec.rb +80 -1
- data/spec/httparty/response_spec.rb +41 -20
- data/spec/httparty/ssl_spec.rb +13 -5
- data/spec/httparty_spec.rb +40 -2
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/ssl_test_helper.rb +28 -6
- data/spec/support/ssl_test_server.rb +19 -8
- data/spec/support/stub_response.rb +13 -0
- metadata +19 -12
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
source :rubygems
|
2
2
|
gemspec
|
3
3
|
|
4
|
-
gem 'rake'
|
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,27 @@
|
|
1
|
+
== 0.8.3 2012-04-21
|
2
|
+
* new
|
3
|
+
* [lazy parsing of responses](https://github.com/jnunemaker/httparty/commit/9fd5259c8dab00e426082b66af44ede2c9068f45)
|
4
|
+
* [add support for PATCH requests](https://github.com/jnunemaker/httparty/commit/7ab6641e37a9e31517e46f6124f38c615395d38a)
|
5
|
+
* bug fixes
|
6
|
+
* [subclasses no longer override superclass options](https://github.com/jnunemaker/httparty/commit/682af8fbf672e7b3009e650da776c85cdfe78d39)
|
7
|
+
|
8
|
+
== 0.8.2 2012-04-12
|
9
|
+
* new
|
10
|
+
* add -r to make CLI return failure code if status >= 400
|
11
|
+
* allow blank username from CLI
|
12
|
+
* bug fixes
|
13
|
+
* return nil for null body
|
14
|
+
* automatically deflate responses with a Content-Encoding: x-gzip header
|
15
|
+
* Do not HEAD on POST request with digest authentication
|
16
|
+
* add support for proxy authentication
|
17
|
+
* fix posting data with CLI
|
18
|
+
* require rexml/document if xml format from CLI
|
19
|
+
* support for fragmented responses
|
20
|
+
|
21
|
+
== 0.8.1 2011-10-05
|
22
|
+
* bug fixes
|
23
|
+
* content-encoding header should be removed when automatically inflating the body
|
24
|
+
|
1
25
|
== 0.8.0 2011-09-13
|
2
26
|
* new
|
3
27
|
* switch to multi json/xml for parsing by default
|
data/README.rdoc
CHANGED
@@ -2,22 +2,6 @@
|
|
2
2
|
|
3
3
|
Makes http fun again!
|
4
4
|
|
5
|
-
== Note on Releases
|
6
|
-
|
7
|
-
Releases are tagged on github and also released as gems on github and rubyforge. Master is pushed to whenever I add a patch or a new feature. To build from master, you can clone the code, generate the updated gemspec, build the gem and install.
|
8
|
-
|
9
|
-
* rake gemspec
|
10
|
-
* gem build httparty.gemspec
|
11
|
-
* gem install the gem that was built
|
12
|
-
|
13
|
-
== Note on Patches/Pull Requests
|
14
|
-
|
15
|
-
* Fork the project.
|
16
|
-
* Make your feature addition or bug fix.
|
17
|
-
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
18
|
-
* 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)
|
19
|
-
* Send me a pull request. Bonus points for topic branches.
|
20
|
-
|
21
5
|
== Features:
|
22
6
|
|
23
7
|
* Easy get, post requests
|
@@ -29,6 +13,14 @@ Releases are tagged on github and also released as gems on github and rubyforge.
|
|
29
13
|
|
30
14
|
See http://github.com/jnunemaker/httparty/tree/master/examples
|
31
15
|
|
16
|
+
== Note on Patches/Pull Requests
|
17
|
+
|
18
|
+
* Fork the project.
|
19
|
+
* Make your feature addition or bug fix.
|
20
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
21
|
+
* 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)
|
22
|
+
* Send me a pull request. Bonus points for topic branches.
|
23
|
+
|
32
24
|
== Command Line Interface
|
33
25
|
|
34
26
|
httparty also includes the executable <tt>httparty</tt> which can be
|
@@ -49,6 +41,7 @@ options. Below is an example of how easy it is.
|
|
49
41
|
|
50
42
|
* sudo gem install httparty
|
51
43
|
|
52
|
-
== Docs
|
44
|
+
== Help and Docs
|
53
45
|
|
54
|
-
|
46
|
+
* https://groups.google.com/forum/#!forum/httparty-gem
|
47
|
+
* http://rdoc.info/projects/jnunemaker/httparty
|
data/bin/httparty
CHANGED
@@ -32,9 +32,9 @@ 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[:
|
35
|
+
opts[:body] = open(d[1..-1]).read
|
36
36
|
else
|
37
|
-
opts[:
|
37
|
+
opts[:body] = d
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -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 =
|
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
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
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
@@ -36,11 +36,13 @@ module HTTParty
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# == Common Request Options
|
39
|
-
# Request methods (get, post, put, delete, head, options) all take a common set of options. These are:
|
39
|
+
# Request methods (get, post, patch, put, delete, head, options) all take a common set of options. These are:
|
40
40
|
#
|
41
41
|
# [:+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
42
|
# [:+http_proxyaddr+:] Address of proxy server to use.
|
43
43
|
# [:+http_proxyport+:] Port of proxy server to use.
|
44
|
+
# [:+http_proxyuser+:] User for proxy server authentication.
|
45
|
+
# [:+http_proxypass+:] Password for proxy server authentication.
|
44
46
|
# [:+limit+:] Maximum number of redirects to follow. Takes precedences over :+no_follow+.
|
45
47
|
# [:+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
48
|
# [:+timeout+:] Timeout for opening connection and reading data.
|
@@ -67,11 +69,13 @@ module HTTParty
|
|
67
69
|
#
|
68
70
|
# class Foo
|
69
71
|
# include HTTParty
|
70
|
-
# http_proxy 'http://foo.com', 80
|
72
|
+
# http_proxy 'http://foo.com', 80, 'user', 'pass'
|
71
73
|
# end
|
72
|
-
def http_proxy(addr=nil, port = nil)
|
74
|
+
def http_proxy(addr=nil, port=nil, user=nil, pass=nil)
|
73
75
|
default_options[:http_proxyaddr] = addr
|
74
76
|
default_options[:http_proxyport] = port
|
77
|
+
default_options[:http_proxyuser] = user
|
78
|
+
default_options[:http_proxypass] = pass
|
75
79
|
end
|
76
80
|
|
77
81
|
# Allows setting a base uri to be used for each request.
|
@@ -339,8 +343,8 @@ module HTTParty
|
|
339
343
|
# # Simple get with full url and query parameters
|
340
344
|
# # ie: http://foo.com/resource.json?limit=10
|
341
345
|
# Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
|
342
|
-
def get(path, options={})
|
343
|
-
perform_request Net::HTTP::Get, path, options
|
346
|
+
def get(path, options={}, &block)
|
347
|
+
perform_request Net::HTTP::Get, path, options, &block
|
344
348
|
end
|
345
349
|
|
346
350
|
# Allows making a post request to a url.
|
@@ -355,28 +359,33 @@ module HTTParty
|
|
355
359
|
# # Simple post with full url using :query option,
|
356
360
|
# # which gets set as form data on the request.
|
357
361
|
# Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
|
358
|
-
def post(path, options={})
|
359
|
-
perform_request Net::HTTP::Post, path, options
|
362
|
+
def post(path, options={}, &block)
|
363
|
+
perform_request Net::HTTP::Post, path, options, &block
|
364
|
+
end
|
365
|
+
|
366
|
+
# Perform a PATCH request to a path
|
367
|
+
def patch(path, options={}, &block)
|
368
|
+
perform_request Net::HTTP::Patch, path, options, &block
|
360
369
|
end
|
361
370
|
|
362
371
|
# Perform a PUT request to a path
|
363
|
-
def put(path, options={})
|
364
|
-
perform_request Net::HTTP::Put, path, options
|
372
|
+
def put(path, options={}, &block)
|
373
|
+
perform_request Net::HTTP::Put, path, options, &block
|
365
374
|
end
|
366
375
|
|
367
376
|
# Perform a DELETE request to a path
|
368
|
-
def delete(path, options={})
|
369
|
-
perform_request Net::HTTP::Delete, path, options
|
377
|
+
def delete(path, options={}, &block)
|
378
|
+
perform_request Net::HTTP::Delete, path, options, &block
|
370
379
|
end
|
371
380
|
|
372
381
|
# Perform a HEAD request to a path
|
373
|
-
def head(path, options={})
|
374
|
-
perform_request Net::HTTP::Head, path, options
|
382
|
+
def head(path, options={}, &block)
|
383
|
+
perform_request Net::HTTP::Head, path, options, &block
|
375
384
|
end
|
376
385
|
|
377
386
|
# Perform an OPTIONS request to a path
|
378
|
-
def options(path, options={})
|
379
|
-
perform_request Net::HTTP::Options, path, options
|
387
|
+
def options(path, options={}, &block)
|
388
|
+
perform_request Net::HTTP::Options, path, options, &block
|
380
389
|
end
|
381
390
|
|
382
391
|
def default_options #:nodoc:
|
@@ -385,10 +394,10 @@ module HTTParty
|
|
385
394
|
|
386
395
|
private
|
387
396
|
|
388
|
-
def perform_request(http_method, path, options) #:nodoc:
|
397
|
+
def perform_request(http_method, path, options, &block) #:nodoc:
|
389
398
|
options = default_options.dup.merge(options)
|
390
399
|
process_cookies(options)
|
391
|
-
Request.new(http_method, path, options).perform
|
400
|
+
Request.new(http_method, path, options).perform(&block)
|
392
401
|
end
|
393
402
|
|
394
403
|
def process_cookies(options) #:nodoc:
|
@@ -419,28 +428,32 @@ module HTTParty
|
|
419
428
|
include HTTParty
|
420
429
|
end
|
421
430
|
|
422
|
-
def self.get(*args)
|
423
|
-
Basement.get(*args)
|
431
|
+
def self.get(*args, &block)
|
432
|
+
Basement.get(*args, &block)
|
433
|
+
end
|
434
|
+
|
435
|
+
def self.post(*args, &block)
|
436
|
+
Basement.post(*args, &block)
|
424
437
|
end
|
425
438
|
|
426
|
-
def self.
|
427
|
-
Basement.
|
439
|
+
def self.patch(*args, &block)
|
440
|
+
Basement.patch(*args, &block)
|
428
441
|
end
|
429
442
|
|
430
|
-
def self.put(*args)
|
431
|
-
Basement.put(*args)
|
443
|
+
def self.put(*args, &block)
|
444
|
+
Basement.put(*args, &block)
|
432
445
|
end
|
433
446
|
|
434
|
-
def self.delete(*args)
|
435
|
-
Basement.delete(*args)
|
447
|
+
def self.delete(*args, &block)
|
448
|
+
Basement.delete(*args, &block)
|
436
449
|
end
|
437
450
|
|
438
|
-
def self.head(*args)
|
439
|
-
Basement.head(*args)
|
451
|
+
def self.head(*args, &block)
|
452
|
+
Basement.head(*args, &block)
|
440
453
|
end
|
441
454
|
|
442
|
-
def self.options(*args)
|
443
|
-
Basement.options(*args)
|
455
|
+
def self.options(*args, &block)
|
456
|
+
Basement.options(*args, &block)
|
444
457
|
end
|
445
458
|
end
|
446
459
|
|
data/lib/httparty/cookie_hash.rb
CHANGED
@@ -6,4 +6,27 @@ module HTTParty
|
|
6
6
|
instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval/ }
|
7
7
|
end
|
8
8
|
end
|
9
|
+
|
10
|
+
unless defined?(Net::HTTP::Patch)
|
11
|
+
class Net::HTTP
|
12
|
+
def patch(path, data, initheader = nil, dest = nil, &block) #:nodoc:
|
13
|
+
res = nil
|
14
|
+
request(Patch.new(path, initheader), data) {|r|
|
15
|
+
r.read_body dest, &block
|
16
|
+
res = r
|
17
|
+
}
|
18
|
+
unless @newimpl
|
19
|
+
res.value
|
20
|
+
return res, res.body
|
21
|
+
end
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
class Patch < Net::HTTPRequest
|
26
|
+
METHOD = 'PATCH'
|
27
|
+
REQUEST_HAS_BODY = true
|
28
|
+
RESPONSE_HAS_BODY = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
9
32
|
end
|
@@ -22,7 +22,7 @@ module HTTParty
|
|
22
22
|
if instance_variable_get(ivar).respond_to?(:merge)
|
23
23
|
method = <<-EOM
|
24
24
|
def self.#{inheritable_attribute}
|
25
|
-
#{ivar} = superclass.#{inheritable_attribute}.merge #{ivar}
|
25
|
+
#{ivar} = superclass.#{inheritable_attribute}.merge Marshal.load(Marshal.dump(#{ivar}))
|
26
26
|
end
|
27
27
|
EOM
|
28
28
|
subclass.class_eval method
|