jnunemaker-httparty 0.4.4 → 0.4.5
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.
- data/.gitignore +6 -0
- data/History +10 -0
- data/README.rdoc +1 -1
- data/Rakefile +70 -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 +13 -14
- data/lib/httparty/cookie_hash.rb +16 -3
- data/lib/httparty/core_extensions.rb +3 -7
- data/lib/httparty/request.rb +16 -0
- 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 +39 -1
- data/spec/spec.opts +1 -2
- data/spec/spec_helper.rb +7 -4
- data/website/index.html +35 -36
- metadata +30 -30
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.
|
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,70 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
task
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
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"]
|
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 is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
19
|
+
rubyforge.doc_task = "rdoc"
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
spec.spec_opts = ['--options', 'spec/spec.opts']
|
30
|
+
end
|
31
|
+
|
32
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
33
|
+
spec.libs << 'lib' << 'spec'
|
34
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
35
|
+
spec.rcov = true
|
36
|
+
end
|
37
|
+
|
38
|
+
task :spec => :check_dependencies
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'cucumber/rake/task'
|
42
|
+
Cucumber::Rake::Task.new(:features)
|
43
|
+
|
44
|
+
task :features => :check_dependencies
|
45
|
+
rescue LoadError
|
46
|
+
task :features do
|
47
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
task :default => [:spec, :features]
|
52
|
+
|
53
|
+
require 'rake/rdoctask'
|
54
|
+
Rake::RDocTask.new do |rdoc|
|
55
|
+
if File.exist?('VERSION')
|
56
|
+
version = File.read('VERSION')
|
57
|
+
else
|
58
|
+
version = ""
|
59
|
+
end
|
60
|
+
|
61
|
+
rdoc.rdoc_dir = 'rdoc'
|
62
|
+
rdoc.title = "httparty #{version}"
|
63
|
+
rdoc.rdoc_files.include('README*')
|
64
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'Upload website files to rubyforge'
|
68
|
+
task :website do
|
69
|
+
sh %{rsync -av website/ jnunemaker@rubyforge.org:/var/www/gforge-projects/httparty}
|
70
|
+
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
|
|
@@ -160,11 +161,9 @@ module HTTParty
|
|
160
161
|
end
|
161
162
|
|
162
163
|
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)
|
164
|
+
return unless options[:cookies] || default_cookies.any?
|
165
|
+
options[:headers] ||= headers.dup
|
166
|
+
options[:headers]["cookie"] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string
|
168
167
|
end
|
169
168
|
end
|
170
169
|
|
@@ -200,7 +199,7 @@ module HTTParty
|
|
200
199
|
end
|
201
200
|
end
|
202
201
|
|
203
|
-
require 'httparty/core_extensions'
|
204
|
-
require 'httparty/exceptions'
|
205
|
-
require 'httparty/request'
|
206
|
-
require 'httparty/response'
|
202
|
+
require dir + 'httparty/core_extensions'
|
203
|
+
require dir + 'httparty/exceptions'
|
204
|
+
require dir + 'httparty/request'
|
205
|
+
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)
|
@@ -118,6 +125,15 @@ module HTTParty
|
|
118
125
|
body
|
119
126
|
end
|
120
127
|
end
|
128
|
+
|
129
|
+
def capture_cookies(response)
|
130
|
+
return unless response['Set-Cookie']
|
131
|
+
cookies_hash = HTTParty::CookieHash.new()
|
132
|
+
cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie']
|
133
|
+
cookies_hash.add_cookies(response['Set-Cookie'])
|
134
|
+
options[:headers] ||= {}
|
135
|
+
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
|
136
|
+
end
|
121
137
|
|
122
138
|
# Uses the HTTP Content-Type header to determine the format of the response
|
123
139
|
# It compares the MIME type returned to the types stored in the AllowedFormats hash
|
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
|
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
|
@@ -18,4 +21,4 @@ def stub_http_response_with(filename)
|
|
18
21
|
http_request.stub!(:perform_actual_request).and_return(response)
|
19
22
|
|
20
23
|
HTTParty::Request.should_receive(:new).and_return(http_request)
|
21
|
-
end
|
24
|
+
end
|
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: jnunemaker-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,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-12 00:00:00 -07:00
|
13
13
|
default_executable: httparty
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -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
|
@@ -101,12 +95,7 @@ has_rdoc: true
|
|
101
95
|
homepage: http://httparty.rubyforge.org
|
102
96
|
post_install_message: When you HTTParty, you must party hard!
|
103
97
|
rdoc_options:
|
104
|
-
- --
|
105
|
-
- --inline-source
|
106
|
-
- --title
|
107
|
-
- Httparty
|
108
|
-
- --main
|
109
|
-
- README.rdoc
|
98
|
+
- --charset=UTF-8
|
110
99
|
require_paths:
|
111
100
|
- lib
|
112
101
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -119,14 +108,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
108
|
requirements:
|
120
109
|
- - ">="
|
121
110
|
- !ruby/object:Gem::Version
|
122
|
-
version: "
|
111
|
+
version: "0"
|
123
112
|
version:
|
124
113
|
requirements: []
|
125
114
|
|
126
|
-
rubyforge_project:
|
115
|
+
rubyforge_project:
|
127
116
|
rubygems_version: 1.2.0
|
128
117
|
signing_key:
|
129
118
|
specification_version: 2
|
130
119
|
summary: Makes http fun! Also, makes consuming restful web services dead easy.
|
131
|
-
test_files:
|
132
|
-
|
120
|
+
test_files:
|
121
|
+
- spec/httparty/cookie_hash_spec.rb
|
122
|
+
- spec/httparty/request_spec.rb
|
123
|
+
- spec/httparty/response_spec.rb
|
124
|
+
- spec/httparty_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
- examples/aaws.rb
|
127
|
+
- examples/basic.rb
|
128
|
+
- examples/delicious.rb
|
129
|
+
- examples/google.rb
|
130
|
+
- examples/rubyurl.rb
|
131
|
+
- examples/twitter.rb
|
132
|
+
- examples/whoismyrep.rb
|