httparty 0.4.4 → 0.4.5
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 +6 -0
- data/History +11 -1
- data/README.rdoc +1 -1
- data/Rakefile +71 -48
- data/VERSION +1 -0
- data/bin/httparty +1 -1
- data/features/steps/env.rb +1 -0
- data/features/steps/httparty_response_steps.rb +2 -2
- data/features/steps/httparty_steps.rb +6 -2
- data/features/steps/mongrel_helper.rb +2 -1
- data/features/steps/remote_service_steps.rb +5 -0
- data/features/supports_timeout_option.feature +12 -0
- data/httparty.gemspec +79 -10
- data/lib/httparty.rb +25 -15
- data/lib/httparty/cookie_hash.rb +16 -3
- data/lib/httparty/core_extensions.rb +3 -7
- data/lib/httparty/request.rb +41 -7
- data/lib/httparty/response.rb +1 -1
- data/spec/httparty/cookie_hash_spec.rb +42 -9
- data/spec/httparty/request_spec.rb +46 -1
- data/spec/httparty_spec.rb +40 -2
- data/spec/spec.opts +1 -2
- data/spec/spec_helper.rb +6 -3
- data/website/index.html +35 -36
- metadata +34 -32
data/History
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.4.5 2009-09-12
|
2
|
+
* bug fixes
|
3
|
+
* Fixed class-level headers overwritten by cookie management code. Closes #19
|
4
|
+
* Fixed "superclass mismatch for class BlankSlate" error. Closes #20
|
5
|
+
* Fixed reading files as post data from the command line (vesan)
|
6
|
+
* minor enhancements
|
7
|
+
* Timeout option added; will raise a Timeout::Error after the timeout has elapsed (attack). Closes #17
|
8
|
+
HTTParty.get "http://github.com", :timeout => 1
|
9
|
+
* Building gem with Jeweler
|
10
|
+
|
1
11
|
== 0.4.4 2009-07-19
|
2
12
|
* 2 minor update
|
3
13
|
* :query no longer sets form data. Use body and set content type to application/x-www-form-urlencoded if you need it. :query was wrong for that.
|
@@ -128,4 +138,4 @@
|
|
128
138
|
== 0.1.0 2008-07-27
|
129
139
|
|
130
140
|
* 1 major enhancement:
|
131
|
-
* Initial release
|
141
|
+
* Initial release
|
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ Makes http fun again!
|
|
6
6
|
|
7
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
8
|
|
9
|
-
* rake
|
9
|
+
* rake gemspec
|
10
10
|
* gem build httparty.gemspec
|
11
11
|
* gem install the gem that was built
|
12
12
|
|
data/Rakefile
CHANGED
@@ -1,48 +1,71 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "httparty"
|
8
|
+
gem.summary = %Q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
9
|
+
gem.description = %Q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
10
|
+
gem.email = "nunemaker@gmail.com"
|
11
|
+
gem.homepage = "http://httparty.rubyforge.org"
|
12
|
+
gem.authors = ["John Nunemaker", "Sandro Turriate"]
|
13
|
+
gem.add_dependency 'crack', '>= 0.1.1'
|
14
|
+
gem.add_development_dependency "rspec", "1.2.8"
|
15
|
+
gem.post_install_message = "When you HTTParty, you must party hard!"
|
16
|
+
gem.rubyforge_project = 'httparty'
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
20
|
+
rubyforge.doc_task = "rdoc"
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'spec/rake/spectask'
|
27
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
30
|
+
spec.spec_opts = ['--options', 'spec/spec.opts']
|
31
|
+
end
|
32
|
+
|
33
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
34
|
+
spec.libs << 'lib' << 'spec'
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :spec => :check_dependencies
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'cucumber/rake/task'
|
43
|
+
Cucumber::Rake::Task.new(:features)
|
44
|
+
|
45
|
+
task :features => :check_dependencies
|
46
|
+
rescue LoadError
|
47
|
+
task :features do
|
48
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :default => [:spec, :features]
|
53
|
+
|
54
|
+
require 'rake/rdoctask'
|
55
|
+
Rake::RDocTask.new do |rdoc|
|
56
|
+
if File.exist?('VERSION')
|
57
|
+
version = File.read('VERSION')
|
58
|
+
else
|
59
|
+
version = ""
|
60
|
+
end
|
61
|
+
|
62
|
+
rdoc.rdoc_dir = 'rdoc'
|
63
|
+
rdoc.title = "httparty #{version}"
|
64
|
+
rdoc.rdoc_files.include('README*')
|
65
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Upload website files to rubyforge'
|
69
|
+
task :website do
|
70
|
+
sh %{rsync -av website/ jnunemaker@rubyforge.org:/var/www/gforge-projects/httparty}
|
71
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.5
|
data/bin/httparty
CHANGED
data/features/steps/env.rb
CHANGED
@@ -20,7 +20,7 @@ Then /it should return a response with a (\d+) response code/ do |code|
|
|
20
20
|
@response_from_httparty.code.should eql(code.to_i)
|
21
21
|
end
|
22
22
|
|
23
|
-
Then /it should raise an
|
23
|
+
Then /it should raise (?:an|a) ([\w:]+) exception/ do |exception|
|
24
24
|
@exception_from_httparty.should_not be_nil
|
25
|
-
@exception_from_httparty.class.should eql(
|
25
|
+
@exception_from_httparty.class.name.should eql(exception)
|
26
26
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
When /^I set my HTTParty timeout option to (\d+)$/ do |timeout|
|
2
|
+
@request_options[:timeout] = timeout.to_i
|
3
|
+
end
|
4
|
+
|
1
5
|
When /I call HTTParty#get with '(.*)'$/ do |url|
|
2
6
|
begin
|
3
|
-
@response_from_httparty = HTTParty.get("http://#{@host_and_port}#{url}")
|
4
|
-
rescue HTTParty::RedirectionTooDeep => e
|
7
|
+
@response_from_httparty = HTTParty.get("http://#{@host_and_port}#{url}", @request_options)
|
8
|
+
rescue HTTParty::RedirectionTooDeep, Timeout::Error => e
|
5
9
|
@exception_from_httparty = e
|
6
10
|
end
|
7
11
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
def basic_mongrel_handler
|
2
2
|
Class.new(Mongrel::HttpHandler) do
|
3
|
-
attr_writer :content_type, :response_body, :response_code
|
3
|
+
attr_writer :content_type, :response_body, :response_code, :preprocessor
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@content_type = "text/html"
|
@@ -10,6 +10,7 @@ def basic_mongrel_handler
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def process(request, response)
|
13
|
+
instance_eval &@preprocessor if @preprocessor
|
13
14
|
reply_with(response, @response_code, @response_body)
|
14
15
|
end
|
15
16
|
|
@@ -12,6 +12,11 @@ Given /that service is accessed at the path '(.*)'/ do |path|
|
|
12
12
|
@server.register(path, @handler)
|
13
13
|
end
|
14
14
|
|
15
|
+
Given /^that service takes (\d+) seconds to generate a response$/ do |time|
|
16
|
+
preprocessor = lambda { sleep time.to_i }
|
17
|
+
@handler.preprocessor = preprocessor
|
18
|
+
end
|
19
|
+
|
15
20
|
Given /the response from the service has a Content-Type of '(.*)'/ do |content_type|
|
16
21
|
@handler.content_type = content_type
|
17
22
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: Supports the timeout option
|
2
|
+
In order to handle inappropriately slow response times
|
3
|
+
As a developer
|
4
|
+
I want my request to raise an exception after my specified timeout as elapsed
|
5
|
+
|
6
|
+
Scenario: A long running response
|
7
|
+
Given a remote service that returns '<h1>Some HTML</h1>'
|
8
|
+
And that service is accessed at the path '/service.html'
|
9
|
+
And that service takes 2 seconds to generate a response
|
10
|
+
When I set my HTTParty timeout option to 1
|
11
|
+
And I call HTTParty#get with '/service.html'
|
12
|
+
Then it should raise a Timeout::Error exception
|
data/httparty.gemspec
CHANGED
@@ -1,26 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{httparty}
|
5
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.5"
|
6
9
|
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">=
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["John Nunemaker"]
|
9
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-09-12}
|
10
13
|
s.default_executable = %q{httparty}
|
11
14
|
s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
12
15
|
s.email = %q{nunemaker@gmail.com}
|
13
16
|
s.executables = ["httparty"]
|
14
|
-
s.extra_rdoc_files = [
|
15
|
-
|
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/delicious.rb",
|
33
|
+
"examples/google.rb",
|
34
|
+
"examples/rubyurl.rb",
|
35
|
+
"examples/twitter.rb",
|
36
|
+
"examples/whoismyrep.rb",
|
37
|
+
"features/basic_authentication.feature",
|
38
|
+
"features/command_line.feature",
|
39
|
+
"features/deals_with_http_error_codes.feature",
|
40
|
+
"features/handles_multiple_formats.feature",
|
41
|
+
"features/steps/env.rb",
|
42
|
+
"features/steps/httparty_response_steps.rb",
|
43
|
+
"features/steps/httparty_steps.rb",
|
44
|
+
"features/steps/mongrel_helper.rb",
|
45
|
+
"features/steps/remote_service_steps.rb",
|
46
|
+
"features/supports_redirection.feature",
|
47
|
+
"features/supports_timeout_option.feature",
|
48
|
+
"httparty.gemspec",
|
49
|
+
"lib/httparty.rb",
|
50
|
+
"lib/httparty/cookie_hash.rb",
|
51
|
+
"lib/httparty/core_extensions.rb",
|
52
|
+
"lib/httparty/exceptions.rb",
|
53
|
+
"lib/httparty/module_inheritable_attributes.rb",
|
54
|
+
"lib/httparty/request.rb",
|
55
|
+
"lib/httparty/response.rb",
|
56
|
+
"lib/httparty/version.rb",
|
57
|
+
"spec/fixtures/delicious.xml",
|
58
|
+
"spec/fixtures/empty.xml",
|
59
|
+
"spec/fixtures/google.html",
|
60
|
+
"spec/fixtures/twitter.json",
|
61
|
+
"spec/fixtures/twitter.xml",
|
62
|
+
"spec/fixtures/undefined_method_add_node_for_nil.xml",
|
63
|
+
"spec/httparty/cookie_hash_spec.rb",
|
64
|
+
"spec/httparty/request_spec.rb",
|
65
|
+
"spec/httparty/response_spec.rb",
|
66
|
+
"spec/httparty_spec.rb",
|
67
|
+
"spec/spec.opts",
|
68
|
+
"spec/spec_helper.rb",
|
69
|
+
"website/css/common.css",
|
70
|
+
"website/index.html"
|
71
|
+
]
|
16
72
|
s.has_rdoc = true
|
17
73
|
s.homepage = %q{http://httparty.rubyforge.org}
|
18
74
|
s.post_install_message = %q{When you HTTParty, you must party hard!}
|
19
|
-
s.rdoc_options = ["--
|
75
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
20
76
|
s.require_paths = ["lib"]
|
21
|
-
s.rubyforge_project = %q{httparty}
|
22
77
|
s.rubygems_version = %q{1.3.1}
|
23
78
|
s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
79
|
+
s.test_files = [
|
80
|
+
"spec/httparty/cookie_hash_spec.rb",
|
81
|
+
"spec/httparty/request_spec.rb",
|
82
|
+
"spec/httparty/response_spec.rb",
|
83
|
+
"spec/httparty_spec.rb",
|
84
|
+
"spec/spec_helper.rb",
|
85
|
+
"examples/aaws.rb",
|
86
|
+
"examples/basic.rb",
|
87
|
+
"examples/delicious.rb",
|
88
|
+
"examples/google.rb",
|
89
|
+
"examples/rubyurl.rb",
|
90
|
+
"examples/twitter.rb",
|
91
|
+
"examples/whoismyrep.rb"
|
92
|
+
]
|
24
93
|
|
25
94
|
if s.respond_to? :specification_version then
|
26
95
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -28,13 +97,13 @@ Gem::Specification.new do |s|
|
|
28
97
|
|
29
98
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
99
|
s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
|
31
|
-
s.add_development_dependency(%q<
|
100
|
+
s.add_development_dependency(%q<rspec>, ["= 1.2.8"])
|
32
101
|
else
|
33
102
|
s.add_dependency(%q<crack>, [">= 0.1.1"])
|
34
|
-
s.add_dependency(%q<
|
103
|
+
s.add_dependency(%q<rspec>, ["= 1.2.8"])
|
35
104
|
end
|
36
105
|
else
|
37
106
|
s.add_dependency(%q<crack>, [">= 0.1.1"])
|
38
|
-
s.add_dependency(%q<
|
107
|
+
s.add_dependency(%q<rspec>, ["= 1.2.8"])
|
39
108
|
end
|
40
109
|
end
|
data/lib/httparty.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'pathname'
|
3
2
|
require 'net/http'
|
4
3
|
require 'net/https'
|
5
|
-
require 'httparty/module_inheritable_attributes'
|
6
4
|
require 'rubygems'
|
7
|
-
gem 'crack'
|
5
|
+
gem 'crack', '>= 0.1.1'
|
8
6
|
require 'crack'
|
9
7
|
|
10
|
-
|
8
|
+
dir = Pathname(__FILE__).dirname.expand_path
|
9
|
+
|
10
|
+
require dir + 'httparty/module_inheritable_attributes'
|
11
|
+
require dir + 'httparty/cookie_hash'
|
11
12
|
|
12
13
|
module HTTParty
|
13
14
|
|
@@ -109,6 +110,16 @@ module HTTParty
|
|
109
110
|
default_options[:format] = f
|
110
111
|
end
|
111
112
|
|
113
|
+
# Allows setting a custom parser for the response.
|
114
|
+
#
|
115
|
+
# class Foo
|
116
|
+
# include HTTParty
|
117
|
+
# parser Proc.new {|data| ...}
|
118
|
+
# end
|
119
|
+
def parser(customer_parser)
|
120
|
+
default_options[:parser] = customer_parser
|
121
|
+
end
|
122
|
+
|
112
123
|
# Allows making a get request to a url.
|
113
124
|
#
|
114
125
|
# class Foo
|
@@ -155,16 +166,15 @@ module HTTParty
|
|
155
166
|
|
156
167
|
private
|
157
168
|
def perform_request(http_method, path, options) #:nodoc:
|
169
|
+
options = default_options.dup.merge(options)
|
158
170
|
process_cookies(options)
|
159
|
-
Request.new(http_method, path,
|
171
|
+
Request.new(http_method, path, options).perform
|
160
172
|
end
|
161
173
|
|
162
174
|
def process_cookies(options) #:nodoc:
|
163
|
-
return unless options[:cookies] || default_cookies
|
164
|
-
options[:headers] ||=
|
165
|
-
options[:headers]["cookie"] = cookies.merge(options
|
166
|
-
|
167
|
-
options.delete(:cookies)
|
175
|
+
return unless options[:cookies] || default_cookies.any?
|
176
|
+
options[:headers] ||= headers.dup
|
177
|
+
options[:headers]["cookie"] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string
|
168
178
|
end
|
169
179
|
end
|
170
180
|
|
@@ -200,7 +210,7 @@ module HTTParty
|
|
200
210
|
end
|
201
211
|
end
|
202
212
|
|
203
|
-
require 'httparty/core_extensions'
|
204
|
-
require 'httparty/exceptions'
|
205
|
-
require 'httparty/request'
|
206
|
-
require 'httparty/response'
|
213
|
+
require dir + 'httparty/core_extensions'
|
214
|
+
require dir + 'httparty/exceptions'
|
215
|
+
require dir + 'httparty/request'
|
216
|
+
require dir + 'httparty/response'
|
data/lib/httparty/cookie_hash.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
class HTTParty::CookieHash < Hash #:nodoc:
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
CLIENT_COOKIES = %w{path expires domain path secure HTTPOnly}
|
4
|
+
|
5
|
+
def add_cookies(value)
|
6
|
+
case value
|
7
|
+
when Hash
|
8
|
+
merge!(value)
|
9
|
+
when String
|
10
|
+
value.split('; ').each do |cookie|
|
11
|
+
array = cookie.split('=')
|
12
|
+
self[array[0].to_sym] = array[1]
|
13
|
+
end
|
14
|
+
else
|
15
|
+
raise "add_cookies only takes a Hash or a String"
|
16
|
+
end
|
4
17
|
end
|
5
18
|
|
6
19
|
def to_cookie_string
|
7
|
-
collect { |k, v| "#{k}=#{v}" }.join("; ")
|
20
|
+
delete_if { |k, v| CLIENT_COOKIES.include?(k.to_s) }.collect { |k, v| "#{k}=#{v}" }.join("; ")
|
8
21
|
end
|
9
22
|
end
|
@@ -1,10 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
end
|
5
|
-
else
|
6
|
-
class BlankSlate < BasicObject; end
|
7
|
-
end
|
1
|
+
class BasicObject #:nodoc:
|
2
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval/ }
|
3
|
+
end unless defined?(BasicObject)
|
8
4
|
|
9
5
|
# 1.8.6 has mistyping of transitive in if statement
|
10
6
|
require "rexml/document"
|
data/lib/httparty/request.rb
CHANGED
@@ -41,10 +41,15 @@ module HTTParty
|
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
|
+
|
44
45
|
def http
|
45
46
|
http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
|
46
47
|
http.use_ssl = (uri.port == 443)
|
47
48
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
49
|
+
if options[:timeout] && options[:timeout].is_a?(Integer)
|
50
|
+
http.open_timeout = options[:timeout]
|
51
|
+
http.read_timeout = options[:timeout]
|
52
|
+
end
|
48
53
|
http
|
49
54
|
end
|
50
55
|
|
@@ -98,6 +103,8 @@ module HTTParty
|
|
98
103
|
options[:limit] -= 1
|
99
104
|
self.path = response['location']
|
100
105
|
@redirect = true
|
106
|
+
self.http_method = Net::HTTP::Get
|
107
|
+
capture_cookies(response)
|
101
108
|
perform
|
102
109
|
else
|
103
110
|
parsed_response = parse_response(response.body)
|
@@ -105,18 +112,45 @@ module HTTParty
|
|
105
112
|
end
|
106
113
|
end
|
107
114
|
|
115
|
+
# HTTParty.const_get((self.format.to_s || 'text').capitalize)
|
108
116
|
def parse_response(body)
|
109
117
|
return nil if body.nil? or body.empty?
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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)
|
117
132
|
else
|
118
133
|
body
|
119
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
|
145
|
+
end
|
146
|
+
|
147
|
+
def capture_cookies(response)
|
148
|
+
return unless response['Set-Cookie']
|
149
|
+
cookies_hash = HTTParty::CookieHash.new()
|
150
|
+
cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie']
|
151
|
+
cookies_hash.add_cookies(response['Set-Cookie'])
|
152
|
+
options[:headers] ||= {}
|
153
|
+
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
|
120
154
|
end
|
121
155
|
|
122
156
|
# Uses the HTTP Content-Type header to determine the format of the response
|
data/lib/httparty/response.rb
CHANGED
@@ -6,17 +6,44 @@ describe HTTParty::CookieHash do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#add_cookies" do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
|
10
|
+
describe "with a hash" do
|
11
|
+
it "should add new key/value pairs to the hash" do
|
12
|
+
@cookie_hash.add_cookies(:foo => "bar")
|
13
|
+
@cookie_hash.add_cookies(:rofl => "copter")
|
14
|
+
@cookie_hash.length.should eql(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should overwrite any existing key" do
|
18
|
+
@cookie_hash.add_cookies(:foo => "bar")
|
19
|
+
@cookie_hash.add_cookies(:foo => "copter")
|
20
|
+
@cookie_hash.length.should eql(1)
|
21
|
+
@cookie_hash[:foo].should eql("copter")
|
22
|
+
end
|
13
23
|
end
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
25
|
+
describe "with a string" do
|
26
|
+
it "should add new key/value pairs to the hash" do
|
27
|
+
@cookie_hash.add_cookies("first=one; second=two; third")
|
28
|
+
@cookie_hash[:first].should == 'one'
|
29
|
+
@cookie_hash[:second].should == 'two'
|
30
|
+
@cookie_hash[:third].should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should overwrite any existing key" do
|
34
|
+
@cookie_hash[:foo] = 'bar'
|
35
|
+
@cookie_hash.add_cookies("foo=tar")
|
36
|
+
@cookie_hash.length.should eql(1)
|
37
|
+
@cookie_hash[:foo].should eql("tar")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'with other class' do
|
42
|
+
it "should error" do
|
43
|
+
lambda {
|
44
|
+
@cookie_hash.add_cookies(Array.new)
|
45
|
+
}.should raise_error
|
46
|
+
end
|
20
47
|
end
|
21
48
|
end
|
22
49
|
|
@@ -34,5 +61,11 @@ describe HTTParty::CookieHash do
|
|
34
61
|
@s.should match(/rofl=copter/)
|
35
62
|
@s.should match(/^\w+=\w+; \w+=\w+$/)
|
36
63
|
end
|
64
|
+
|
65
|
+
it "should not include client side only cookies" do
|
66
|
+
@cookie_hash.add_cookies(:path => "/")
|
67
|
+
@s = @cookie_hash.to_cookie_string
|
68
|
+
@s.should_not match(/path=\//)
|
69
|
+
end
|
37
70
|
end
|
38
71
|
end
|
@@ -46,8 +46,26 @@ describe HTTParty::Request do
|
|
46
46
|
@request.send(:setup_raw_request)
|
47
47
|
@request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
|
48
48
|
end
|
49
|
+
|
50
|
+
context "when setting timeout" do
|
51
|
+
it "does nothing if the timeout option is a string" do
|
52
|
+
http = mock("http", :null_object => true)
|
53
|
+
http.should_not_receive(:open_timeout=)
|
54
|
+
http.should_not_receive(:read_timeout=)
|
55
|
+
Net::HTTP.stub(:new => http)
|
56
|
+
|
57
|
+
request = HTTParty::Request.new(Net::HTTP::Get, 'https://foobar.com', {:timeout => "five seconds"})
|
58
|
+
request.send(:http)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "sets the timeout to 5 seconds" do
|
62
|
+
@request.options[:timeout] = 5
|
63
|
+
@request.send(:http).open_timeout.should == 5
|
64
|
+
@request.send(:http).read_timeout.should == 5
|
65
|
+
end
|
66
|
+
end
|
49
67
|
end
|
50
|
-
|
68
|
+
|
51
69
|
describe '#format_from_mimetype' do
|
52
70
|
it 'should handle text/xml' do
|
53
71
|
["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
|
@@ -176,6 +194,33 @@ describe HTTParty::Request do
|
|
176
194
|
@request.http_method = Net::HTTP::Put
|
177
195
|
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
178
196
|
end
|
197
|
+
|
198
|
+
it "should keep track of cookies between redirects" do
|
199
|
+
@redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
|
200
|
+
@request.perform
|
201
|
+
@request.options[:headers]['Cookie'].should match(/foo=bar/)
|
202
|
+
@request.options[:headers]['Cookie'].should match(/name=value/)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should update cookies with rediects' do
|
206
|
+
@request.options[:headers] = {'Cookie'=> 'foo=bar;'}
|
207
|
+
@redirect['Set-Cookie'] = 'foo=tar;'
|
208
|
+
@request.perform
|
209
|
+
@request.options[:headers]['Cookie'].should match(/foo=tar/)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should keep cookies between rediects' do
|
213
|
+
@request.options[:headers] = {'Cookie'=> 'keep=me'}
|
214
|
+
@redirect['Set-Cookie'] = 'foo=tar;'
|
215
|
+
@request.perform
|
216
|
+
@request.options[:headers]['Cookie'].should match(/keep=me/)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should make resulting request a get request if it not already' do
|
220
|
+
@request.http_method = Net::HTTP::Delete
|
221
|
+
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
222
|
+
@request.http_method.should == Net::HTTP::Get
|
223
|
+
end
|
179
224
|
end
|
180
225
|
|
181
226
|
describe "infinitely" do
|
data/spec/httparty_spec.rb
CHANGED
@@ -51,15 +51,53 @@ describe HTTParty do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
describe "headers" do
|
54
|
+
def expect_headers(header={})
|
55
|
+
HTTParty::Request.should_receive(:new) \
|
56
|
+
.with(anything, anything, hash_including({ :headers => header })) \
|
57
|
+
.and_return(mock("mock response", :perform => nil))
|
58
|
+
end
|
59
|
+
|
54
60
|
it "should default to empty hash" do
|
55
61
|
@klass.headers.should == {}
|
56
62
|
end
|
57
|
-
|
63
|
+
|
58
64
|
it "should be able to be updated" do
|
59
65
|
init_headers = {:foo => 'bar', :baz => 'spax'}
|
60
66
|
@klass.headers init_headers
|
61
67
|
@klass.headers.should == init_headers
|
62
68
|
end
|
69
|
+
|
70
|
+
it "uses the class headers when sending a request" do
|
71
|
+
expect_headers(:foo => 'bar')
|
72
|
+
@klass.headers(:foo => 'bar')
|
73
|
+
@klass.get('')
|
74
|
+
end
|
75
|
+
|
76
|
+
it "overwrites class headers when passing in headers" do
|
77
|
+
expect_headers(:baz => 'spax')
|
78
|
+
@klass.headers(:foo => 'bar')
|
79
|
+
@klass.get('', :headers => {:baz => 'spax'})
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with cookies" do
|
83
|
+
it 'utilizes the class-level cookies' do
|
84
|
+
expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle')
|
85
|
+
@klass.headers(:foo => 'bar')
|
86
|
+
@klass.cookies(:type => 'snickerdoodle')
|
87
|
+
@klass.get('')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'adds cookies to the headers' do
|
91
|
+
expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle')
|
92
|
+
@klass.headers(:foo => 'bar')
|
93
|
+
@klass.get('', :cookies => {:type => 'snickerdoodle'})
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'adds optional cookies to the optional headers' do
|
97
|
+
expect_headers(:baz => 'spax', 'cookie' => 'type=snickerdoodle')
|
98
|
+
@klass.get('', :cookies => {:type => 'snickerdoodle'}, :headers => {:baz => 'spax'})
|
99
|
+
end
|
100
|
+
end
|
63
101
|
end
|
64
102
|
|
65
103
|
describe "cookies" do
|
@@ -287,4 +325,4 @@ describe HTTParty do
|
|
287
325
|
result.should == nil
|
288
326
|
end
|
289
327
|
end
|
290
|
-
end
|
328
|
+
end
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
gem 'rspec', '>= 1.2.8'
|
3
|
-
require 'spec'
|
4
1
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'httparty')
|
2
|
+
gem 'rspec', '1.2.8'
|
3
|
+
gem 'fakeweb'
|
4
|
+
require 'spec/autorun'
|
5
|
+
require 'fakeweb'
|
6
|
+
|
7
|
+
FakeWeb.allow_net_connect = false
|
5
8
|
|
6
9
|
def file_fixture(filename)
|
7
10
|
open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read
|
data/website/index.html
CHANGED
@@ -1,32 +1,31 @@
|
|
1
1
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
2
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
3
|
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
5
|
+
<title>HTTParty by John Nunemaker</title>
|
6
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
7
7
|
</head>
|
8
8
|
<body>
|
9
9
|
|
10
10
|
<div id="wrapper">
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
<p>The following is a simple example of wrapping Twitter's API for posting updates.</p>
|
11
|
+
<div id="header">
|
12
|
+
<h1>HTTParty</h1>
|
13
|
+
<p>Tonight we're gonna HTTParty like it's 1999!</p>
|
14
|
+
|
15
|
+
<ul id="nav">
|
16
|
+
<li><a href="rdoc/">Docs</a></li>
|
17
|
+
<li><a href="http://github.com/jnunemaker/httparty">Github</a></li>
|
18
|
+
<li><a href="http://rubyforge.org/projects/httparty/">Rubyforge</a></li>
|
19
|
+
</ul>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div id="content">
|
23
|
+
<h2>Install</h2>
|
24
|
+
<pre><code>$ sudo gem install httparty</code></pre>
|
25
|
+
|
26
|
+
<h2>Some Quick Examples</h2>
|
27
|
+
|
28
|
+
<p>The following is a simple example of wrapping Twitter's API for posting updates.</p>
|
30
29
|
|
31
30
|
<pre><code>class Twitter
|
32
31
|
include HTTParty
|
@@ -36,9 +35,9 @@ end
|
|
36
35
|
|
37
36
|
Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty and everyone is invited!"})</code></pre>
|
38
37
|
|
39
|
-
|
38
|
+
<p>That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples). </p>
|
40
39
|
|
41
|
-
|
40
|
+
<p>That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:</p>
|
42
41
|
|
43
42
|
<pre><code>class Twitter
|
44
43
|
include HTTParty
|
@@ -55,19 +54,19 @@ Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty an
|
|
55
54
|
end
|
56
55
|
|
57
56
|
Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")</code></pre>
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
|
58
|
+
<p><strong>More Examples:</strong> There are <a href="http://github.com/jnunemaker/httparty/tree/master/examples/">several examples in the gem itself</a>.</p>
|
59
|
+
|
60
|
+
<h2>Support</h2>
|
61
|
+
<p>Conversations welcome in the <a href="http://groups.google.com/group/httparty-gem">google group</a> and bugs/features over at <a href="http://github.com/jnunemaker/httparty">Github</a>.</p>
|
62
|
+
|
63
|
+
|
64
|
+
</div>
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
<div id="footer">
|
67
|
+
<p>Created by <a href="http://addictedtonew.com/about/">John Nunemaker</a> |
|
68
|
+
<a href="http://orderedlist.com/">Hire Me at Ordered List</a></p>
|
69
|
+
</div>
|
71
70
|
</div>
|
72
71
|
|
73
72
|
</body>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httparty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
13
|
-
default_executable:
|
12
|
+
date: 2009-09-12 00:00:00 -04:00
|
13
|
+
default_executable: httparty
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: crack
|
@@ -23,14 +23,14 @@ dependencies:
|
|
23
23
|
version: 0.1.1
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
26
|
+
name: rspec
|
27
27
|
type: :development
|
28
28
|
version_requirement:
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.2.8
|
34
34
|
version:
|
35
35
|
description: Makes http fun! Also, makes consuming restful web services dead easy.
|
36
36
|
email: nunemaker@gmail.com
|
@@ -39,17 +39,15 @@ executables:
|
|
39
39
|
extensions: []
|
40
40
|
|
41
41
|
extra_rdoc_files:
|
42
|
-
- bin/httparty
|
43
|
-
- lib/httparty/cookie_hash.rb
|
44
|
-
- lib/httparty/core_extensions.rb
|
45
|
-
- lib/httparty/exceptions.rb
|
46
|
-
- lib/httparty/module_inheritable_attributes.rb
|
47
|
-
- lib/httparty/request.rb
|
48
|
-
- lib/httparty/response.rb
|
49
|
-
- lib/httparty/version.rb
|
50
|
-
- lib/httparty.rb
|
51
42
|
- README.rdoc
|
52
43
|
files:
|
44
|
+
- .gitignore
|
45
|
+
- History
|
46
|
+
- MIT-LICENSE
|
47
|
+
- Manifest
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
53
51
|
- bin/httparty
|
54
52
|
- cucumber.yml
|
55
53
|
- examples/aaws.rb
|
@@ -69,8 +67,9 @@ files:
|
|
69
67
|
- features/steps/mongrel_helper.rb
|
70
68
|
- features/steps/remote_service_steps.rb
|
71
69
|
- features/supports_redirection.feature
|
72
|
-
-
|
70
|
+
- features/supports_timeout_option.feature
|
73
71
|
- httparty.gemspec
|
72
|
+
- lib/httparty.rb
|
74
73
|
- lib/httparty/cookie_hash.rb
|
75
74
|
- lib/httparty/core_extensions.rb
|
76
75
|
- lib/httparty/exceptions.rb
|
@@ -78,11 +77,6 @@ files:
|
|
78
77
|
- lib/httparty/request.rb
|
79
78
|
- lib/httparty/response.rb
|
80
79
|
- lib/httparty/version.rb
|
81
|
-
- lib/httparty.rb
|
82
|
-
- Manifest
|
83
|
-
- MIT-LICENSE
|
84
|
-
- Rakefile
|
85
|
-
- README.rdoc
|
86
80
|
- spec/fixtures/delicious.xml
|
87
81
|
- spec/fixtures/empty.xml
|
88
82
|
- spec/fixtures/google.html
|
@@ -99,14 +93,11 @@ files:
|
|
99
93
|
- website/index.html
|
100
94
|
has_rdoc: true
|
101
95
|
homepage: http://httparty.rubyforge.org
|
96
|
+
licenses: []
|
97
|
+
|
102
98
|
post_install_message: When you HTTParty, you must party hard!
|
103
99
|
rdoc_options:
|
104
|
-
- --
|
105
|
-
- --inline-source
|
106
|
-
- --title
|
107
|
-
- Httparty
|
108
|
-
- --main
|
109
|
-
- README.rdoc
|
100
|
+
- --charset=UTF-8
|
110
101
|
require_paths:
|
111
102
|
- lib
|
112
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -119,14 +110,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
110
|
requirements:
|
120
111
|
- - ">="
|
121
112
|
- !ruby/object:Gem::Version
|
122
|
-
version: "
|
113
|
+
version: "0"
|
123
114
|
version:
|
124
115
|
requirements: []
|
125
116
|
|
126
|
-
rubyforge_project:
|
127
|
-
rubygems_version: 1.3.
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 1.3.5
|
128
119
|
signing_key:
|
129
120
|
specification_version: 2
|
130
121
|
summary: Makes http fun! Also, makes consuming restful web services dead easy.
|
131
|
-
test_files:
|
132
|
-
|
122
|
+
test_files:
|
123
|
+
- spec/httparty/cookie_hash_spec.rb
|
124
|
+
- spec/httparty/request_spec.rb
|
125
|
+
- spec/httparty/response_spec.rb
|
126
|
+
- spec/httparty_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- examples/aaws.rb
|
129
|
+
- examples/basic.rb
|
130
|
+
- examples/delicious.rb
|
131
|
+
- examples/google.rb
|
132
|
+
- examples/rubyurl.rb
|
133
|
+
- examples/twitter.rb
|
134
|
+
- examples/whoismyrep.rb
|