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.
@@ -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.
@@ -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,70 @@
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"]
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
@@ -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
 
@@ -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[:cookies] || {}).to_cookie_string
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'
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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: jnunemaker-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,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-19 00:00:00 -07:00
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: 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
@@ -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
- - --line-numbers
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: "1.2"
111
+ version: "0"
123
112
  version:
124
113
  requirements: []
125
114
 
126
- rubyforge_project: httparty
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