yoyle439587298 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +14 -0
  5. data/Guardfile +16 -0
  6. data/History +303 -0
  7. data/LICENSE +21 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +80 -0
  10. data/Rakefile +12 -0
  11. data/bin/httparty +117 -0
  12. data/cucumber.yml +1 -0
  13. data/examples/aaws.rb +32 -0
  14. data/examples/basic.rb +32 -0
  15. data/examples/crack.rb +19 -0
  16. data/examples/custom_parsers.rb +67 -0
  17. data/examples/delicious.rb +37 -0
  18. data/examples/google.rb +16 -0
  19. data/examples/headers_and_user_agents.rb +6 -0
  20. data/examples/nokogiri_html_parser.rb +22 -0
  21. data/examples/rubyurl.rb +14 -0
  22. data/examples/tripit_sign_in.rb +33 -0
  23. data/examples/twitter.rb +31 -0
  24. data/examples/whoismyrep.rb +10 -0
  25. data/features/basic_authentication.feature +20 -0
  26. data/features/command_line.feature +7 -0
  27. data/features/deals_with_http_error_codes.feature +26 -0
  28. data/features/digest_authentication.feature +20 -0
  29. data/features/handles_compressed_responses.feature +27 -0
  30. data/features/handles_multiple_formats.feature +57 -0
  31. data/features/steps/env.rb +22 -0
  32. data/features/steps/httparty_response_steps.rb +52 -0
  33. data/features/steps/httparty_steps.rb +35 -0
  34. data/features/steps/mongrel_helper.rb +94 -0
  35. data/features/steps/remote_service_steps.rb +74 -0
  36. data/features/supports_redirection.feature +22 -0
  37. data/features/supports_timeout_option.feature +13 -0
  38. data/httparty.gemspec +26 -0
  39. data/lib/httparty.rb +578 -0
  40. data/lib/httparty/connection_adapter.rb +176 -0
  41. data/lib/httparty/cookie_hash.rb +22 -0
  42. data/lib/httparty/core_extensions.rb +32 -0
  43. data/lib/httparty/exceptions.rb +29 -0
  44. data/lib/httparty/hash_conversions.rb +51 -0
  45. data/lib/httparty/logger/apache_logger.rb +22 -0
  46. data/lib/httparty/logger/curl_logger.rb +48 -0
  47. data/lib/httparty/logger/logger.rb +18 -0
  48. data/lib/httparty/module_inheritable_attributes.rb +56 -0
  49. data/lib/httparty/net_digest_auth.rb +84 -0
  50. data/lib/httparty/parser.rb +141 -0
  51. data/lib/httparty/request.rb +330 -0
  52. data/lib/httparty/response.rb +72 -0
  53. data/lib/httparty/response/headers.rb +31 -0
  54. data/lib/httparty/version.rb +3 -0
  55. data/script/release +42 -0
  56. data/spec/fixtures/delicious.xml +23 -0
  57. data/spec/fixtures/empty.xml +0 -0
  58. data/spec/fixtures/google.html +3 -0
  59. data/spec/fixtures/ssl/generate.sh +29 -0
  60. data/spec/fixtures/ssl/generated/1fe462c2.0 +16 -0
  61. data/spec/fixtures/ssl/generated/bogushost.crt +13 -0
  62. data/spec/fixtures/ssl/generated/ca.crt +16 -0
  63. data/spec/fixtures/ssl/generated/ca.key +15 -0
  64. data/spec/fixtures/ssl/generated/selfsigned.crt +14 -0
  65. data/spec/fixtures/ssl/generated/server.crt +13 -0
  66. data/spec/fixtures/ssl/generated/server.key +15 -0
  67. data/spec/fixtures/ssl/openssl-exts.cnf +9 -0
  68. data/spec/fixtures/twitter.csv +2 -0
  69. data/spec/fixtures/twitter.json +1 -0
  70. data/spec/fixtures/twitter.xml +403 -0
  71. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  72. data/spec/httparty/connection_adapter_spec.rb +298 -0
  73. data/spec/httparty/cookie_hash_spec.rb +83 -0
  74. data/spec/httparty/exception_spec.rb +23 -0
  75. data/spec/httparty/logger/apache_logger_spec.rb +26 -0
  76. data/spec/httparty/logger/curl_logger_spec.rb +18 -0
  77. data/spec/httparty/logger/logger_spec.rb +22 -0
  78. data/spec/httparty/net_digest_auth_spec.rb +152 -0
  79. data/spec/httparty/parser_spec.rb +165 -0
  80. data/spec/httparty/request_spec.rb +631 -0
  81. data/spec/httparty/response_spec.rb +221 -0
  82. data/spec/httparty/ssl_spec.rb +74 -0
  83. data/spec/httparty_spec.rb +764 -0
  84. data/spec/spec.opts +2 -0
  85. data/spec/spec_helper.rb +37 -0
  86. data/spec/support/ssl_test_helper.rb +47 -0
  87. data/spec/support/ssl_test_server.rb +80 -0
  88. data/spec/support/stub_response.rb +43 -0
  89. data/website/css/common.css +47 -0
  90. data/website/index.html +73 -0
  91. metadata +208 -0
@@ -0,0 +1,12 @@
1
+ require 'spec/rake/spectask'
2
+ Spec::Rake::SpecTask.new(:spec) do |spec|
3
+ spec.ruby_opts << '-rubygems'
4
+ spec.libs << 'lib' << 'spec'
5
+ spec.spec_files = FileList['spec/**/*_spec.rb']
6
+ spec.spec_opts = ['--options', 'spec/spec.opts']
7
+ end
8
+
9
+ require 'cucumber/rake/task'
10
+ Cucumber::Rake::Task.new(:features)
11
+
12
+ task :default => [:spec, :features]
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "pp"
5
+
6
+ $:.unshift(File.join(File.dirname(__FILE__), "/../lib"))
7
+ require "httparty"
8
+
9
+ opts = {
10
+ :action => :get,
11
+ :headers => {},
12
+ :verbose => false
13
+ }
14
+
15
+ OptionParser.new do |o|
16
+ o.banner = "USAGE: #{$0} [options] [url]"
17
+
18
+ o.on("-f",
19
+ "--format [FORMAT]",
20
+ "Output format to use instead of pretty-print ruby: " +
21
+ "plain, csv, json or xml") do |f|
22
+ opts[:output_format] = f.downcase.to_sym
23
+ end
24
+
25
+ o.on("-a",
26
+ "--action [ACTION]",
27
+ "HTTP action: get (default), post, put, delete, head, or options") do |a|
28
+ opts[:action] = a.downcase.to_sym
29
+ end
30
+
31
+ o.on("-d",
32
+ "--data [BODY]",
33
+ "Data to put in request body (prefix with '@' for file)") do |d|
34
+ if d =~ /^@/
35
+ opts[:body] = open(d[1..-1]).read
36
+ else
37
+ opts[:body] = d
38
+ end
39
+ end
40
+
41
+ o.on("-H", "--header [NAME:VALUE]", "Additional HTTP headers in NAME:VALUE form") do |h|
42
+ abort "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/
43
+ name, value = h.split(':')
44
+ opts[:headers][name.strip] = value.strip
45
+ end
46
+
47
+ o.on("-v", "--verbose", "If set, print verbose output") do |v|
48
+ opts[:verbose] = true
49
+ end
50
+
51
+ o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u|
52
+ abort "Invalid credentials format. Must be user:password" unless u =~ /.*:.+/
53
+ user, password = u.split(':')
54
+ opts[:basic_auth] = { :username => user, :password => password }
55
+ end
56
+
57
+ o.on("-r", "--response-code", "Command fails if response code >= 400") do
58
+ opts[:response_code] = true
59
+ end
60
+
61
+ o.on("-h", "--help", "Show help documentation") do |h|
62
+ puts o
63
+ exit
64
+ end
65
+ end.parse!
66
+
67
+
68
+ if ARGV.empty?
69
+ STDERR.puts "You need to provide a URL"
70
+ STDERR.puts "USAGE: #{$0} [options] [url]"
71
+ end
72
+
73
+ def dump_headers(response)
74
+ resp_type = Net::HTTPResponse::CODE_TO_OBJ[response.code.to_s]
75
+ puts "#{response.code} #{resp_type.to_s.sub(/^Net::HTTP/, '')}"
76
+ response.headers.each do |n,v|
77
+ puts "#{n}: #{v}"
78
+ end
79
+ puts
80
+ end
81
+
82
+ if opts[:verbose]
83
+ puts "#{opts[:action].to_s.upcase} #{ARGV.first}"
84
+ opts[:headers].each do |n,v|
85
+ puts "#{n}: #{v}"
86
+ end
87
+ puts
88
+ end
89
+
90
+ response = HTTParty.send(opts[:action], ARGV.first, opts)
91
+ if opts[:output_format].nil?
92
+ dump_headers(response) if opts[:verbose]
93
+ pp response
94
+ else
95
+ print_format = opts[:output_format]
96
+ dump_headers(response) if opts[:verbose]
97
+
98
+ case opts[:output_format]
99
+ when :json
100
+ begin
101
+ require 'json'
102
+ puts JSON.pretty_generate(response.delegate)
103
+ rescue LoadError
104
+ puts YAML.dump(response.delegate)
105
+ end
106
+ when :xml
107
+ require 'rexml/document'
108
+ REXML::Document.new(response.body).write(STDOUT, 2)
109
+ puts
110
+ when :csv
111
+ require 'csv'
112
+ puts CSV.parse(response.body).map{|row| row.to_s }
113
+ else
114
+ puts response
115
+ end
116
+ end
117
+ exit false if opts[:response_code] && response.code >= 400
@@ -0,0 +1 @@
1
+ default: features --format progress
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+
4
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require File.join(dir, 'httparty')
6
+ require 'pp'
7
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.aaws')))
8
+
9
+ module AAWS
10
+ class Book
11
+ include HTTParty
12
+ base_uri 'http://ecs.amazonaws.com'
13
+ default_params :Service => 'AWSECommerceService', :Operation => 'ItemSearch', :SearchIndex => 'Books'
14
+
15
+ def initialize(key)
16
+ self.class.default_params :AWSAccessKeyId => key
17
+ end
18
+
19
+ def search(options={})
20
+ raise ArgumentError, 'You must search for something' if options[:query].blank?
21
+
22
+ # amazon uses nasty camelized query params
23
+ options[:query] = options[:query].inject({}) { |h, q| h[q[0].to_s.camelize] = q[1]; h }
24
+
25
+ # make a request and return the items (NOTE: this doesn't handle errors at this point)
26
+ self.class.get('/onca/xml', options)['ItemSearchResponse']['Items']
27
+ end
28
+ end
29
+ end
30
+
31
+ aaws = AAWS::Book.new(config[:access_key])
32
+ pp aaws.search(:query => {:title => 'Ruby On Rails'})
@@ -0,0 +1,32 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ # You can also use post, put, delete, head, options in the same fashion
6
+ response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
7
+ puts response.body, response.code, response.message, response.headers.inspect
8
+
9
+ response.each do |item|
10
+ puts item['user']['screen_name']
11
+ end
12
+
13
+ # An example post to a minimal rails app in the development environment
14
+ # Note that "skip_before_filter :verify_authenticity_token" must be set in the
15
+ # "pears" controller for this example
16
+
17
+ class Partay
18
+ include HTTParty
19
+ base_uri 'http://localhost:3000'
20
+ end
21
+
22
+ options = {
23
+ :body => {
24
+ :pear => { # your resource
25
+ :foo => '123', # your columns/data
26
+ :bar => 'second',
27
+ :baz => 'last thing'
28
+ }
29
+ }
30
+ }
31
+
32
+ pp Partay.post('/pears.xml', options)
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'crack'
3
+
4
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require File.join(dir, 'httparty')
6
+ require 'pp'
7
+
8
+ class Rep
9
+ include HTTParty
10
+
11
+ parser(
12
+ Proc.new do |body, format|
13
+ Crack::XML.parse(body)
14
+ end
15
+ )
16
+ end
17
+
18
+ pp Rep.get('http://whoismyrepresentative.com/getall_mems.php?zip=46544')
19
+ pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', :query => {:zip => 46544})
@@ -0,0 +1,67 @@
1
+ class ParseAtom
2
+ include HTTParty
3
+
4
+ # Support Atom along with the default parsers: xml, json, 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
@@ -0,0 +1,37 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.delicious')))
5
+
6
+ class Delicious
7
+ include HTTParty
8
+ base_uri 'https://api.del.icio.us/v1'
9
+
10
+ def initialize(u, p)
11
+ @auth = {:username => u, :password => p}
12
+ end
13
+
14
+ # query params that filter the posts are:
15
+ # tag (optional). Filter by this tag.
16
+ # dt (optional). Filter by this date (CCYY-MM-DDThh:mm:ssZ).
17
+ # url (optional). Filter by this url.
18
+ # ie: posts(:query => {:tag => 'ruby'})
19
+ def posts(options={})
20
+ options.merge!({:basic_auth => @auth})
21
+ self.class.get('/posts/get', options)
22
+ end
23
+
24
+ # query params that filter the posts are:
25
+ # tag (optional). Filter by this tag.
26
+ # count (optional). Number of items to retrieve (Default:15, Maximum:100).
27
+ def recent(options={})
28
+ options.merge!({:basic_auth => @auth})
29
+ self.class.get('/posts/recent', options)
30
+ end
31
+ end
32
+
33
+ delicious = Delicious.new(config['username'], config['password'])
34
+ pp delicious.posts(:query => {:tag => 'ruby'})
35
+ pp delicious.recent
36
+
37
+ delicious.recent['posts']['post'].each { |post| puts post['href'] }
@@ -0,0 +1,16 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Google
6
+ include HTTParty
7
+ format :html
8
+ end
9
+
10
+ # google.com redirects to www.google.com so this is live test for redirection
11
+ pp Google.get('http://google.com')
12
+
13
+ puts '', '*'*70, ''
14
+
15
+ # check that ssl is requesting right
16
+ pp Google.get('https://www.google.com')
@@ -0,0 +1,6 @@
1
+ # To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below.
2
+
3
+ require 'httparty'
4
+
5
+ APPLICATION_NAME = "Httparty"
6
+ response = HTTParty.get('http://example.com', :headers => {"User-Agent" => APPLICATION_NAME})
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+
5
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require File.join(dir, 'httparty')
7
+ require 'pp'
8
+
9
+ class HtmlParserIncluded < HTTParty::Parser
10
+ SupportedFormats.merge!('text/html' => :html)
11
+
12
+ def html
13
+ Nokogiri::HTML(body)
14
+ end
15
+ end
16
+
17
+ class Page
18
+ include HTTParty
19
+ parser HtmlParserIncluded
20
+ end
21
+
22
+ pp Page.get('http://www.google.com')
@@ -0,0 +1,14 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Rubyurl
6
+ include HTTParty
7
+ base_uri 'rubyurl.com'
8
+
9
+ def self.shorten( website_url )
10
+ post( '/api/links.json', :query => { :link => { :website_url => website_url } } )
11
+ end
12
+ end
13
+
14
+ pp Rubyurl.shorten( 'http://istwitterdown.com/')
@@ -0,0 +1,33 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+
4
+ class TripIt
5
+ include HTTParty
6
+ base_uri 'http://www.tripit.com'
7
+ debug_output
8
+
9
+ def initialize(email, password)
10
+ @email = email
11
+ response = self.class.get('/account/login')
12
+ response = self.class.post(
13
+ '/account/login',
14
+ :body => {
15
+ :login_email_address => email,
16
+ :login_password => password
17
+ },
18
+ :headers => {'Cookie' => response.headers['Set-Cookie']}
19
+ )
20
+ @cookie = response.request.options[:headers]['Cookie']
21
+ end
22
+
23
+ def account_settings
24
+ self.class.get('/account/edit', :headers => {'Cookie' => @cookie})
25
+ end
26
+
27
+ def logged_in?
28
+ account_settings.include? "You're logged in as #{@email}"
29
+ end
30
+ end
31
+
32
+ tripit = TripIt.new('email', 'password')
33
+ puts "Logged in: #{tripit.logged_in?}"
@@ -0,0 +1,31 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+ config = YAML::load(File.read(File.join(ENV['HOME'], '.twitter')))
5
+
6
+ class Twitter
7
+ include HTTParty
8
+ base_uri 'twitter.com'
9
+
10
+ def initialize(u, p)
11
+ @auth = {:username => u, :password => p}
12
+ end
13
+
14
+ # which can be :friends, :user or :public
15
+ # options[:query] can be things like since, since_id, count, etc.
16
+ def timeline(which=:friends, options={})
17
+ options.merge!({:basic_auth => @auth})
18
+ self.class.get("/statuses/#{which}_timeline.json", options)
19
+ end
20
+
21
+ def post(text)
22
+ options = { :query => {:status => text}, :basic_auth => @auth }
23
+ self.class.post('/statuses/update.json', options)
24
+ end
25
+ end
26
+
27
+ twitter = Twitter.new(config['email'], config['password'])
28
+ pp twitter.timeline
29
+ # pp twitter.timeline(:friends, :query => {:since_id => 868482746})
30
+ # pp twitter.timeline(:friends, :query => 'since_id=868482746')
31
+ # pp twitter.post('this is a test of 0.2.0')