httparty 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of httparty might be problematic. Click here for more details.

data/History CHANGED
@@ -1,3 +1,21 @@
1
+ == 0.5.0 2009-12-07
2
+ * bug fixes
3
+ * inheritable attributes no longer mutable by subclasses (yyyc514)
4
+ * namespace BasicObject within HTTParty to avoid class name collisions (eric)
5
+
6
+ * major enhancements
7
+ * Custom Parsers via class or proc
8
+ * Deprecation warning on HTTParty::AllowedFormats
9
+ moved to HTTParty::Parser::SupportedFormats
10
+
11
+ * minor enhancements
12
+ * Curl inspired output when using the binary in verbose mode (alexvollmer)
13
+ * raise UnsupportedURIScheme when scheme is not HTTP or HTTPS (djspinmonkey)
14
+ * Allow SSL for ports other than 443 when scheme is HTTPS (stefankroes)
15
+ * Accept PEM certificates via HTTParty#pem (chrislo)
16
+ * Support HEAD and OPTION verbs (grempe)
17
+ * Verify SSL certificates when providing a PEM file (collectiveidea/danielmorrison)
18
+
1
19
  == 0.4.5 2009-09-12
2
20
  * bug fixes
3
21
  * Fixed class-level headers overwritten by cookie management code. Closes #19
@@ -138,4 +156,4 @@
138
156
  == 0.1.0 2008-07-27
139
157
 
140
158
  * 1 major enhancement:
141
- * Initial release
159
+ * Initial release
data/Rakefile CHANGED
@@ -4,36 +4,41 @@ require 'rake'
4
4
  begin
5
5
  require 'jeweler'
6
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
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 "activesupport", "~>2.3"
15
+ gem.add_development_dependency "cucumber", "~>0.4"
16
+ gem.add_development_dependency "fakeweb", "~>1.2"
17
+ gem.add_development_dependency "mongrel", "~>1.1"
18
+ gem.add_development_dependency "rspec", "1.2.9"
19
+ gem.post_install_message = "When you HTTParty, you must party hard!"
20
+ gem.rubyforge_project = 'httparty'
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
22
  end
19
23
  Jeweler::RubyforgeTasks.new do |rubyforge|
20
- rubyforge.doc_task = "rdoc"
24
+ rubyforge.doc_task = "rdoc"
21
25
  end
26
+ Jeweler::GemcutterTasks.new
22
27
  rescue LoadError
23
28
  puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
24
29
  end
25
30
 
26
31
  require 'spec/rake/spectask'
27
32
  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']
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.spec_files = FileList['spec/**/*_spec.rb']
35
+ spec.spec_opts = ['--options', 'spec/spec.opts']
31
36
  end
32
37
 
33
38
  Spec::Rake::SpecTask.new(:rcov) do |spec|
34
- spec.libs << 'lib' << 'spec'
35
- spec.pattern = 'spec/**/*_spec.rb'
36
- spec.rcov = true
39
+ spec.libs << 'lib' << 'spec'
40
+ spec.pattern = 'spec/**/*_spec.rb'
41
+ spec.rcov = true
37
42
  end
38
43
 
39
44
  task :spec => :check_dependencies
@@ -41,11 +46,11 @@ task :spec => :check_dependencies
41
46
  begin
42
47
  require 'cucumber/rake/task'
43
48
  Cucumber::Rake::Task.new(:features)
44
-
49
+
45
50
  task :features => :check_dependencies
46
51
  rescue LoadError
47
52
  task :features do
48
- abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
53
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
49
54
  end
50
55
  end
51
56
 
@@ -53,19 +58,19 @@ task :default => [:spec, :features]
53
58
 
54
59
  require 'rake/rdoctask'
55
60
  Rake::RDocTask.new do |rdoc|
56
- if File.exist?('VERSION')
57
- version = File.read('VERSION')
58
- else
59
- version = ""
60
- end
61
+ if File.exist?('VERSION')
62
+ version = File.read('VERSION')
63
+ else
64
+ version = ""
65
+ end
61
66
 
62
- rdoc.rdoc_dir = 'rdoc'
63
- rdoc.title = "httparty #{version}"
64
- rdoc.rdoc_files.include('README*')
65
- rdoc.rdoc_files.include('lib/**/*.rb')
67
+ rdoc.rdoc_dir = 'rdoc'
68
+ rdoc.title = "httparty #{version}"
69
+ rdoc.rdoc_files.include('README*')
70
+ rdoc.rdoc_files.include('lib/**/*.rb')
66
71
  end
67
72
 
68
73
  desc 'Upload website files to rubyforge'
69
74
  task :website do
70
- sh %{rsync -av website/ jnunemaker@rubyforge.org:/var/www/gforge-projects/httparty}
71
- end
75
+ sh %{rsync -av website/ jnunemaker@rubyforge.org:/var/www/gforge-projects/httparty}
76
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.5
1
+ 0.5.0
@@ -12,27 +12,22 @@ opts = {
12
12
  :verbose => false
13
13
  }
14
14
 
15
- def die(msg)
16
- STDERR.puts(msg)
17
- exit 1
18
- end
19
-
20
15
  OptionParser.new do |o|
21
16
  o.banner = "USAGE: #{$0} [options] [url]"
22
-
17
+
23
18
  o.on("-f",
24
19
  "--format [FORMAT]",
25
20
  "Output format to use instead of pretty-print ruby: " +
26
21
  "plain, json or xml") do |f|
27
22
  opts[:output_format] = f.downcase.to_sym
28
23
  end
29
-
24
+
30
25
  o.on("-a",
31
26
  "--action [ACTION]",
32
- "HTTP action: get (default), post, put or delete") do |a|
27
+ "HTTP action: get (default), post, put, delete, head, or options") do |a|
33
28
  opts[:action] = a.downcase.to_sym
34
29
  end
35
-
30
+
36
31
  o.on("-d",
37
32
  "--data [BODY]",
38
33
  "Data to put in request body (prefix with '@' for file)") do |d|
@@ -42,44 +37,60 @@ OptionParser.new do |o|
42
37
  opts[:data] = d
43
38
  end
44
39
  end
45
-
40
+
46
41
  o.on("-H", "--header [NAME=VALUE]", "Additional HTTP headers in NAME=VALUE form") do |h|
47
- die "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/
42
+ abort "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/
48
43
  name, value = h.split(':')
49
44
  opts[:headers][name.strip] = value.strip
50
45
  end
51
-
46
+
52
47
  o.on("-v", "--verbose", "If set, print verbose output") do |v|
53
48
  opts[:verbose] = true
54
49
  end
55
-
50
+
56
51
  o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u|
57
- die "Invalid credentials format. Must be user:password" unless u =~ /.+:.+/
52
+ abort "Invalid credentials format. Must be user:password" unless u =~ /.+:.+/
58
53
  user, password = u.split(':')
59
54
  opts[:basic_auth] = { :username => user, :password => password }
60
55
  end
61
-
56
+
62
57
  o.on("-h", "--help", "Show help documentation") do |h|
63
58
  puts o
64
59
  exit
65
60
  end
66
61
  end.parse!
67
62
 
68
- puts "Querying #{ARGV.first} with options: #{opts.inspect}" if opts[:verbose]
69
63
 
70
64
  if ARGV.empty?
71
65
  STDERR.puts "You need to provide a URL"
72
66
  STDERR.puts "USAGE: #{$0} [options] [url]"
73
67
  end
74
68
 
69
+ def dump_headers(response)
70
+ resp_type = Net::HTTPResponse::CODE_TO_OBJ[response.code.to_s]
71
+ puts "#{response.code} #{resp_type.to_s.sub(/^Net::HTTP/, '')}"
72
+ response.headers.each do |n,v|
73
+ puts "#{n}: #{v}"
74
+ end
75
+ puts
76
+ end
77
+
78
+ if opts[:verbose]
79
+ puts "#{opts[:action].to_s.upcase} #{ARGV.first}"
80
+ opts[:headers].each do |n,v|
81
+ puts "#{n}: #{v}"
82
+ end
83
+ puts
84
+ end
85
+
86
+ response = HTTParty.send(opts[:action], ARGV.first, opts)
75
87
  if opts[:output_format].nil?
76
- response = HTTParty.send(opts[:action], ARGV.first, opts)
77
- puts "Status: #{response.code}"
88
+ dump_headers(response) if opts[:verbose]
78
89
  pp response
79
90
  else
80
91
  print_format = opts[:output_format]
81
- response = HTTParty.send(opts[:action], ARGV.first, opts)
82
- puts "Status: #{response.code}"
92
+ dump_headers(response) if opts[:verbose]
93
+
83
94
  case opts[:output_format]
84
95
  when :json
85
96
  begin
@@ -95,4 +106,4 @@ else
95
106
  else
96
107
  puts response
97
108
  end
98
- end
109
+ end
@@ -2,7 +2,7 @@ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require File.join(dir, 'httparty')
3
3
  require 'pp'
4
4
 
5
- # You can also use post, put, delete in the same fashion
5
+ # You can also use post, put, delete, head, options in the same fashion
6
6
  response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
7
7
  puts response.body, response.code, response.message, response.headers.inspect
8
8
 
@@ -0,0 +1,67 @@
1
+ class ParseAtom
2
+ include HTTParty
3
+
4
+ # Support Atom along with the default parsers: xml, json, yaml, etc.
5
+ class Parser::Atom < HTTParty::Parser
6
+ SupportedFormats.merge!({"application/atom+xml" => :atom})
7
+
8
+ protected
9
+
10
+ # perform atom parsing on body
11
+ def atom
12
+ body.to_atom
13
+ end
14
+ end
15
+
16
+ parser Parser::Atom
17
+ end
18
+
19
+
20
+ class OnlyParseAtom
21
+ include HTTParty
22
+
23
+ # Only support Atom
24
+ class Parser::OnlyAtom < HTTParty::Parser
25
+ SupportedFormats = {"application/atom+xml" => :atom}
26
+
27
+ protected
28
+
29
+ # perform atom parsing on body
30
+ def atom
31
+ body.to_atom
32
+ end
33
+ end
34
+
35
+ parser Parser::OnlyAtom
36
+ end
37
+
38
+
39
+ class SkipParsing
40
+ include HTTParty
41
+
42
+ # Parse the response body however you like
43
+ class Parser::Simple < HTTParty::Parser
44
+ def parse
45
+ body
46
+ end
47
+ end
48
+
49
+ parser Parser::Simple
50
+ end
51
+
52
+
53
+ class AdHocParsing
54
+ include HTTParty
55
+ parser(
56
+ Proc.new do |body, format|
57
+ case format
58
+ when :json
59
+ body.to_json
60
+ when :xml
61
+ body.to_xml
62
+ else
63
+ body
64
+ end
65
+ end
66
+ )
67
+ end
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{httparty}
8
- s.version = "0.4.5"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-09-12}
11
+ s.authors = ["John Nunemaker", "Sandro Turriate"]
12
+ s.date = %q{2009-12-07}
13
13
  s.default_executable = %q{httparty}
14
14
  s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
15
15
  s.email = %q{nunemaker@gmail.com}
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  "cucumber.yml",
30
30
  "examples/aaws.rb",
31
31
  "examples/basic.rb",
32
+ "examples/custom_parsers.rb",
32
33
  "examples/delicious.rb",
33
34
  "examples/google.rb",
34
35
  "examples/rubyurl.rb",
@@ -51,6 +52,7 @@ Gem::Specification.new do |s|
51
52
  "lib/httparty/core_extensions.rb",
52
53
  "lib/httparty/exceptions.rb",
53
54
  "lib/httparty/module_inheritable_attributes.rb",
55
+ "lib/httparty/parser.rb",
54
56
  "lib/httparty/request.rb",
55
57
  "lib/httparty/response.rb",
56
58
  "lib/httparty/version.rb",
@@ -61,6 +63,7 @@ Gem::Specification.new do |s|
61
63
  "spec/fixtures/twitter.xml",
62
64
  "spec/fixtures/undefined_method_add_node_for_nil.xml",
63
65
  "spec/httparty/cookie_hash_spec.rb",
66
+ "spec/httparty/parser_spec.rb",
64
67
  "spec/httparty/request_spec.rb",
65
68
  "spec/httparty/response_spec.rb",
66
69
  "spec/httparty_spec.rb",
@@ -69,21 +72,23 @@ Gem::Specification.new do |s|
69
72
  "website/css/common.css",
70
73
  "website/index.html"
71
74
  ]
72
- s.has_rdoc = true
73
75
  s.homepage = %q{http://httparty.rubyforge.org}
74
76
  s.post_install_message = %q{When you HTTParty, you must party hard!}
75
77
  s.rdoc_options = ["--charset=UTF-8"]
76
78
  s.require_paths = ["lib"]
77
- s.rubygems_version = %q{1.3.1}
79
+ s.rubyforge_project = %q{httparty}
80
+ s.rubygems_version = %q{1.3.5}
78
81
  s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
79
82
  s.test_files = [
80
83
  "spec/httparty/cookie_hash_spec.rb",
84
+ "spec/httparty/parser_spec.rb",
81
85
  "spec/httparty/request_spec.rb",
82
86
  "spec/httparty/response_spec.rb",
83
87
  "spec/httparty_spec.rb",
84
88
  "spec/spec_helper.rb",
85
89
  "examples/aaws.rb",
86
90
  "examples/basic.rb",
91
+ "examples/custom_parsers.rb",
87
92
  "examples/delicious.rb",
88
93
  "examples/google.rb",
89
94
  "examples/rubyurl.rb",
@@ -93,17 +98,30 @@ Gem::Specification.new do |s|
93
98
 
94
99
  if s.respond_to? :specification_version then
95
100
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
96
- s.specification_version = 2
101
+ s.specification_version = 3
97
102
 
98
103
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
99
104
  s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
100
- s.add_development_dependency(%q<rspec>, ["= 1.2.8"])
105
+ s.add_development_dependency(%q<activesupport>, ["~> 2.3"])
106
+ s.add_development_dependency(%q<cucumber>, ["~> 0.4"])
107
+ s.add_development_dependency(%q<fakeweb>, ["~> 1.2"])
108
+ s.add_development_dependency(%q<mongrel>, ["~> 1.1"])
109
+ s.add_development_dependency(%q<rspec>, ["= 1.2.9"])
101
110
  else
102
111
  s.add_dependency(%q<crack>, [">= 0.1.1"])
103
- s.add_dependency(%q<rspec>, ["= 1.2.8"])
112
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
113
+ s.add_dependency(%q<cucumber>, ["~> 0.4"])
114
+ s.add_dependency(%q<fakeweb>, ["~> 1.2"])
115
+ s.add_dependency(%q<mongrel>, ["~> 1.1"])
116
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
104
117
  end
105
118
  else
106
119
  s.add_dependency(%q<crack>, [">= 0.1.1"])
107
- s.add_dependency(%q<rspec>, ["= 1.2.8"])
120
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
121
+ s.add_dependency(%q<cucumber>, ["~> 0.4"])
122
+ s.add_dependency(%q<fakeweb>, ["~> 1.2"])
123
+ s.add_dependency(%q<mongrel>, ["~> 1.1"])
124
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
108
125
  end
109
126
  end
127
+
@@ -11,20 +11,19 @@ require dir + 'httparty/module_inheritable_attributes'
11
11
  require dir + 'httparty/cookie_hash'
12
12
 
13
13
  module HTTParty
14
-
15
- AllowedFormats = {
16
- 'text/xml' => :xml,
17
- 'application/xml' => :xml,
18
- 'application/json' => :json,
19
- 'text/json' => :json,
20
- 'application/javascript' => :json,
21
- 'text/javascript' => :json,
22
- 'text/html' => :html,
23
- 'application/x-yaml' => :yaml,
24
- 'text/yaml' => :yaml,
25
- 'text/plain' => :plain
26
- } unless defined?(AllowedFormats)
27
-
14
+ module AllowedFormatsDeprecation
15
+ def const_missing(const)
16
+ if const.to_s =~ /AllowedFormats$/
17
+ Kernel.warn("Deprecated: Use HTTParty::Parser::SupportedFormats")
18
+ HTTParty::Parser::SupportedFormats
19
+ else
20
+ super
21
+ end
22
+ end
23
+ end
24
+
25
+ extend AllowedFormatsDeprecation
26
+
28
27
  def self.included(base)
29
28
  base.extend ClassMethods
30
29
  base.send :include, HTTParty::ModuleInheritableAttributes
@@ -33,8 +32,10 @@ module HTTParty
33
32
  base.instance_variable_set("@default_options", {})
34
33
  base.instance_variable_set("@default_cookies", CookieHash.new)
35
34
  end
36
-
35
+
37
36
  module ClassMethods
37
+ extend AllowedFormatsDeprecation
38
+
38
39
  # Allows setting http proxy information to be used
39
40
  #
40
41
  # class Foo
@@ -45,7 +46,7 @@ module HTTParty
45
46
  default_options[:http_proxyaddr] = addr
46
47
  default_options[:http_proxyport] = port
47
48
  end
48
-
49
+
49
50
  # Allows setting a base uri to be used for each request.
50
51
  # Will normalize uri to include http, etc.
51
52
  #
@@ -57,7 +58,7 @@ module HTTParty
57
58
  return default_options[:base_uri] unless uri
58
59
  default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
59
60
  end
60
-
61
+
61
62
  # Allows setting basic authentication username and password.
62
63
  #
63
64
  # class Foo
@@ -67,7 +68,7 @@ module HTTParty
67
68
  def basic_auth(u, p)
68
69
  default_options[:basic_auth] = {:username => u, :password => p}
69
70
  end
70
-
71
+
71
72
  # Allows setting default parameters to be appended to each request.
72
73
  # Great for api keys and such.
73
74
  #
@@ -80,7 +81,7 @@ module HTTParty
80
81
  default_options[:default_params] ||= {}
81
82
  default_options[:default_params].merge!(h)
82
83
  end
83
-
84
+
84
85
  # Allows setting a base uri to be used for each request.
85
86
  #
86
87
  # class Foo
@@ -97,7 +98,7 @@ module HTTParty
97
98
  raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash)
98
99
  default_cookies.add_cookies(h)
99
100
  end
100
-
101
+
101
102
  # Allows setting the format with which to parse.
102
103
  # Must be one of the allowed formats ie: json, xml
103
104
  #
@@ -105,47 +106,67 @@ module HTTParty
105
106
  # include HTTParty
106
107
  # format :json
107
108
  # end
108
- def format(f)
109
- raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.map { |v| v.to_s }.uniq.sort.join(', ')}" unless AllowedFormats.value?(f)
110
- default_options[:format] = f
109
+ def format(f = nil)
110
+ if f.nil?
111
+ default_options[:format]
112
+ else
113
+ parser(Parser) if parser.nil?
114
+ default_options[:format] = f
115
+ validate_format
116
+ end
111
117
  end
112
-
118
+
119
+ # Allows setting a PEM file to be used
120
+ #
121
+ # class Foo
122
+ # include HTTParty
123
+ # pem File.read('/home/user/my.pem')
124
+ # end
125
+ def pem(pem_contents)
126
+ default_options[:pem] = pem_contents
127
+ end
128
+
113
129
  # Allows setting a custom parser for the response.
114
130
  #
115
131
  # class Foo
116
132
  # include HTTParty
117
133
  # parser Proc.new {|data| ...}
118
134
  # end
119
- def parser(customer_parser)
120
- default_options[:parser] = customer_parser
135
+ def parser(customer_parser = nil)
136
+ if customer_parser.nil?
137
+ default_options[:parser]
138
+ else
139
+ default_options[:parser] = customer_parser
140
+ validate_format
141
+ end
121
142
  end
122
-
143
+
123
144
  # Allows making a get request to a url.
124
145
  #
125
146
  # class Foo
126
147
  # include HTTParty
127
148
  # end
128
- #
149
+ #
129
150
  # # Simple get with full url
130
151
  # Foo.get('http://foo.com/resource.json')
131
- #
152
+ #
132
153
  # # Simple get with full url and query parameters
133
154
  # # ie: http://foo.com/resource.json?limit=10
134
155
  # Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
135
156
  def get(path, options={})
136
157
  perform_request Net::HTTP::Get, path, options
137
158
  end
138
-
159
+
139
160
  # Allows making a post request to a url.
140
161
  #
141
162
  # class Foo
142
163
  # include HTTParty
143
164
  # end
144
- #
165
+ #
145
166
  # # Simple post with full url and setting the body
146
167
  # Foo.post('http://foo.com/resources', :body => {:bar => 'baz'})
147
168
  #
148
- # # Simple post with full url using :query option,
169
+ # # Simple post with full url using :query option,
149
170
  # # which gets set as form data on the request.
150
171
  # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
151
172
  def post(path, options={})
@@ -159,12 +180,21 @@ module HTTParty
159
180
  def delete(path, options={})
160
181
  perform_request Net::HTTP::Delete, path, options
161
182
  end
162
-
183
+
184
+ def head(path, options={})
185
+ perform_request Net::HTTP::Head, path, options
186
+ end
187
+
188
+ def options(path, options={})
189
+ perform_request Net::HTTP::Options, path, options
190
+ end
191
+
163
192
  def default_options #:nodoc:
164
193
  @default_options
165
194
  end
166
195
 
167
196
  private
197
+
168
198
  def perform_request(http_method, path, options) #:nodoc:
169
199
  options = default_options.dup.merge(options)
170
200
  process_cookies(options)
@@ -176,27 +206,33 @@ module HTTParty
176
206
  options[:headers] ||= headers.dup
177
207
  options[:headers]["cookie"] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string
178
208
  end
209
+
210
+ def validate_format
211
+ if format && parser.respond_to?(:supports_format?) && !parser.supports_format?(format)
212
+ raise UnsupportedFormat, "'#{format.inspect}' Must be one of: #{parser.supported_formats.map{|f| f.to_s}.sort.join(', ')}"
213
+ end
214
+ end
179
215
  end
180
216
 
181
217
  def self.normalize_base_uri(url) #:nodoc:
182
218
  normalized_url = url.dup
183
219
  use_ssl = (normalized_url =~ /^https/) || normalized_url.include?(':443')
184
220
  ends_with_slash = normalized_url =~ /\/$/
185
-
221
+
186
222
  normalized_url.chop! if ends_with_slash
187
223
  normalized_url.gsub!(/^https?:\/\//i, '')
188
-
224
+
189
225
  "http#{'s' if use_ssl}://#{normalized_url}"
190
226
  end
191
-
227
+
192
228
  class Basement #:nodoc:
193
229
  include HTTParty
194
230
  end
195
-
231
+
196
232
  def self.get(*args)
197
233
  Basement.get(*args)
198
234
  end
199
-
235
+
200
236
  def self.post(*args)
201
237
  Basement.post(*args)
202
238
  end
@@ -208,9 +244,20 @@ module HTTParty
208
244
  def self.delete(*args)
209
245
  Basement.delete(*args)
210
246
  end
247
+
248
+ def self.head(*args)
249
+ Basement.head(*args)
250
+ end
251
+
252
+ def self.options(*args)
253
+ Basement.options(*args)
254
+ end
255
+
211
256
  end
212
257
 
213
258
  require dir + 'httparty/core_extensions'
214
259
  require dir + 'httparty/exceptions'
260
+ require dir + 'httparty/parser'
215
261
  require dir + 'httparty/request'
216
262
  require dir + 'httparty/response'
263
+