alexvollmer-httparty 0.3.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/History CHANGED
@@ -1,3 +1,20 @@
1
+ == 0.4.5 2009-04-23
2
+ * 1 minor update
3
+ * added message to the response object
4
+
5
+ == 0.4.2 2009-03-30
6
+ * 2 minor changes
7
+ * response code now returns an integer instead of a string (jqr)
8
+ * rubyforge project setup for crack so i'm now depending on that instead of jnunemaker-crack
9
+
10
+ == 0.4.1 2009-03-29
11
+ * 1 minor fix
12
+ * gem 'jnunemaker-crack' instead of gem 'crack'
13
+
14
+ == 0.4.0 2009-03-29
15
+ * 1 minor change
16
+ * Switched xml and json parsing to crack (same code as before just moved to gem for easier reuse in other projects)
17
+
1
18
  == 0.3.1 2009-02-10
2
19
  * 1 minor fix, 1 minor enhancement
3
20
  * Fixed unescaping umlauts (siebertm)
data/Manifest CHANGED
@@ -19,13 +19,10 @@ features/steps/remote_service_steps.rb
19
19
  features/supports_redirection.feature
20
20
  History
21
21
  httparty.gemspec
22
- lib/core_extensions.rb
23
22
  lib/httparty/cookie_hash.rb
23
+ lib/httparty/core_extensions.rb
24
24
  lib/httparty/exceptions.rb
25
25
  lib/httparty/module_inheritable_attributes.rb
26
- lib/httparty/parsers/json.rb
27
- lib/httparty/parsers/xml.rb
28
- lib/httparty/parsers.rb
29
26
  lib/httparty/request.rb
30
27
  lib/httparty/response.rb
31
28
  lib/httparty/version.rb
@@ -43,8 +40,6 @@ spec/fixtures/twitter.xml
43
40
  spec/fixtures/undefined_method_add_node_for_nil.xml
44
41
  spec/hash_spec.rb
45
42
  spec/httparty/cookie_hash_spec.rb
46
- spec/httparty/parsers/json_spec.rb
47
- spec/httparty/parsers/xml_spec.rb
48
43
  spec/httparty/request_spec.rb
49
44
  spec/httparty/response_spec.rb
50
45
  spec/httparty_spec.rb
data/README CHANGED
@@ -15,7 +15,6 @@ Makes http fun again!
15
15
 
16
16
  See http://github.com/jnunemaker/httparty/tree/master/examples
17
17
 
18
-
19
18
  == COMMAND LINE INTERFACE
20
19
 
21
20
  httparty also includes the executable <tt>httparty</tt> which can be
@@ -29,8 +28,13 @@ options. Below is an example of how easy it is.
29
28
 
30
29
  == REQUIREMENTS:
31
30
 
31
+ * Crack http://github.com/jnunemaker/crack/ - For XML and JSON parsing.
32
32
  * You like to party!
33
33
 
34
34
  == INSTALL:
35
35
 
36
- * sudo gem install httparty
36
+ * sudo gem install httparty
37
+
38
+ == DOCS:
39
+
40
+ http://rdoc.info/projects/jnunemaker/httparty
data/Rakefile CHANGED
@@ -14,6 +14,7 @@ Echoe.new(ProjectName, HTTParty::Version) do |p|
14
14
  p.url = "http://#{ProjectName}.rubyforge.org"
15
15
  p.author = "John Nunemaker"
16
16
  p.email = "nunemaker@gmail.com"
17
+ p.extra_deps = [['crack', '>= 0.1.1']]
17
18
  p.need_tar_gz = false
18
19
  p.docs_host = WebsitePath
19
20
  end
@@ -12,11 +12,6 @@ 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
 
@@ -44,7 +39,7 @@ OptionParser.new do |o|
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
@@ -54,7 +49,7 @@ OptionParser.new do |o|
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
@@ -65,21 +60,37 @@ OptionParser.new do |o|
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
@@ -4,8 +4,8 @@ require 'pp'
4
4
 
5
5
  # You can also use post, put, delete in the same fashion
6
6
  response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
7
- puts response.body, response.code, response.headers.inspect
7
+ puts response.body, response.code, response.message, response.headers.inspect
8
8
 
9
9
  response.each do |item|
10
10
  puts item['user']['screen_name']
11
- end
11
+ end
@@ -17,7 +17,7 @@ Then /it should return a Hash equaling:/ do |hash_table|
17
17
  end
18
18
 
19
19
  Then /it should return a response with a (\d+) response code/ do |code|
20
- @response_from_httparty.code.should eql(code)
20
+ @response_from_httparty.code.should eql(code.to_i)
21
21
  end
22
22
 
23
23
  Then /it should raise an HTTParty::RedirectionTooDeep exception/ do
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{httparty}
5
- s.version = "0.3.1"
5
+ s.version = "0.4.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["John Nunemaker"]
9
- s.date = %q{2009-02-10}
9
+ s.date = %q{2009-04-23}
10
10
  s.default_executable = %q{httparty}
11
11
  s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
12
12
  s.email = %q{nunemaker@gmail.com}
13
13
  s.executables = ["httparty"]
14
- s.extra_rdoc_files = ["bin/httparty", "lib/core_extensions.rb", "lib/httparty/cookie_hash.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/parsers/json.rb", "lib/httparty/parsers/xml.rb", "lib/httparty/parsers.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "README"]
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/core_extensions.rb", "lib/httparty/cookie_hash.rb", "lib/httparty/exceptions.rb", "lib/httparty/module_inheritable_attributes.rb", "lib/httparty/parsers/json.rb", "lib/httparty/parsers/xml.rb", "lib/httparty/parsers.rb", "lib/httparty/request.rb", "lib/httparty/response.rb", "lib/httparty/version.rb", "lib/httparty.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README", "setup.rb", "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/hash_spec.rb", "spec/httparty/cookie_hash_spec.rb", "spec/httparty/parsers/json_spec.rb", "spec/httparty/parsers/xml_spec.rb", "spec/httparty/request_spec.rb", "spec/httparty/response_spec.rb", "spec/httparty_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/string_spec.rb", "website/css/common.css", "website/index.html"]
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"]
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", "setup.rb", "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/hash_spec.rb", "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", "spec/string_spec.rb", "website/css/common.css", "website/index.html"]
16
16
  s.has_rdoc = true
17
17
  s.homepage = %q{http://httparty.rubyforge.org}
18
18
  s.post_install_message = %q{When you HTTParty, you must party hard!}
@@ -27,11 +27,14 @@ Gem::Specification.new do |s|
27
27
  s.specification_version = 2
28
28
 
29
29
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
30
31
  s.add_development_dependency(%q<echoe>, [">= 0"])
31
32
  else
33
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
32
34
  s.add_dependency(%q<echoe>, [">= 0"])
33
35
  end
34
36
  else
37
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
35
38
  s.add_dependency(%q<echoe>, [">= 0"])
36
39
  end
37
40
  end
@@ -2,8 +2,10 @@ $:.unshift(File.dirname(__FILE__))
2
2
 
3
3
  require 'net/http'
4
4
  require 'net/https'
5
- require 'core_extensions'
6
5
  require 'httparty/module_inheritable_attributes'
6
+ require 'rubygems'
7
+ gem 'crack'
8
+ require 'crack'
7
9
 
8
10
  module HTTParty
9
11
 
@@ -16,7 +18,8 @@ module HTTParty
16
18
  'text/javascript' => :json,
17
19
  'text/html' => :html,
18
20
  'application/x-yaml' => :yaml,
19
- 'text/yaml' => :yaml
21
+ 'text/yaml' => :yaml,
22
+ 'text/plain' => :plain
20
23
  } unless defined?(AllowedFormats)
21
24
 
22
25
  def self.included(base)
@@ -99,7 +102,7 @@ module HTTParty
99
102
  # format :json
100
103
  # end
101
104
  def format(f)
102
- raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.join(', ')}" unless AllowedFormats.value?(f)
105
+ raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.uniq.join(', ')}" unless AllowedFormats.value?(f)
103
106
  default_options[:format] = f
104
107
  end
105
108
 
@@ -164,13 +167,14 @@ module HTTParty
164
167
  end
165
168
 
166
169
  def self.normalize_base_uri(url) #:nodoc:
167
- use_ssl = (url =~ /^https/) || url.include?(':443')
168
- ends_with_slash = url =~ /\/$/
170
+ normalized_url = url.dup
171
+ use_ssl = (normalized_url =~ /^https/) || normalized_url.include?(':443')
172
+ ends_with_slash = normalized_url =~ /\/$/
169
173
 
170
- url.chop! if ends_with_slash
171
- url.gsub!(/^https?:\/\//i, '')
174
+ normalized_url.chop! if ends_with_slash
175
+ normalized_url.gsub!(/^https?:\/\//i, '')
172
176
 
173
- "http#{'s' if use_ssl}://#{url}"
177
+ "http#{'s' if use_ssl}://#{normalized_url}"
174
178
  end
175
179
 
176
180
  class Basement #:nodoc:
@@ -195,7 +199,7 @@ module HTTParty
195
199
  end
196
200
 
197
201
  require 'httparty/cookie_hash'
202
+ require 'httparty/core_extensions'
198
203
  require 'httparty/exceptions'
199
204
  require 'httparty/request'
200
205
  require 'httparty/response'
201
- require 'httparty/parsers'
@@ -0,0 +1,25 @@
1
+ class BlankSlate #:nodoc:
2
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
3
+ end
4
+
5
+ # 1.8.6 has mistyping of transitive in if statement
6
+ require "rexml/document"
7
+ module REXML #:nodoc:
8
+ class Document < Element #:nodoc:
9
+ def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
10
+ if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
11
+ output = Output.new( output, xml_decl.encoding )
12
+ end
13
+ formatter = if indent > -1
14
+ if transitive
15
+ REXML::Formatters::Transitive.new( indent, ie_hack )
16
+ else
17
+ REXML::Formatters::Pretty.new( indent, ie_hack )
18
+ end
19
+ else
20
+ REXML::Formatters::Default.new( ie_hack )
21
+ end
22
+ formatter.write( self, output )
23
+ end
24
+ end
25
+ end
@@ -1,24 +1,24 @@
1
1
  require 'uri'
2
2
 
3
3
  module HTTParty
4
- class Request
4
+ class Request #:nodoc:
5
5
  SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete]
6
-
6
+
7
7
  attr_accessor :http_method, :path, :options
8
-
8
+
9
9
  def initialize(http_method, path, o={})
10
10
  self.http_method = http_method
11
11
  self.path = path
12
12
  self.options = {
13
- :limit => o.delete(:no_follow) ? 0 : 5,
14
- :default_params => {}
13
+ :limit => o.delete(:no_follow) ? 0 : 5,
14
+ :default_params => {},
15
15
  }.merge(o)
16
16
  end
17
17
 
18
18
  def path=(uri)
19
19
  @path = URI.parse(uri)
20
20
  end
21
-
21
+
22
22
  def uri
23
23
  new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
24
24
 
@@ -28,11 +28,11 @@ module HTTParty
28
28
 
29
29
  new_uri
30
30
  end
31
-
31
+
32
32
  def format
33
33
  options[:format]
34
34
  end
35
-
35
+
36
36
  def perform
37
37
  validate
38
38
  setup_raw_request
@@ -84,7 +84,7 @@ module HTTParty
84
84
  query_string_parts << options[:default_params].to_params unless options[:default_params].blank?
85
85
  query_string_parts << options[:query] unless options[:query].blank?
86
86
  end
87
-
87
+
88
88
  query_string_parts.size > 0 ? query_string_parts.join('&') : nil
89
89
  end
90
90
 
@@ -102,7 +102,7 @@ module HTTParty
102
102
  perform
103
103
  else
104
104
  parsed_response = parse_response(response.body)
105
- Response.new(parsed_response, response.body, response.code, response.to_hash)
105
+ Response.new(parsed_response, response.body, response.code, response.message, response.to_hash)
106
106
  end
107
107
  end
108
108
 
@@ -110,16 +110,16 @@ module HTTParty
110
110
  return nil if body.nil? or body.empty?
111
111
  case format
112
112
  when :xml
113
- HTTParty::Parsers::XML.parse(body)
113
+ Crack::XML.parse(body)
114
114
  when :json
115
- HTTParty::Parsers::JSON.decode(body)
115
+ Crack::JSON.parse(body)
116
116
  when :yaml
117
117
  YAML::load(body)
118
118
  else
119
119
  body
120
120
  end
121
121
  end
122
-
122
+
123
123
  # Uses the HTTP Content-Type header to determine the format of the response
124
124
  # It compares the MIME type returned to the types stored in the AllowedFormats hash
125
125
  def format_from_mimetype(mimetype)
@@ -133,7 +133,7 @@ module HTTParty
133
133
  raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
134
134
  raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash)
135
135
  end
136
-
136
+
137
137
  def post?
138
138
  Net::HTTP::Post == http_method
139
139
  end
@@ -1,12 +1,13 @@
1
1
  module HTTParty
2
2
  class Response < BlankSlate #:nodoc:
3
- attr_accessor :body, :code, :headers
3
+ attr_accessor :body, :code, :message, :headers
4
4
  attr_reader :delegate
5
5
 
6
- def initialize(delegate, body, code, headers={})
6
+ def initialize(delegate, body, code, message, headers={})
7
7
  @delegate = delegate
8
8
  @body = body
9
- @code = code
9
+ @code = code.to_i
10
+ @message = message
10
11
  @headers = headers
11
12
  end
12
13
 
@@ -1,3 +1,3 @@
1
1
  module HTTParty #:nodoc:
2
- Version = '0.3.1'
2
+ Version = '0.4.3'
3
3
  end
@@ -18,7 +18,7 @@ describe HTTParty::Request do
18
18
  before do
19
19
  @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
20
20
  end
21
-
21
+
22
22
  describe "#format" do
23
23
  it "should return the correct parsing format" do
24
24
  @request.format.should == :xml
@@ -30,7 +30,7 @@ describe HTTParty::Request do
30
30
  request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443')
31
31
  request.send(:http).use_ssl?.should == true
32
32
  end
33
-
33
+
34
34
  it 'should not use ssl for port 80' do
35
35
  request = HTTParty::Request.new(Net::HTTP::Get, 'http://foobar.com')
36
36
  @request.send(:http).use_ssl?.should == false
@@ -81,51 +81,13 @@ describe HTTParty::Request do
81
81
  end
82
82
  end
83
83
 
84
- describe '#format_from_mimetype' do
85
- it 'should handle text/xml' do
86
- ["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
87
- @request.send(:format_from_mimetype, ct).should == :xml
88
- end
89
- end
90
-
91
- it 'should handle application/xml' do
92
- ["application/xml", "application/xml; charset=iso8859-1"].each do |ct|
93
- @request.send(:format_from_mimetype, ct).should == :xml
94
- end
95
- end
96
-
97
- it 'should handle text/json' do
98
- ["text/json", "text/json; charset=iso8859-1"].each do |ct|
99
- @request.send(:format_from_mimetype, ct).should == :json
100
- end
101
- end
102
-
103
- it 'should handle application/json' do
104
- ["application/json", "application/json; charset=iso8859-1"].each do |ct|
105
- @request.send(:format_from_mimetype, ct).should == :json
106
- end
107
- end
108
-
109
- it 'should handle text/javascript' do
110
- ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
111
- @request.send(:format_from_mimetype, ct).should == :json
112
- end
113
- end
114
-
115
- it 'should handle application/javascript' do
116
- ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct|
117
- @request.send(:format_from_mimetype, ct).should == :json
118
- end
119
- end
120
- end
121
-
122
84
  describe 'parsing responses' do
123
85
  it 'should handle xml automatically' do
124
86
  xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
125
87
  @request.options[:format] = :xml
126
88
  @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
127
89
  end
128
-
90
+
129
91
  it 'should handle json automatically' do
130
92
  json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
131
93
  @request.options[:format] = :json
@@ -177,7 +139,7 @@ describe HTTParty::Request do
177
139
  it "should not fail for missing mime type" do
178
140
  stub_response "Content for you"
179
141
  @request.options[:format] = :html
180
- @request.perform.body.should == 'Content for you'
142
+ @request.perform.should == 'Content for you'
181
143
  end
182
144
 
183
145
  it "should drop query parameters when following redirects" do