mss-sdk 1.0.0

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 (131) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +9 -0
  3. data/LICENSE.txt +0 -0
  4. data/README.md +192 -0
  5. data/bin/mss-rb +178 -0
  6. data/ca-bundle.crt +3554 -0
  7. data/lib/mss/core/async_handle.rb +89 -0
  8. data/lib/mss/core/cacheable.rb +76 -0
  9. data/lib/mss/core/client.rb +786 -0
  10. data/lib/mss/core/collection/simple.rb +81 -0
  11. data/lib/mss/core/collection/with_limit_and_next_token.rb +70 -0
  12. data/lib/mss/core/collection/with_next_token.rb +96 -0
  13. data/lib/mss/core/collection.rb +262 -0
  14. data/lib/mss/core/configuration.rb +527 -0
  15. data/lib/mss/core/credential_providers.rb +653 -0
  16. data/lib/mss/core/data.rb +251 -0
  17. data/lib/mss/core/deprecations.rb +83 -0
  18. data/lib/mss/core/endpoints.rb +36 -0
  19. data/lib/mss/core/http/connection_pool.rb +374 -0
  20. data/lib/mss/core/http/curb_handler.rb +150 -0
  21. data/lib/mss/core/http/handler.rb +88 -0
  22. data/lib/mss/core/http/net_http_handler.rb +144 -0
  23. data/lib/mss/core/http/patch.rb +98 -0
  24. data/lib/mss/core/http/request.rb +258 -0
  25. data/lib/mss/core/http/response.rb +80 -0
  26. data/lib/mss/core/indifferent_hash.rb +87 -0
  27. data/lib/mss/core/inflection.rb +55 -0
  28. data/lib/mss/core/ini_parser.rb +41 -0
  29. data/lib/mss/core/json_client.rb +46 -0
  30. data/lib/mss/core/json_parser.rb +75 -0
  31. data/lib/mss/core/json_request_builder.rb +34 -0
  32. data/lib/mss/core/json_response_parser.rb +78 -0
  33. data/lib/mss/core/lazy_error_classes.rb +107 -0
  34. data/lib/mss/core/log_formatter.rb +426 -0
  35. data/lib/mss/core/managed_file.rb +31 -0
  36. data/lib/mss/core/meta_utils.rb +44 -0
  37. data/lib/mss/core/model.rb +61 -0
  38. data/lib/mss/core/naming.rb +29 -0
  39. data/lib/mss/core/option_grammar.rb +737 -0
  40. data/lib/mss/core/options/json_serializer.rb +81 -0
  41. data/lib/mss/core/options/validator.rb +154 -0
  42. data/lib/mss/core/options/xml_serializer.rb +117 -0
  43. data/lib/mss/core/page_result.rb +74 -0
  44. data/lib/mss/core/policy.rb +938 -0
  45. data/lib/mss/core/query_client.rb +40 -0
  46. data/lib/mss/core/query_error_parser.rb +23 -0
  47. data/lib/mss/core/query_request_builder.rb +46 -0
  48. data/lib/mss/core/query_response_parser.rb +34 -0
  49. data/lib/mss/core/region.rb +84 -0
  50. data/lib/mss/core/region_collection.rb +79 -0
  51. data/lib/mss/core/resource.rb +412 -0
  52. data/lib/mss/core/resource_cache.rb +39 -0
  53. data/lib/mss/core/response.rb +214 -0
  54. data/lib/mss/core/response_cache.rb +49 -0
  55. data/lib/mss/core/rest_error_parser.rb +23 -0
  56. data/lib/mss/core/rest_json_client.rb +39 -0
  57. data/lib/mss/core/rest_request_builder.rb +153 -0
  58. data/lib/mss/core/rest_response_parser.rb +65 -0
  59. data/lib/mss/core/rest_xml_client.rb +46 -0
  60. data/lib/mss/core/service_interface.rb +82 -0
  61. data/lib/mss/core/signers/base.rb +45 -0
  62. data/lib/mss/core/signers/cloud_front.rb +55 -0
  63. data/lib/mss/core/signers/s3.rb +158 -0
  64. data/lib/mss/core/signers/version_2.rb +71 -0
  65. data/lib/mss/core/signers/version_3.rb +85 -0
  66. data/lib/mss/core/signers/version_3_https.rb +60 -0
  67. data/lib/mss/core/signers/version_4/chunk_signed_stream.rb +190 -0
  68. data/lib/mss/core/signers/version_4.rb +227 -0
  69. data/lib/mss/core/uri_escape.rb +43 -0
  70. data/lib/mss/core/xml/frame.rb +245 -0
  71. data/lib/mss/core/xml/frame_stack.rb +84 -0
  72. data/lib/mss/core/xml/grammar.rb +306 -0
  73. data/lib/mss/core/xml/parser.rb +69 -0
  74. data/lib/mss/core/xml/root_frame.rb +64 -0
  75. data/lib/mss/core/xml/sax_handlers/libxml.rb +46 -0
  76. data/lib/mss/core/xml/sax_handlers/nokogiri.rb +55 -0
  77. data/lib/mss/core/xml/sax_handlers/ox.rb +40 -0
  78. data/lib/mss/core/xml/sax_handlers/rexml.rb +46 -0
  79. data/lib/mss/core/xml/stub.rb +122 -0
  80. data/lib/mss/core.rb +602 -0
  81. data/lib/mss/errors.rb +161 -0
  82. data/lib/mss/rails.rb +194 -0
  83. data/lib/mss/s3/access_control_list.rb +262 -0
  84. data/lib/mss/s3/acl_object.rb +263 -0
  85. data/lib/mss/s3/acl_options.rb +200 -0
  86. data/lib/mss/s3/bucket.rb +757 -0
  87. data/lib/mss/s3/bucket_collection.rb +161 -0
  88. data/lib/mss/s3/bucket_lifecycle_configuration.rb +472 -0
  89. data/lib/mss/s3/bucket_region_cache.rb +51 -0
  90. data/lib/mss/s3/bucket_tag_collection.rb +110 -0
  91. data/lib/mss/s3/bucket_version_collection.rb +78 -0
  92. data/lib/mss/s3/cipher_io.rb +119 -0
  93. data/lib/mss/s3/client/xml.rb +265 -0
  94. data/lib/mss/s3/client.rb +2076 -0
  95. data/lib/mss/s3/config.rb +60 -0
  96. data/lib/mss/s3/cors_rule.rb +107 -0
  97. data/lib/mss/s3/cors_rule_collection.rb +193 -0
  98. data/lib/mss/s3/data_options.rb +190 -0
  99. data/lib/mss/s3/encryption_utils.rb +145 -0
  100. data/lib/mss/s3/errors.rb +93 -0
  101. data/lib/mss/s3/multipart_upload.rb +353 -0
  102. data/lib/mss/s3/multipart_upload_collection.rb +75 -0
  103. data/lib/mss/s3/object_collection.rb +355 -0
  104. data/lib/mss/s3/object_metadata.rb +102 -0
  105. data/lib/mss/s3/object_upload_collection.rb +76 -0
  106. data/lib/mss/s3/object_version.rb +153 -0
  107. data/lib/mss/s3/object_version_collection.rb +88 -0
  108. data/lib/mss/s3/paginated_collection.rb +74 -0
  109. data/lib/mss/s3/policy.rb +73 -0
  110. data/lib/mss/s3/prefix_and_delimiter_collection.rb +46 -0
  111. data/lib/mss/s3/prefixed_collection.rb +84 -0
  112. data/lib/mss/s3/presign_v4.rb +135 -0
  113. data/lib/mss/s3/presigned_post.rb +574 -0
  114. data/lib/mss/s3/region_detection.rb +75 -0
  115. data/lib/mss/s3/request.rb +61 -0
  116. data/lib/mss/s3/s3_object.rb +1795 -0
  117. data/lib/mss/s3/tree/branch_node.rb +67 -0
  118. data/lib/mss/s3/tree/child_collection.rb +103 -0
  119. data/lib/mss/s3/tree/leaf_node.rb +93 -0
  120. data/lib/mss/s3/tree/node.rb +21 -0
  121. data/lib/mss/s3/tree/parent.rb +86 -0
  122. data/lib/mss/s3/tree.rb +115 -0
  123. data/lib/mss/s3/uploaded_part.rb +81 -0
  124. data/lib/mss/s3/uploaded_part_collection.rb +83 -0
  125. data/lib/mss/s3/website_configuration.rb +101 -0
  126. data/lib/mss/s3.rb +161 -0
  127. data/lib/mss/version.rb +16 -0
  128. data/lib/mss-sdk.rb +2 -0
  129. data/lib/mss.rb +14 -0
  130. data/rails/init.rb +14 -0
  131. metadata +201 -0
@@ -0,0 +1,144 @@
1
+ # Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ #
8
+ # or in the "license" file accompanying this file. This file is
9
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
10
+ # ANY KIND, either express or implied. See the License for the specific
11
+ # language governing permissions and limitations under the License.
12
+
13
+ module MSS
14
+ module Core
15
+ module Http
16
+
17
+ # # NetHttpHandler
18
+ #
19
+ # This is the default HTTP handler for the mss-sdk gem. It uses
20
+ # Ruby's Net::HTTP to make requests. It uses persistent connections
21
+ # and a connection pool.
22
+ #
23
+ class NetHttpHandler
24
+
25
+ class TruncatedBodyError < IOError; end
26
+
27
+ # @api private
28
+ NETWORK_ERRORS = [
29
+ SocketError, EOFError, IOError, Timeout::Error,
30
+ Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE,
31
+ Errno::EINVAL, Errno::ETIMEDOUT, Errno::EHOSTUNREACH,
32
+ OpenSSL::SSL::SSLError
33
+ ]
34
+
35
+ # (see ConnectionPool.new)
36
+ def initialize options = {}
37
+ @pool = options[:connection_pool] || ConnectionPool.new(options)
38
+ @verify_content_length = options[:verify_response_body_content_length]
39
+ end
40
+
41
+ # @return [ConnectionPool]
42
+ attr_reader :pool
43
+
44
+ # Given a populated request object and an empty response object,
45
+ # this method will make the request and them populate the
46
+ # response.
47
+ # @param [Request] request
48
+ # @param [Response] response
49
+ # @return [nil]
50
+ def handle request, response, &read_block
51
+ retry_possible = true
52
+
53
+ begin
54
+
55
+ @pool.session_for(request.endpoint) do |http|
56
+
57
+ http.read_timeout = request.read_timeout
58
+ http.continue_timeout = request.continue_timeout if
59
+ http.respond_to?(:continue_timeout=)
60
+
61
+ exp_length = nil
62
+ act_length = 0
63
+ http.request(build_net_http_request(request)) do |net_http_resp|
64
+ response.status = net_http_resp.code.to_i
65
+ response.headers = net_http_resp.to_hash
66
+ exp_length = determine_expected_content_length(response)
67
+ if block_given? and response.status < 300
68
+ net_http_resp.read_body do |data|
69
+ begin
70
+ act_length += data.bytesize
71
+ yield data unless data.empty?
72
+ ensure
73
+ retry_possible = false
74
+ end
75
+ end
76
+ else
77
+ response.body = net_http_resp.read_body
78
+ act_length += response.body.bytesize unless response.body.nil?
79
+ end
80
+ end
81
+ run_check = exp_length && request.http_method != "HEAD" && @verify_content_length
82
+ if run_check && act_length != exp_length
83
+ raise TruncatedBodyError, 'content-length does not match'
84
+ end
85
+ end
86
+
87
+ rescue *NETWORK_ERRORS => error
88
+ raise error unless retry_possible
89
+ response.network_error = error
90
+ end
91
+ nil
92
+ end
93
+
94
+ protected
95
+
96
+ def determine_expected_content_length response
97
+ if header = response.headers['content-length']
98
+ if header.is_a?(Array)
99
+ header.first.to_i
100
+ end
101
+ end
102
+ end
103
+
104
+ # Given an MSS::Core::HttpRequest, this method translates
105
+ # it into a Net::HTTPRequest (Get, Put, Post, Head or Delete).
106
+ # @param [Request] request
107
+ # @return [Net::HTTPRequest]
108
+ def build_net_http_request request
109
+
110
+ # Net::HTTP adds a content-type (1.8.7+) and accept-encoding (2.0.0+)
111
+ # to the request if these headers are not set. Setting a default
112
+ # empty value defeats this.
113
+ #
114
+ # Removing these are necessary for most services to no break request
115
+ # signatures as well as dynamodb crc32 checks (these fail if the
116
+ # response is gzipped).
117
+ headers = { 'content-type' => '', 'accept-encoding' => '' }
118
+
119
+ request.headers.each_pair do |key,value|
120
+ headers[key] = value.to_s
121
+ end
122
+
123
+ request_class = case request.http_method
124
+ when 'GET' then Net::HTTP::Get
125
+ when 'PUT' then Net::HTTP::Put
126
+ when 'POST' then Net::HTTP::Post
127
+ when 'HEAD' then Net::HTTP::Head
128
+ when 'DELETE' then Net::HTTP::Delete
129
+ else
130
+ msg = "unsupported http method: #{request.http_method}"
131
+ raise ArgumentError, msg
132
+ end
133
+
134
+ net_http_req = request_class.new(request.uri, headers)
135
+ net_http_req.body_stream = request.body_stream
136
+ net_http_req
137
+
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,98 @@
1
+ require 'net/http'
2
+
3
+ module MSS
4
+ module Core
5
+ module Http
6
+ # @api private
7
+ module Patches
8
+
9
+ def self.apply!
10
+ if RUBY_VERSION >= '2.0'
11
+ Net::HTTP.send(:include, Ruby_2)
12
+ elsif RUBY_VERSION >= '1.9.3'
13
+ Net::HTTP.send(:include, Ruby_1_9_3)
14
+ end
15
+ if RUBY_VERSION >= '1.9.3'
16
+ Net::HTTP.send(:alias_method, :old_transport_request, :transport_request)
17
+ Net::HTTP.send(:alias_method, :transport_request, :new_transport_request)
18
+ end
19
+ end
20
+
21
+ module Ruby_2
22
+ def new_transport_request(req)
23
+ count = 0
24
+ begin
25
+ begin_transport req
26
+ res = catch(:response) {
27
+ req.exec @socket, @curr_http_version, edit_path(req.path)
28
+ begin
29
+ res = Net::HTTPResponse.read_new(@socket)
30
+ res.decode_content = req.decode_content
31
+ end while res.kind_of?(Net::HTTPContinue)
32
+
33
+ res.uri = req.uri
34
+
35
+ res
36
+ }
37
+ res.reading_body(@socket, req.response_body_permitted?) {
38
+ yield res if block_given?
39
+ }
40
+ rescue Net::OpenTimeout
41
+ raise
42
+ rescue Net::ReadTimeout, IOError, EOFError,
43
+ Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE,
44
+ # avoid a dependency on OpenSSL
45
+ defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
46
+ Timeout::Error => exception
47
+ if count == 0 && Net::HTTP::IDEMPOTENT_METHODS_.include?(req.method)
48
+ count += 1
49
+ @socket.close if @socket and not @socket.closed?
50
+ D "Conn close because of error #{exception}, and retry"
51
+ if req.body_stream
52
+ if req.body_stream.respond_to?(:rewind)
53
+ req.body_stream.rewind
54
+ else
55
+ raise
56
+ end
57
+ end
58
+ retry
59
+ end
60
+ D "Conn close because of error #{exception}"
61
+ @socket.close if @socket and not @socket.closed?
62
+ raise
63
+ end
64
+
65
+ end_transport req, res
66
+ res
67
+ rescue => exception
68
+ D "Conn close because of error #{exception}"
69
+ @socket.close if @socket and not @socket.closed?
70
+ raise exception
71
+ end
72
+ end
73
+
74
+ module Ruby_1_9_3
75
+ def new_transport_request(req)
76
+ begin_transport req
77
+ res = catch(:response) {
78
+ req.exec @socket, @curr_http_version, edit_path(req.path)
79
+ begin
80
+ res = Net::HTTPResponse.read_new(@socket)
81
+ end while res.kind_of?(Net::HTTPContinue)
82
+ res
83
+ }
84
+ res.reading_body(@socket, req.response_body_permitted?) {
85
+ yield res if block_given?
86
+ }
87
+ end_transport req, res
88
+ res
89
+ rescue => exception
90
+ D "Conn close because of error #{exception}"
91
+ @socket.close if @socket and not @socket.closed?
92
+ raise exception
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,258 @@
1
+ # Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ #
8
+ # or in the "license" file accompanying this file. This file is
9
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
10
+ # ANY KIND, either express or implied. See the License for the specific
11
+ # language governing permissions and limitations under the License.
12
+
13
+ module MSS
14
+ module Core
15
+ module Http
16
+
17
+ # Base class for all service reqeusts. This class describes
18
+ # a basic HTTP request, but will not make one. It is consumed
19
+ # by a HTTP handler class that sends the actual request
20
+ # and parses the actual response.
21
+ class Request
22
+
23
+ extend Deprecations
24
+
25
+ # Returns a new empty http request object.
26
+ def initialize
27
+ @http_method = 'POST'
28
+ @use_ssl = true
29
+ @headers = CaseInsensitiveHash.new
30
+ @uri = '/'
31
+ @params = []
32
+ @read_timeout = 60
33
+ end
34
+
35
+ # @return [String] hostname of the request
36
+ attr_accessor :host
37
+
38
+ # @return [Integer] Returns the port number this request will be
39
+ # made via (usually 443 or 80).
40
+ attr_accessor :port
41
+
42
+ # @return [String] Returns the HTTP request method (e.g. 'GET', 'PUT',
43
+ # 'POST', 'HEAD' or 'DELETE'). Defaults to 'POST'.
44
+ attr_accessor :http_method
45
+
46
+ # @return [CaseInsensitiveHash] request headers
47
+ attr_accessor :headers
48
+
49
+ # @return [String] Returns the request URI (path + querystring).
50
+ attr_accessor :uri
51
+
52
+ # @return [String] The region name this request is for. Only needs
53
+ # to be populated for requests against signature v4 endpoints.
54
+ attr_accessor :region
55
+
56
+ # @api private
57
+ attr_accessor :service
58
+
59
+ # @return [String] Returns the MSS access key ID used to authorize the
60
+ # request.
61
+ # @api private
62
+ attr_accessor :access_key_id
63
+
64
+ # @return [Array<Param>] Returns an array of request params. Requests
65
+ # that use signature version 2 add params to the request and then
66
+ # sign those before building the {#body}. Normally the {#body}
67
+ # should be set directly with the HTTP payload.
68
+ # @api private
69
+ attr_accessor :params
70
+
71
+ # @return [String] The name of the service for Signature v4 signing.
72
+ # This does not always match the ruby name (e.g.
73
+ # simple_email_service and ses do not match).
74
+ attr_accessor :service_ruby_name
75
+
76
+ # @return [Integer] The number of seconds the service has to respond
77
+ # before a timeout error is raised on the request.
78
+ attr_accessor :read_timeout
79
+
80
+ alias_method :default_read_timeout, :read_timeout
81
+ deprecated :default_read_timeout, :use => :read_timeout
82
+
83
+ # @return [Boolean] Returns `true` if this request should be made
84
+ # with SSL enabled.
85
+ attr_accessor :use_ssl
86
+
87
+ alias_method :use_ssl?, :use_ssl
88
+
89
+ # @return [Float] timeout The number of seconds to wait for a
90
+ # 100-continue response before sending the HTTP request body.
91
+ # @api private
92
+ attr_accessor :continue_timeout
93
+
94
+ # @api private
95
+ def endpoint
96
+ scheme = use_ssl ? 'https' : 'http'
97
+ port = case scheme
98
+ when 'https' then self.port == 443 ? '' : ":#{self.port}"
99
+ when 'http' then self.port == 80 ? '' : ":#{self.port}"
100
+ end
101
+ "#{scheme}://#{host}#{port}"
102
+ end
103
+
104
+ # @return [Integer] Returns the port the request will be made over.
105
+ # Defaults to 443 for SSL requests and 80 for non-SSL requests.
106
+ def port
107
+ @port || (use_ssl? ? 443 : 80)
108
+ end
109
+
110
+ # @return [String] Returns the HTTP request path.
111
+ def path
112
+ uri.split(/\?/)[0]
113
+ end
114
+
115
+ # @return [String] Returns the HTTP request querystring.
116
+ def querystring
117
+ uri.split(/\?/)[1]
118
+ end
119
+
120
+ # Adds a request param.
121
+ #
122
+ # @overload add_param(param_name, param_value = nil)
123
+ # Add a param (name/value)
124
+ # @param [String] param_name
125
+ # @param [String] param_value Leave blank for sub resources
126
+ #
127
+ # @overload add_param(param_obj)
128
+ # Add a param (object)
129
+ # @param [Param] param_obj
130
+ #
131
+ # @api private
132
+ def add_param name_or_param, value = nil
133
+ if name_or_param.kind_of?(Param)
134
+ @params << name_or_param
135
+ else
136
+ @params << Param.new(name_or_param, value)
137
+ end
138
+ end
139
+
140
+ # @api private
141
+ def remove_param(name)
142
+ if param = @params.find { |p| p.name == name }
143
+ @params.delete(param)
144
+ end
145
+ end
146
+
147
+ # @api private
148
+ # @return [String,nil] Returns the url encoded request params. If there
149
+ # are no params, then nil is returned.
150
+ def url_encoded_params
151
+ params.empty? ? nil : params.sort.collect(&:encoded).join('&')
152
+ end
153
+
154
+ # @param [String] body
155
+ def body= body
156
+ @body = body
157
+ if body
158
+ headers['content-length'] = body.bytesize if body
159
+ else
160
+ headers.delete('content-length')
161
+ end
162
+ end
163
+
164
+ # @note Calling #body on a request with a #body_stream
165
+ # will cause the entire stream to be read into memory.
166
+ # @return [String,nil] Returns the request body.
167
+ def body
168
+ if @body
169
+ @body
170
+ elsif @body_stream
171
+ @body = @body_stream.read
172
+ if @body_stream.respond_to?(:rewind)
173
+ @body_stream.rewind
174
+ else
175
+ @body_stream = StringIO.new(@body)
176
+ end
177
+ @body
178
+ else
179
+ nil
180
+ end
181
+ end
182
+
183
+ # Sets the request body as an IO object that will be streamed.
184
+ # @note You must also set the #headers['content-length']
185
+ # @param [IO] stream An object that responds to #read and #eof.
186
+ def body_stream= stream
187
+ @body_stream = stream
188
+ end
189
+
190
+ # @return [IO,nil]
191
+ def body_stream
192
+ if @body_stream
193
+ @body_stream
194
+ elsif @body
195
+ StringIO.new(@body)
196
+ else
197
+ nil
198
+ end
199
+ end
200
+
201
+ # @api private
202
+ class CaseInsensitiveHash < Hash
203
+
204
+ def []= key, value
205
+ super(key.to_s.downcase, value)
206
+ end
207
+
208
+ def [] key
209
+ super(key.to_s.downcase)
210
+ end
211
+
212
+ def has_key?(key)
213
+ super(key.to_s.downcase)
214
+ end
215
+ alias_method :key?, :has_key?
216
+ alias_method :include?, :has_key?
217
+ alias_method :member?, :has_key?
218
+
219
+ end
220
+
221
+ # Represents a single request paramater. Some services accept this
222
+ # in a form encoded body string, others as query parameters.
223
+ # It is up to each service's Request class to determine how to
224
+ # consume these params.
225
+ # @api private
226
+ class Param
227
+
228
+ include UriEscape
229
+
230
+ attr_accessor :name, :value
231
+
232
+ def initialize name, value = nil
233
+ @name = name
234
+ @value = value
235
+ end
236
+
237
+ def <=> other
238
+ name <=> other.name
239
+ end
240
+
241
+ def to_s
242
+ value ? "#{name}=#{value}" : name
243
+ end
244
+
245
+ def ==(other)
246
+ other.kind_of?(Param) and to_s == other.to_s
247
+ end
248
+
249
+ def encoded
250
+ value ? "#{escape(name)}=#{escape(value)}" : "#{escape(name)}="
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,80 @@
1
+ # Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ #
8
+ # or in the "license" file accompanying this file. This file is
9
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
10
+ # ANY KIND, either express or implied. See the License for the specific
11
+ # language governing permissions and limitations under the License.
12
+
13
+ module MSS
14
+ module Core
15
+ module Http
16
+
17
+ # Represents the http response from a service request.
18
+ #
19
+ # Responses have:
20
+ #
21
+ # * status (200, 404, 500, etc)
22
+ # * headers (hash of response headers)
23
+ # * body (the response body)
24
+ class Response
25
+
26
+ # @return [Integer] Returns the http response status code.
27
+ attr_accessor :status
28
+
29
+ # @return [Hash] ({}) Returns the HTTP response headers.
30
+ attr_accessor :headers
31
+
32
+ # @return [String,nil] Returns the HTTP response body.
33
+ attr_accessor :body
34
+
35
+ # @return [Exception,nil]
36
+ attr_accessor :network_error
37
+
38
+ # @return [Boolean] Returns `true` if the request could not be made
39
+ # because of a networking issue (including timeouts).
40
+ def network_error?
41
+ @network_error ? true : false
42
+ end
43
+
44
+ # The #network_error attribute was previously #timeout, aliasing
45
+ # for backwards compatability
46
+ alias_method :timeout=, :network_error=
47
+
48
+ # @param [Hash] options
49
+ # @option options [Integer] :status (200) HTTP status code
50
+ # @option options [Hash] :headers ({}) HTTP response headers
51
+ # @option options [String] :body ('') HTTP response body
52
+ def initialize options = {}, &block
53
+ @status = options[:status] || 200
54
+ @headers = options[:headers] || {}
55
+ @body = options[:body]
56
+ yield(self) if block_given?
57
+ self
58
+ end
59
+
60
+ # Returns the header value with the given name.
61
+ #
62
+ # The value is matched case-insensitively so if the headers hash
63
+ # contains a key like 'Date' and you request the value for
64
+ # 'date' the 'Date' value will be returned.
65
+ #
66
+ # @param [String,Symbol] name The name of the header to fetch a value for.
67
+ # @return [String,nil] The value of the given header
68
+ def header name
69
+ headers.each_pair do |header_name, header_value|
70
+ if header_name.downcase == name.to_s.downcase
71
+ return header_value.is_a?(Array) ? header_value.first : header_value
72
+ end
73
+ end
74
+ nil
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,87 @@
1
+ # Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ #
8
+ # or in the "license" file accompanying this file. This file is
9
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
10
+ # ANY KIND, either express or implied. See the License for the specific
11
+ # language governing permissions and limitations under the License.
12
+
13
+ module MSS
14
+ module Core
15
+
16
+ # A utility class to provide indifferent access to hash data.
17
+ #
18
+ # Inspired by ActiveSupport's HashWithIndifferentAccess, this class
19
+ # has a few notable differences:
20
+ #
21
+ # * ALL keys are converted to strings (via #to_s)
22
+ # * It does not deep merge/convert hashes indifferently, good for fla
23
+ # * It will not perserve default value behaviours
24
+ #
25
+ # These features were omitted because our primary use for this class is to
26
+ # wrap a 1-level hash as a return value, but we want the user to access
27
+ # the values with string or symbol keys.
28
+ #
29
+ # @api private
30
+ class IndifferentHash < Hash
31
+
32
+ def initialize *args
33
+ if args.first.is_a?(Hash)
34
+ super()
35
+ merge!(*args)
36
+ else
37
+ super(*args)
38
+ end
39
+ end
40
+
41
+ alias_method :_getter, :[]
42
+ alias_method :_setter, :[]=
43
+
44
+ def []=(key, value)
45
+ _setter(_convert_key(key), value)
46
+ end
47
+ alias_method :store, :[]=
48
+
49
+ def [] key
50
+ _getter(_convert_key(key))
51
+ end
52
+
53
+ def merge! hash
54
+ hash.each_pair do |key,value|
55
+ self[key] = value
56
+ end
57
+ self
58
+ end
59
+ alias_method :update, :merge!
60
+
61
+ def merge hash
62
+ self.dup.merge!(hash)
63
+ end
64
+
65
+ def has_key? key
66
+ super(_convert_key(key))
67
+ end
68
+ alias_method :key?, :has_key?
69
+ alias_method :member?, :has_key?
70
+ alias_method :include?, :has_key?
71
+
72
+ def fetch key, *extras, &block
73
+ super(_convert_key(key), *extras, &block)
74
+ end
75
+
76
+ def delete key
77
+ super(_convert_key(key))
78
+ end
79
+
80
+ private
81
+ def _convert_key key
82
+ key.is_a?(String) ? key : key.to_s
83
+ end
84
+
85
+ end
86
+ end
87
+ end