httpserious 0.13.5.lstoll1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rubocop.yml +92 -0
  4. data/.rubocop_todo.yml +124 -0
  5. data/.simplecov +1 -0
  6. data/.travis.yml +7 -0
  7. data/CONTRIBUTING.md +23 -0
  8. data/Gemfile +19 -0
  9. data/Guardfile +16 -0
  10. data/History +370 -0
  11. data/MIT-LICENSE +20 -0
  12. data/README.md +78 -0
  13. data/Rakefile +10 -0
  14. data/bin/httparty +116 -0
  15. data/cucumber.yml +1 -0
  16. data/examples/README.md +67 -0
  17. data/examples/aaws.rb +32 -0
  18. data/examples/basic.rb +28 -0
  19. data/examples/crack.rb +19 -0
  20. data/examples/custom_parsers.rb +64 -0
  21. data/examples/delicious.rb +37 -0
  22. data/examples/google.rb +16 -0
  23. data/examples/headers_and_user_agents.rb +6 -0
  24. data/examples/logging.rb +36 -0
  25. data/examples/nokogiri_html_parser.rb +19 -0
  26. data/examples/rescue_json.rb +17 -0
  27. data/examples/rubyurl.rb +14 -0
  28. data/examples/stackexchange.rb +24 -0
  29. data/examples/tripit_sign_in.rb +33 -0
  30. data/examples/twitter.rb +31 -0
  31. data/examples/whoismyrep.rb +10 -0
  32. data/features/basic_authentication.feature +20 -0
  33. data/features/command_line.feature +90 -0
  34. data/features/deals_with_http_error_codes.feature +26 -0
  35. data/features/digest_authentication.feature +20 -0
  36. data/features/handles_compressed_responses.feature +27 -0
  37. data/features/handles_multiple_formats.feature +57 -0
  38. data/features/steps/env.rb +27 -0
  39. data/features/steps/httparty_response_steps.rb +52 -0
  40. data/features/steps/httparty_steps.rb +43 -0
  41. data/features/steps/mongrel_helper.rb +94 -0
  42. data/features/steps/remote_service_steps.rb +86 -0
  43. data/features/supports_read_timeout_option.feature +13 -0
  44. data/features/supports_redirection.feature +22 -0
  45. data/features/supports_timeout_option.feature +13 -0
  46. data/httparty.gemspec +28 -0
  47. data/httpserious.gemspec +25 -0
  48. data/lib/httparty.rb +612 -0
  49. data/lib/httparty/connection_adapter.rb +190 -0
  50. data/lib/httparty/cookie_hash.rb +21 -0
  51. data/lib/httparty/exceptions.rb +29 -0
  52. data/lib/httparty/hash_conversions.rb +49 -0
  53. data/lib/httparty/logger/apache_formatter.rb +22 -0
  54. data/lib/httparty/logger/curl_formatter.rb +48 -0
  55. data/lib/httparty/logger/logger.rb +26 -0
  56. data/lib/httparty/module_inheritable_attributes.rb +56 -0
  57. data/lib/httparty/net_digest_auth.rb +117 -0
  58. data/lib/httparty/parser.rb +141 -0
  59. data/lib/httparty/request.rb +361 -0
  60. data/lib/httparty/response.rb +77 -0
  61. data/lib/httparty/response/headers.rb +31 -0
  62. data/lib/httparty/version.rb +3 -0
  63. data/lib/httpserious.rb +1 -0
  64. data/script/release +42 -0
  65. data/spec/fixtures/delicious.xml +23 -0
  66. data/spec/fixtures/empty.xml +0 -0
  67. data/spec/fixtures/google.html +3 -0
  68. data/spec/fixtures/ssl/generate.sh +29 -0
  69. data/spec/fixtures/ssl/generated/1fe462c2.0 +16 -0
  70. data/spec/fixtures/ssl/generated/bogushost.crt +13 -0
  71. data/spec/fixtures/ssl/generated/ca.crt +16 -0
  72. data/spec/fixtures/ssl/generated/ca.key +15 -0
  73. data/spec/fixtures/ssl/generated/selfsigned.crt +14 -0
  74. data/spec/fixtures/ssl/generated/server.crt +13 -0
  75. data/spec/fixtures/ssl/generated/server.key +15 -0
  76. data/spec/fixtures/ssl/openssl-exts.cnf +9 -0
  77. data/spec/fixtures/twitter.csv +2 -0
  78. data/spec/fixtures/twitter.json +1 -0
  79. data/spec/fixtures/twitter.xml +403 -0
  80. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  81. data/spec/httparty/connection_adapter_spec.rb +468 -0
  82. data/spec/httparty/cookie_hash_spec.rb +83 -0
  83. data/spec/httparty/exception_spec.rb +38 -0
  84. data/spec/httparty/hash_conversions_spec.rb +41 -0
  85. data/spec/httparty/logger/apache_formatter_spec.rb +41 -0
  86. data/spec/httparty/logger/curl_formatter_spec.rb +18 -0
  87. data/spec/httparty/logger/logger_spec.rb +38 -0
  88. data/spec/httparty/net_digest_auth_spec.rb +191 -0
  89. data/spec/httparty/parser_spec.rb +167 -0
  90. data/spec/httparty/request_spec.rb +872 -0
  91. data/spec/httparty/response_spec.rb +241 -0
  92. data/spec/httparty/ssl_spec.rb +74 -0
  93. data/spec/httparty_spec.rb +823 -0
  94. data/spec/spec_helper.rb +59 -0
  95. data/spec/support/ssl_test_helper.rb +47 -0
  96. data/spec/support/ssl_test_server.rb +80 -0
  97. data/spec/support/stub_response.rb +43 -0
  98. data/website/css/common.css +47 -0
  99. data/website/index.html +73 -0
  100. metadata +219 -0
@@ -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,36 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'logger'
4
+ require 'pp'
5
+
6
+ my_logger = Logger.new "httparty.log"
7
+
8
+ my_logger.info "Logging can be used on the main HTTParty class. It logs redirects too."
9
+ HTTParty.get "http://google.com", logger: my_logger
10
+
11
+ my_logger.info '*' * 70
12
+
13
+ my_logger.info "It can be used also on a custom class."
14
+
15
+ class Google
16
+ include HTTParty
17
+ logger ::Logger.new "httparty.log"
18
+ end
19
+
20
+ Google.get "http://google.com"
21
+
22
+ my_logger.info '*' * 70
23
+
24
+ my_logger.info "The default formatter is :apache. The :curl formatter can also be used."
25
+ my_logger.info "You can tell wich method to call on the logger too. It is info by default."
26
+ HTTParty.get "http://google.com", logger: my_logger, log_level: :debug, log_format: :curl
27
+
28
+ my_logger.info '*' * 70
29
+
30
+ my_logger.info "These configs are also available on custom classes."
31
+ class Google
32
+ include HTTParty
33
+ logger ::Logger.new("httparty.log"), :debug, :curl
34
+ end
35
+
36
+ Google.get "http://google.com"
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require File.join(dir, 'httparty')
6
+ require 'pp'
7
+
8
+ class HtmlParserIncluded < HTTParty::Parser
9
+ def html
10
+ Nokogiri::HTML(body)
11
+ end
12
+ end
13
+
14
+ class Page
15
+ include HTTParty
16
+ parser HtmlParserIncluded
17
+ end
18
+
19
+ pp Page.get('http://www.google.com')
@@ -0,0 +1,17 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+
4
+ # Take note of the "; 1" at the end of the following line. It's required only if
5
+ # running this in IRB, because IRB will try to inspect the variable named
6
+ # "request", triggering the exception.
7
+ request = HTTParty.get 'https://rubygems.org/api/v1/versions/doesnotexist.json' ; 1
8
+
9
+ # Check an exception due to parsing the response
10
+ # because HTTParty evaluate the response lazily
11
+ begin
12
+ request.inspect
13
+ # This would also suffice by forcing the request to be parsed:
14
+ # request.parsed_response
15
+ rescue => e
16
+ puts "Rescued #{e.inspect}"
17
+ end
@@ -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,24 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class StackExchange
6
+ include HTTParty
7
+ base_uri 'api.stackexchange.com'
8
+
9
+ def initialize(service, page)
10
+ @options = { query: {site: service, page: page} }
11
+ end
12
+
13
+ def questions
14
+ self.class.get("/2.2/questions", @options)
15
+ end
16
+
17
+ def users
18
+ self.class.get("/2.2/users", @options)
19
+ end
20
+ end
21
+
22
+ stack_exchange = StackExchange.new("stackoverflow", 1)
23
+ pp stack_exchange.questions
24
+ pp stack_exchange.users
@@ -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')
@@ -0,0 +1,10 @@
1
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require File.join(dir, 'httparty')
3
+ require 'pp'
4
+
5
+ class Rep
6
+ include HTTParty
7
+ end
8
+
9
+ pp Rep.get('http://whoismyrepresentative.com/getall_mems.php?zip=46544')
10
+ pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', query: {zip: 46544})
@@ -0,0 +1,20 @@
1
+ Feature: Basic Authentication
2
+
3
+ As a developer
4
+ I want to be able to use a service that requires Basic Authentication
5
+ Because that is not an uncommon requirement
6
+
7
+ Scenario: Passing no credentials to a page requiring Basic Authentication
8
+ Given a restricted page at '/basic_auth.html'
9
+ When I call HTTParty#get with '/basic_auth.html'
10
+ Then it should return a response with a 401 response code
11
+
12
+ Scenario: Passing proper credentials to a page requiring Basic Authentication
13
+ Given a remote service that returns 'Authenticated Page'
14
+ And that service is accessed at the path '/basic_auth.html'
15
+ And that service is protected by Basic Authentication
16
+ And that service requires the username 'jcash' with the password 'maninblack'
17
+ When I call HTTParty#get with '/basic_auth.html' and a basic_auth hash:
18
+ | username | password |
19
+ | jcash | maninblack |
20
+ Then the return value should match 'Authenticated Page'
@@ -0,0 +1,90 @@
1
+ @command_line
2
+ Feature: Command Line
3
+
4
+ As a developer
5
+ I want to be able to harness the power of HTTParty from the command line
6
+ Because that would make quick testing and debugging easy
7
+
8
+ Scenario: Show help information
9
+ When I run `httparty --help`
10
+ Then the output should contain "-f, --format [FORMAT]"
11
+
12
+ Scenario: Make a get request
13
+ Given a remote deflate service on port '4001'
14
+ And the response from the service has a body of 'GET request'
15
+ And that service is accessed at the path '/fun'
16
+ When I run `httparty http://0.0.0.0:4001/fun`
17
+ Then the output should contain "GET request"
18
+
19
+ Scenario: Make a post request
20
+ Given a remote deflate service on port '4002'
21
+ And the response from the service has a body of 'POST request'
22
+ And that service is accessed at the path '/fun'
23
+ When I run `httparty http://0.0.0.0:4002/fun --action post --data "a=1&b=2"`
24
+ Then the output should contain "POST request"
25
+
26
+ Scenario: Make a put request
27
+ Given a remote deflate service on port '4003'
28
+ And the response from the service has a body of 'PUT request'
29
+ And that service is accessed at the path '/fun'
30
+ When I run `httparty http://0.0.0.0:4003/fun --action put --data "a=1&b=2"`
31
+ Then the output should contain "PUT request"
32
+
33
+ Scenario: Make a delete request
34
+ Given a remote deflate service on port '4004'
35
+ And the response from the service has a body of 'DELETE request'
36
+ And that service is accessed at the path '/fun'
37
+ When I run `httparty http://0.0.0.0:4004/fun --action delete`
38
+ Then the output should contain "DELETE request"
39
+
40
+ Scenario: Set a verbose mode
41
+ Given a remote deflate service on port '4005'
42
+ And the response from the service has a body of 'Some request'
43
+ And that service is accessed at the path '/fun'
44
+ When I run `httparty http://0.0.0.0:4005/fun --verbose`
45
+ Then the output should contain "content-length"
46
+
47
+ Scenario: Use service with basic authentication
48
+ Given a remote deflate service on port '4006'
49
+ And the response from the service has a body of 'Successfull authentication'
50
+ And that service is accessed at the path '/fun'
51
+ And that service is protected by Basic Authentication
52
+ And that service requires the username 'user' with the password 'pass'
53
+ When I run `httparty http://0.0.0.0:4006/fun --user 'user:pass'`
54
+ Then the output should contain "Successfull authentication"
55
+
56
+ Scenario: Get response in plain format
57
+ Given a remote deflate service on port '4007'
58
+ And the response from the service has a body of 'Some request'
59
+ And that service is accessed at the path '/fun'
60
+ When I run `httparty http://0.0.0.0:4007/fun --format plain`
61
+ Then the output should contain "Some request"
62
+
63
+ Scenario: Get response in json format
64
+ Given a remote deflate service on port '4008'
65
+ Given a remote service that returns '{ "jennings": "waylon", "cash": "johnny" }'
66
+ And that service is accessed at the path '/service.json'
67
+ And the response from the service has a Content-Type of 'application/json'
68
+ When I run `httparty http://0.0.0.0:4008/service.json --format json`
69
+ Then the output should contain '"jennings": "waylon"'
70
+
71
+ Scenario: Get response in xml format
72
+ Given a remote deflate service on port '4009'
73
+ Given a remote service that returns '<singer>waylon jennings</singer>'
74
+ And that service is accessed at the path '/service.xml'
75
+ And the response from the service has a Content-Type of 'text/xml'
76
+ When I run `httparty http://0.0.0.0:4009/service.xml --format xml`
77
+ Then the output should contain "<singer>"
78
+
79
+ Scenario: Get response in csv format
80
+ Given a remote deflate service on port '4010'
81
+ Given a remote service that returns:
82
+ """
83
+ "Last Name","Name"
84
+ "jennings","waylon"
85
+ "cash","johnny"
86
+ """
87
+ And that service is accessed at the path '/service.csv'
88
+ And the response from the service has a Content-Type of 'application/csv'
89
+ When I run `httparty http://0.0.0.0:4010/service.csv --format csv`
90
+ Then the output should contain '["Last Name", "Name"]'
@@ -0,0 +1,26 @@
1
+ Feature: Deals with HTTP error codes
2
+
3
+ As a developer
4
+ I want to be informed of non-successful responses
5
+ Because sometimes thing explode
6
+ And I should probably know what happened
7
+
8
+ Scenario: A response of '404 - Not Found'
9
+ Given a remote service that returns a 404 status code
10
+ And that service is accessed at the path '/404_service.html'
11
+ When I call HTTParty#get with '/404_service.html'
12
+ Then it should return a response with a 404 response code
13
+
14
+ Scenario: A response of '500 - Internal Server Error'
15
+ Given a remote service that returns a 500 status code
16
+ And that service is accessed at the path '/500_service.html'
17
+ When I call HTTParty#get with '/500_service.html'
18
+ Then it should return a response with a 500 response code
19
+
20
+ Scenario: A non-successful response where I need the body
21
+ Given a remote service that returns a 400 status code
22
+ And the response from the service has a body of 'Bad response'
23
+ And that service is accessed at the path '/400_service.html'
24
+ When I call HTTParty#get with '/400_service.html'
25
+ Then it should return a response with a 400 response code
26
+ And the return value should match 'Bad response'
@@ -0,0 +1,20 @@
1
+ Feature: Digest Authentication
2
+
3
+ As a developer
4
+ I want to be able to use a service that requires Digest Authentication
5
+ Because that is not an uncommon requirement
6
+
7
+ Scenario: Passing no credentials to a page requiring Digest Authentication
8
+ Given a restricted page at '/digest_auth.html'
9
+ When I call HTTParty#get with '/digest_auth.html'
10
+ Then it should return a response with a 401 response code
11
+
12
+ Scenario: Passing proper credentials to a page requiring Digest Authentication
13
+ Given a remote service that returns 'Digest Authenticated Page'
14
+ And that service is accessed at the path '/digest_auth.html'
15
+ And that service is protected by Digest Authentication
16
+ And that service requires the username 'jcash' with the password 'maninblack'
17
+ When I call HTTParty#get with '/digest_auth.html' and a digest_auth hash:
18
+ | username | password |
19
+ | jcash | maninblack |
20
+ Then the return value should match 'Digest Authenticated Page'
@@ -0,0 +1,27 @@
1
+ Feature: Handles Compressed Responses
2
+
3
+ In order to save bandwidth
4
+ As a developer
5
+ I want to uncompress compressed responses
6
+
7
+ Scenario: Supports deflate encoding
8
+ Given a remote deflate service
9
+ And the response from the service has a body of '<h1>Some HTML</h1>'
10
+ And that service is accessed at the path '/deflate_service.html'
11
+ When I call HTTParty#get with '/deflate_service.html'
12
+ Then the return value should match '<h1>Some HTML</h1>'
13
+
14
+ Scenario: Supports gzip encoding
15
+ Given a remote gzip service
16
+ And the response from the service has a body of '<h1>Some HTML</h1>'
17
+ And that service is accessed at the path '/gzip_service.html'
18
+ When I call HTTParty#get with '/gzip_service.html'
19
+ Then the return value should match '<h1>Some HTML</h1>'
20
+
21
+ Scenario: Supports HEAD request with gzip encoding
22
+ Given a remote gzip service
23
+ And that service is accessed at the path '/gzip_head.gz.js'
24
+ When I call HTTParty#head with '/gzip_head.gz.js'
25
+ Then it should return a response with a 200 response code
26
+ Then it should return a response with a gzip content-encoding
27
+ Then it should return a response with a blank body