httparty-responsibly 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +18 -0
  3. data/.gitignore +13 -0
  4. data/.rubocop.yml +92 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.simplecov +1 -0
  7. data/.travis.yml +11 -0
  8. data/CONTRIBUTING.md +23 -0
  9. data/Changelog.md +509 -0
  10. data/Gemfile +24 -0
  11. data/Guardfile +16 -0
  12. data/MIT-LICENSE +20 -0
  13. data/README.md +78 -0
  14. data/Rakefile +10 -0
  15. data/bin/httparty +123 -0
  16. data/cucumber.yml +1 -0
  17. data/docs/README.md +106 -0
  18. data/examples/README.md +86 -0
  19. data/examples/aaws.rb +32 -0
  20. data/examples/basic.rb +28 -0
  21. data/examples/body_stream.rb +14 -0
  22. data/examples/crack.rb +19 -0
  23. data/examples/custom_parsers.rb +68 -0
  24. data/examples/delicious.rb +37 -0
  25. data/examples/google.rb +16 -0
  26. data/examples/headers_and_user_agents.rb +10 -0
  27. data/examples/logging.rb +36 -0
  28. data/examples/microsoft_graph.rb +52 -0
  29. data/examples/multipart.rb +22 -0
  30. data/examples/nokogiri_html_parser.rb +19 -0
  31. data/examples/peer_cert.rb +9 -0
  32. data/examples/rescue_json.rb +17 -0
  33. data/examples/rubyurl.rb +14 -0
  34. data/examples/stackexchange.rb +24 -0
  35. data/examples/stream_download.rb +26 -0
  36. data/examples/tripit_sign_in.rb +44 -0
  37. data/examples/twitter.rb +31 -0
  38. data/examples/whoismyrep.rb +10 -0
  39. data/httparty-responsibly.gemspec +27 -0
  40. data/lib/httparty.rb +668 -0
  41. data/lib/httparty/connection_adapter.rb +254 -0
  42. data/lib/httparty/cookie_hash.rb +21 -0
  43. data/lib/httparty/exceptions.rb +33 -0
  44. data/lib/httparty/hash_conversions.rb +69 -0
  45. data/lib/httparty/headers_processor.rb +30 -0
  46. data/lib/httparty/logger/apache_formatter.rb +45 -0
  47. data/lib/httparty/logger/curl_formatter.rb +91 -0
  48. data/lib/httparty/logger/logger.rb +28 -0
  49. data/lib/httparty/logger/logstash_formatter.rb +59 -0
  50. data/lib/httparty/module_inheritable_attributes.rb +56 -0
  51. data/lib/httparty/net_digest_auth.rb +136 -0
  52. data/lib/httparty/parser.rb +150 -0
  53. data/lib/httparty/request.rb +386 -0
  54. data/lib/httparty/request/body.rb +84 -0
  55. data/lib/httparty/request/multipart_boundary.rb +11 -0
  56. data/lib/httparty/response.rb +140 -0
  57. data/lib/httparty/response/headers.rb +33 -0
  58. data/lib/httparty/response_fragment.rb +19 -0
  59. data/lib/httparty/text_encoder.rb +70 -0
  60. data/lib/httparty/utils.rb +11 -0
  61. data/lib/httparty/version.rb +3 -0
  62. data/script/release +42 -0
  63. data/website/css/common.css +47 -0
  64. data/website/index.html +73 -0
  65. metadata +138 -0
@@ -0,0 +1,11 @@
1
+ require 'securerandom'
2
+
3
+ module HTTParty
4
+ class Request
5
+ class MultipartBoundary
6
+ def self.generate
7
+ "------------------------#{SecureRandom.urlsafe_base64(12)}"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,140 @@
1
+ module HTTParty
2
+ class Response < Object
3
+ def self.underscore(string)
4
+ string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
5
+ end
6
+
7
+ def self._load(data)
8
+ req, resp, parsed_resp, resp_body = Marshal.load(data)
9
+
10
+ new(req, resp, -> { parsed_resp }, body: resp_body)
11
+ end
12
+
13
+ attr_reader :request, :response, :body, :headers
14
+
15
+ def initialize(request, response, parsed_block, options = {})
16
+ @request = request
17
+ @response = response
18
+ @body = options[:body] || response.body
19
+ @parsed_block = parsed_block
20
+ @headers = Headers.new(response.to_hash)
21
+
22
+ if request.options[:logger]
23
+ logger = ::HTTParty::Logger.build(
24
+ request.options[:logger],
25
+ request.options[:log_level],
26
+ request.options[:log_format]
27
+ )
28
+ logger.format(request, self)
29
+ end
30
+
31
+ throw_exception
32
+ end
33
+
34
+ def parsed_response
35
+ @parsed_response ||= @parsed_block.call
36
+ end
37
+
38
+ def code
39
+ response.code.to_i
40
+ end
41
+
42
+ def http_version
43
+ response.http_version
44
+ end
45
+
46
+ def tap
47
+ yield self
48
+ self
49
+ end
50
+
51
+ def inspect
52
+ inspect_id = ::Kernel::format "%x", (object_id * 2)
53
+ %(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
54
+ end
55
+
56
+ CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ
57
+
58
+ CODES_TO_OBJ.each do |response_code, klass|
59
+ name = klass.name.sub("Net::HTTP", '')
60
+ name = "#{underscore(name)}?".to_sym
61
+
62
+ define_method(name) do
63
+ klass === response
64
+ end
65
+ end
66
+
67
+ # Support old multiple_choice? method from pre 2.0.0 era.
68
+ if ::RUBY_VERSION >= "2.0.0" && ::RUBY_PLATFORM != "java"
69
+ alias_method :multiple_choice?, :multiple_choices?
70
+ end
71
+
72
+ # Support old status codes method from pre 2.6.0 era.
73
+ if ::RUBY_VERSION >= "2.6.0" && ::RUBY_PLATFORM != "java"
74
+ alias_method :gateway_time_out?, :gateway_timeout?
75
+ alias_method :request_entity_too_large?, :payload_too_large?
76
+ alias_method :request_time_out?, :request_timeout?
77
+ alias_method :request_uri_too_long?, :uri_too_long?
78
+ alias_method :requested_range_not_satisfiable?, :range_not_satisfiable?
79
+ end
80
+
81
+ def nil?
82
+ response.nil? || response.body.nil? || response.body.empty?
83
+ end
84
+
85
+ def to_s
86
+ if !response.nil? && !response.body.nil? && response.body.respond_to?(:to_s)
87
+ response.body.to_s
88
+ else
89
+ inspect
90
+ end
91
+ end
92
+
93
+ def pretty_print(pp)
94
+ if !parsed_response.nil? && parsed_response.respond_to?(:pretty_print)
95
+ parsed_response.pretty_print(pp)
96
+ else
97
+ super
98
+ end
99
+ end
100
+
101
+ def display(port=$>)
102
+ if !parsed_response.nil? && parsed_response.respond_to?(:display)
103
+ parsed_response.display(port)
104
+ elsif !response.nil? && !response.body.nil? && response.body.respond_to?(:display)
105
+ response.body.display(port)
106
+ else
107
+ port.write(inspect)
108
+ end
109
+ end
110
+
111
+ def respond_to_missing?(name, *args)
112
+ return true if super
113
+ parsed_response.respond_to?(name) || response.respond_to?(name)
114
+ end
115
+
116
+ def _dump(_level)
117
+ Marshal.dump([request, response, parsed_response, body])
118
+ end
119
+
120
+ protected
121
+
122
+ def method_missing(name, *args, &block)
123
+ if parsed_response.respond_to?(name)
124
+ parsed_response.send(name, *args, &block)
125
+ elsif response.respond_to?(name)
126
+ response.send(name, *args, &block)
127
+ else
128
+ super
129
+ end
130
+ end
131
+
132
+ def throw_exception
133
+ if @request.options[:raise_on] && @request.options[:raise_on].include?(code)
134
+ ::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}"
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ require 'httparty/response/headers'
@@ -0,0 +1,33 @@
1
+ require 'delegate'
2
+
3
+ module HTTParty
4
+ class Response #:nodoc:
5
+ class Headers < ::SimpleDelegator
6
+ include ::Net::HTTPHeader
7
+
8
+ def initialize(header_values = nil)
9
+ @header = {}
10
+ if header_values
11
+ header_values.each_pair do |k,v|
12
+ if v.is_a?(Array)
13
+ v.each do |sub_v|
14
+ add_field(k, sub_v)
15
+ end
16
+ else
17
+ add_field(k, v)
18
+ end
19
+ end
20
+ end
21
+ super(@header)
22
+ end
23
+
24
+ def ==(other)
25
+ if other.is_a?(::Net::HTTPHeader)
26
+ @header == other.instance_variable_get(:@header)
27
+ elsif other.is_a?(Hash)
28
+ @header == other || @header == Headers.new(other).instance_variable_get(:@header)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ require 'delegate'
2
+
3
+ module HTTParty
4
+ # Allow access to http_response and code by delegation on fragment
5
+ class ResponseFragment < SimpleDelegator
6
+ attr_reader :http_response, :connection
7
+
8
+ def code
9
+ @http_response.code.to_i
10
+ end
11
+
12
+ def initialize(fragment, http_response, connection)
13
+ @fragment = fragment
14
+ @http_response = http_response
15
+ @connection = connection
16
+ super fragment
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,70 @@
1
+ module HTTParty
2
+ class TextEncoder
3
+ attr_reader :text, :content_type, :assume_utf16_is_big_endian
4
+
5
+ def initialize(text, assume_utf16_is_big_endian: true, content_type: nil)
6
+ @text = text.dup
7
+ @content_type = content_type
8
+ @assume_utf16_is_big_endian = assume_utf16_is_big_endian
9
+ end
10
+
11
+ def call
12
+ if can_encode?
13
+ encoded_text
14
+ else
15
+ text
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def can_encode?
22
+ ''.respond_to?(:encoding) && charset
23
+ end
24
+
25
+ def encoded_text
26
+ if 'utf-16'.casecmp(charset) == 0
27
+ encode_utf_16
28
+ else
29
+ encode_with_ruby_encoding
30
+ end
31
+ end
32
+
33
+ def encode_utf_16
34
+ if text.bytesize >= 2
35
+ if text.getbyte(0) == 0xFF && text.getbyte(1) == 0xFE
36
+ return text.force_encoding("UTF-16LE")
37
+ elsif text.getbyte(0) == 0xFE && text.getbyte(1) == 0xFF
38
+ return text.force_encoding("UTF-16BE")
39
+ end
40
+ end
41
+
42
+ if assume_utf16_is_big_endian # option
43
+ text.force_encoding("UTF-16BE")
44
+ else
45
+ text.force_encoding("UTF-16LE")
46
+ end
47
+ end
48
+
49
+ def encode_with_ruby_encoding
50
+ # NOTE: This will raise an argument error if the
51
+ # charset does not exist
52
+ encoding = Encoding.find(charset)
53
+ text.force_encoding(encoding.to_s)
54
+ rescue ArgumentError
55
+ text
56
+ end
57
+
58
+ def charset
59
+ return nil if content_type.nil?
60
+
61
+ if (matchdata = content_type.match(/;\s*charset\s*=\s*([^=,;"\s]+)/i))
62
+ return matchdata.captures.first
63
+ end
64
+
65
+ if (matchdata = content_type.match(/;\s*charset\s*=\s*"((\\.|[^\\"])+)"/i))
66
+ return matchdata.captures.first.gsub(/\\(.)/, '\1')
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ module HTTParty
2
+ module Utils
3
+ def self.stringify_keys(hash)
4
+ return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys)
5
+
6
+ hash.each_with_object({}) do |(key, value), new_hash|
7
+ new_hash[key.to_s] = value
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module HTTParty
2
+ VERSION = "0.17.1"
3
+ end
@@ -0,0 +1,42 @@
1
+ #!/bin/sh
2
+ #/ Usage: release
3
+ #/
4
+ #/ Tag the version in the repo and push the gem.
5
+ #/
6
+
7
+ set -e
8
+ cd $(dirname "$0")/..
9
+
10
+ [ "$1" = "--help" -o "$1" = "-h" -o "$1" = "help" ] && {
11
+ grep '^#/' <"$0"| cut -c4-
12
+ exit 0
13
+ }
14
+
15
+ gem_name=httparty
16
+
17
+ # Build a new gem archive.
18
+ rm -rf $gem_name-*.gem
19
+ gem build -q $gem_name.gemspec
20
+
21
+ # Make sure we're on the master branch.
22
+ (git branch | grep -q '* master') || {
23
+ echo "Only release from the master branch."
24
+ exit 1
25
+ }
26
+
27
+ # Figure out what version we're releasing.
28
+ tag=v`ls $gem_name-*.gem | sed "s/^$gem_name-\(.*\)\.gem$/\1/"`
29
+
30
+ echo "Releasing $tag"
31
+
32
+ # Make sure we haven't released this version before.
33
+ git fetch -t origin
34
+
35
+ (git tag -l | grep -q "$tag") && {
36
+ echo "Whoops, there's already a '${tag}' tag."
37
+ exit 1
38
+ }
39
+
40
+ # Tag it and bag it.
41
+ gem push $gem_name-*.gem && git tag "$tag" &&
42
+ git push origin master && git push origin "$tag"
@@ -0,0 +1,47 @@
1
+ @media screen, projection {
2
+ /*
3
+ Copyright (c) 2007, Yahoo! Inc. All rights reserved.
4
+ Code licensed under the BSD License:
5
+ http://developer.yahoo.net/yui/license.txt
6
+ version: 2.2.0
7
+ */
8
+ body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;}
9
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;}
10
+ /* end of yahoo reset and fonts */
11
+
12
+ body {color:#333; background:#4b1a1a; line-height:1.3;}
13
+ p {margin:0 0 20px;}
14
+ a {color:#4b1a1a;}
15
+ a:hover {text-decoration:none;}
16
+ strong {font-weight:bold;}
17
+ em {font-style:italics;}
18
+ h1,h2,h3,h4,h5,h6 {font-weight:bold;}
19
+ h1 {font-size:197%; margin:30px 0; color:#4b1a1a;}
20
+ h2 {font-size:174%; margin:20px 0; color:#b8111a;}
21
+ h3 {font-size:152%; margin:10px 0;}
22
+ h4 {font-size:129%; margin:10px 0;}
23
+ pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;}
24
+ code {font-size:100%; margin:0; padding:0;}
25
+ ul, ol {margin:10px 0 10px 25px;}
26
+ ol li {margin:0 0 10px;}
27
+
28
+
29
+
30
+
31
+
32
+ div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #bc8c46; border-width:0 10px;}
33
+ div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;}
34
+ div#header p {margin:0; padding:0;}
35
+ div#header h1 {margin:0; padding:0;}
36
+ ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;}
37
+ ul#nav li {display:inline; padding:0 0 0 5px;}
38
+ ul#nav li a {}
39
+ div#content {}
40
+ div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;}
41
+
42
+
43
+
44
+
45
+
46
+
47
+ }
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>HTTParty by John Nunemaker</title>
6
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
7
+ </head>
8
+ <body>
9
+
10
+ <div id="wrapper">
11
+ <div id="header">
12
+ <h1>HTTParty</h1>
13
+ <p>Tonight we're gonna HTTParty like it's 1999!</p>
14
+
15
+ <ul id="nav">
16
+ <li><a href="rdoc/">Docs</a></li>
17
+ <li><a href="http://github.com/jnunemaker/httparty">Github</a></li>
18
+ <li><a href="http://rubyforge.org/projects/httparty/">Rubyforge</a></li>
19
+ </ul>
20
+ </div>
21
+
22
+ <div id="content">
23
+ <h2>Install</h2>
24
+ <pre><code>$ sudo gem install httparty</code></pre>
25
+
26
+ <h2>Some Quick Examples</h2>
27
+
28
+ <p>The following is a simple example of wrapping Twitter's API for posting updates.</p>
29
+
30
+ <pre><code>class Twitter
31
+ include HTTParty
32
+ base_uri 'twitter.com'
33
+ basic_auth 'username', 'password'
34
+ end
35
+
36
+ Twitter.post('/statuses/update.json', query: {status: "It's an HTTParty and everyone is invited!"})</code></pre>
37
+
38
+ <p>That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples). </p>
39
+
40
+ <p>That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:</p>
41
+
42
+ <pre><code>class Twitter
43
+ include HTTParty
44
+ base_uri 'twitter.com'
45
+
46
+ def initialize(u, p)
47
+ @auth = {username: u, password: p}
48
+ end
49
+
50
+ def post(text)
51
+ options = { query: {status: text}, basic_auth: @auth }
52
+ self.class.post('/statuses/update.json', options)
53
+ end
54
+ end
55
+
56
+ Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")</code></pre>
57
+
58
+ <p><strong>More Examples:</strong> There are <a href="http://github.com/jnunemaker/httparty/tree/master/examples/">several examples in the gem itself</a>.</p>
59
+
60
+ <h2>Support</h2>
61
+ <p>Conversations welcome in the <a href="http://groups.google.com/group/httparty-gem">google group</a> and bugs/features over at <a href="http://github.com/jnunemaker/httparty">Github</a>.</p>
62
+
63
+
64
+ </div>
65
+
66
+ <div id="footer">
67
+ <p>Created by <a href="http://addictedtonew.com/about/">John Nunemaker</a> |
68
+ <a href="http://orderedlist.com/">Hire Me at Ordered List</a></p>
69
+ </div>
70
+ </div>
71
+
72
+ </body>
73
+ </html>