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.

@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ doc/
3
+ tmp/
4
+ log/
5
+ pkg/
6
+ *.swp
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
@@ -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 build_gemspec
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
- ProjectName = 'httparty'
2
- WebsitePath = "jnunemaker@rubyforge.org:/var/www/gforge-projects/#{ProjectName}"
3
-
4
- require 'rubygems'
5
- require 'rake'
6
- require 'echoe'
7
- require 'spec/rake/spectask'
8
- require "lib/#{ProjectName}/version"
9
- require 'cucumber/rake/task'
10
-
11
- Echoe.new(ProjectName, HTTParty::Version) do |p|
12
- p.description = "Makes http fun! Also, makes consuming restful web services dead easy."
13
- p.install_message = "When you HTTParty, you must party hard!"
14
- p.url = "http://#{ProjectName}.rubyforge.org"
15
- p.author = "John Nunemaker"
16
- p.email = "nunemaker@gmail.com"
17
- p.extra_deps = [['crack', '>= 0.1.1']]
18
- p.need_tar_gz = false
19
- p.docs_host = WebsitePath
20
- end
21
-
22
- desc 'Upload website files to rubyforge'
23
- task :website do
24
- sh %{rsync -av website/ #{WebsitePath}}
25
- Rake::Task['website_docs'].invoke
26
- end
27
-
28
- task :website_docs do
29
- Rake::Task['redocs'].invoke
30
- sh %{rsync -av doc/ #{WebsitePath}/docs}
31
- end
32
-
33
- desc 'Preps the gem for a new release'
34
- task :prepare do
35
- %w[manifest build_gemspec].each do |task|
36
- Rake::Task[task].invoke
37
- end
38
- end
39
-
40
- Rake::Task[:default].prerequisites.clear
41
- task :default => :spec
42
- Spec::Rake::SpecTask.new do |t|
43
- t.spec_files = FileList["spec/**/*_spec.rb"]
44
- end
45
-
46
- Cucumber::Rake::Task.new(:features) do |t|
47
- t.cucumber_opts = "--format pretty"
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", "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
@@ -37,7 +37,7 @@ OptionParser.new do |o|
37
37
  "--data [BODY]",
38
38
  "Data to put in request body (prefix with '@' for file)") do |d|
39
39
  if d =~ /^@/
40
- opts[:data] = open(d).read
40
+ opts[:data] = open(d[1..-1]).read
41
41
  else
42
42
  opts[:data] = d
43
43
  end
@@ -8,6 +8,7 @@ Before do
8
8
  @host_and_port = "0.0.0.0:#{port}"
9
9
  @server = Mongrel::HttpServer.new("0.0.0.0", port)
10
10
  @server.run
11
+ @request_options = {}
11
12
  end
12
13
 
13
14
  After do
@@ -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 HTTParty::RedirectionTooDeep exception/ do
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(HTTParty::RedirectionTooDeep)
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
@@ -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.4"
8
+ s.version = "0.4.5"
6
9
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
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-07-19}
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 = ["bin/httparty", "lib/httparty/cookie_hash.rb", "lib/httparty/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "README.rdoc"]
15
- s.files = ["bin/httparty", "cucumber.yml", "examples/aaws.rb", "examples/basic.rb", "examples/delicious.rb", "examples/google.rb", "examples/rubyurl.rb", "examples/twitter.rb", "examples/whoismyrep.rb", "features/basic_authentication.feature", "features/command_line.feature", "features/deals_with_http_error_codes.feature", "features/handles_multiple_formats.feature", "features/steps/env.rb", "features/steps/httparty_response_steps.rb", "features/steps/httparty_steps.rb", "features/steps/mongrel_helper.rb", "features/steps/remote_service_steps.rb", "features/supports_redirection.feature", "History", "httparty.gemspec", "lib/httparty/cookie_hash.rb", "lib/httparty/core_extensions.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "spec/fixtures/delicious.xml", "spec/fixtures/empty.xml", "spec/fixtures/google.html", "spec/fixtures/twitter.json", "spec/fixtures/twitter.xml", "spec/fixtures/undefined_method_add_node_for_nil.xml", "spec/httparty/cookie_hash_spec.rb", "spec/httparty/request_spec.rb", "spec/httparty/response_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "website/css/common.css", "website/index.html"]
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 = ["--line-numbers", "--inline-source", "--title", "Httparty", "--main", "README.rdoc"]
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<echoe>, [">= 0"])
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<echoe>, [">= 0"])
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<echoe>, [">= 0"])
107
+ s.add_dependency(%q<rspec>, ["= 1.2.8"])
39
108
  end
40
109
  end
@@ -1,13 +1,14 @@
1
- $:.unshift(File.dirname(__FILE__))
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
- require 'httparty/cookie_hash'
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, default_options.dup.merge(options)).perform
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[:cookies] || {}).to_cookie_string
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'
@@ -1,9 +1,22 @@
1
1
  class HTTParty::CookieHash < Hash #:nodoc:
2
- def add_cookies(hash)
3
- merge!(hash)
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
- if RUBY_VERSION.to_f == 1.8
2
- class BlankSlate #:nodoc:
3
- instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval|object_id/ }
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"
@@ -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
- case format
111
- when :xml
112
- Crack::XML.parse(body)
113
- when :json
114
- Crack::JSON.parse(body)
115
- when :yaml
116
- YAML::load(body)
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
@@ -1,5 +1,5 @@
1
1
  module HTTParty
2
- class Response < BlankSlate #:nodoc:
2
+ class Response < BasicObject #:nodoc:
3
3
  attr_accessor :body, :code, :message, :headers
4
4
  attr_reader :delegate
5
5
 
@@ -6,17 +6,44 @@ describe HTTParty::CookieHash do
6
6
  end
7
7
 
8
8
  describe "#add_cookies" do
9
- it "should add new key/value pairs to the hash" do
10
- @cookie_hash.add_cookies(:foo => "bar")
11
- @cookie_hash.add_cookies(:rofl => "copter")
12
- @cookie_hash.length.should eql(2)
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
- it "should overwrite any existing key" do
16
- @cookie_hash.add_cookies(:foo => "bar")
17
- @cookie_hash.add_cookies(:foo => "copter")
18
- @cookie_hash.length.should eql(1)
19
- @cookie_hash[:foo].should eql("copter")
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
@@ -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
@@ -1,3 +1,2 @@
1
- --format
2
- progress
3
1
  --colour
2
+ --format specdoc
@@ -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
@@ -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
- <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" />
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
- <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://jnunemaker.lighthouseapp.com/projects/14842-httparty/tickets">Lighthouse</a></li>
19
- <li><a href="http://rubyforge.org/projects/httparty/">Rubyforge</a></li>
20
- </ul>
21
- </div>
22
-
23
- <div id="content">
24
- <h2>Install</h2>
25
- <pre><code>$ sudo gem install httparty</code></pre>
26
-
27
- <h2>Some Quick Examples</h2>
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
- <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>
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
- <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>
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
- <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>
60
-
61
- <h2>Support</h2>
62
- <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://jnunemaker.lighthouseapp.com/projects/14842-httparty/overview">Lightouse</a>.</p>
63
-
64
-
65
- </div>
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
- <div id="footer">
68
- <p>Created by <a href="http://addictedtonew.com/about/">John Nunemaker</a> |
69
- <a href="http://orderedlist.com/">Hire Me at Ordered List</a></p>
70
- </div>
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
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-07-19 00:00:00 -04:00
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: echoe
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: "0"
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
- - History
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
- - --line-numbers
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: "1.2"
113
+ version: "0"
123
114
  version:
124
115
  requirements: []
125
116
 
126
- rubyforge_project: httparty
127
- rubygems_version: 1.3.1
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