httpserious 0.13.5.lstoll1

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.
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