aws-sdk-core 2.0.33 → 2.0.34

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.
@@ -62,7 +62,7 @@ module Aws
62
62
  end
63
63
 
64
64
  def empty_value?(value)
65
- value.nil? || value == [] || value == {}
65
+ value.nil? || value == '' || value == [] || value == {}
66
66
  end
67
67
 
68
68
  end
@@ -1,5 +1,3 @@
1
- require 'multi_xml'
2
-
3
1
  module Aws
4
2
  module Plugins
5
3
  class S3CompleteMultipartUploadFix < Seahorse::Client::Plugin
@@ -17,10 +15,10 @@ module Aws
17
15
  end
18
16
 
19
17
  def check_for_error(context)
20
- xml = MultiXml.parse(context.http_response.body_contents)
21
- if xml['Error']
22
- error_code = xml['Error']['Code']
23
- error_message = xml['Error']['Message']
18
+ xml = context.http_response.body_contents
19
+ if xml.match(/<Error>/)
20
+ error_code = xml.match(/<Code>(.+?)<\/Code>/)[1]
21
+ error_message = xml.match(/<Message>(.+?)<\/Message>/)[1]
24
22
  S3::Errors.error_class(error_code).new(context, error_message)
25
23
  end
26
24
  end
@@ -7,16 +7,9 @@ module Aws
7
7
  def call(context)
8
8
  @handler.call(context).on(200) do |response|
9
9
  response.data = Structure.new([:location_constraint])
10
- xml = MultiXml.parse(context.http_response.body_contents)
11
- if constraint = xml['LocationConstraint']
12
- response.data[:location_constraint] =
13
- case constraint
14
- when String then constraint
15
- when Hash then constraint['__content__'].to_s
16
- end
17
- else
18
- response.data[:location_constraint] = ''
19
- end
10
+ xml = context.http_response.body_contents
11
+ matches = xml.match(/>(.+?)<\/LocationConstraint>/)
12
+ response.data[:location_constraint] = matches ? matches[1] : ''
20
13
  end
21
14
  end
22
15
  end
@@ -51,25 +51,17 @@ module Aws
51
51
  now = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
52
52
  body_digest = options[:body_digest] || hexdigest(request.body)
53
53
 
54
- params = Query::ParamList.new
55
-
56
- request.headers['Host'] ||= request.endpoint.host
57
- request.headers.each do |header_name, header_value|
58
- if header_name.match(/^x-amz/)
59
- params.set(header_name, header_value)
60
- end
61
- unless %w(host content-type content-md5).include?(header_name)
62
- request.headers.delete(header_name)
63
- end
64
- end
54
+ request.headers['Host'] = request.endpoint.host
55
+ request.headers.delete('User-Agent')
65
56
 
57
+ params = Aws::Query::ParamList.new
66
58
  params.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256")
59
+ params.set("X-Amz-Credential", credential(now))
67
60
  params.set("X-Amz-Date", now)
68
- params.set("X-Amz-SignedHeaders", signed_headers(request))
69
61
  params.set("X-Amz-Expires", options[:expires_in].to_s)
62
+ params.set("X-Amz-SignedHeaders", signed_headers(request))
70
63
  params.set('X-Amz-Security-Token', credentials.session_token) if
71
64
  credentials.session_token
72
- params.set("X-Amz-Credential", credential(now))
73
65
 
74
66
  endpoint = request.endpoint
75
67
  if endpoint.query
@@ -63,7 +63,7 @@ module Aws
63
63
  when Struct
64
64
  obj.members.each.with_object({}) do |member, hash|
65
65
  value = obj[member]
66
- hash[member] = to_hash(value) unless value.nil?
66
+ hash[member] = to_hash(value) unless value == nil
67
67
  end
68
68
  when Hash
69
69
  obj.each.with_object({}) do |(key, value), hash|
@@ -1,3 +1,3 @@
1
1
  module Aws
2
- VERSION = '2.0.33'
2
+ VERSION = '2.0.34'
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'multi_xml'
1
+ require 'cgi'
2
2
 
3
3
  module Aws
4
4
  module Xml
@@ -14,22 +14,29 @@ module Aws
14
14
  private
15
15
 
16
16
  def error(context)
17
- if empty_body?(context)
18
- error_code = empty_body_error_code(context)
19
- error_message = ''
20
- else
21
- error_code, error_message = extract_error(context)
22
- end
17
+ body = context.http_response.body_contents
18
+ code, message = extract_error(body, context)
23
19
  svc = context.client.class.name.split('::')[1]
24
20
  errors_module = Aws.const_get(svc).const_get(:Errors)
25
- errors_module.error_class(error_code).new(context, error_message)
21
+ errors_module.error_class(code).new(context, message)
22
+ end
23
+
24
+ def extract_error(body, context)
25
+ [
26
+ error_code(body, context),
27
+ error_message(body),
28
+ ]
26
29
  end
27
30
 
28
- def empty_body?(context)
29
- context.http_response.body_contents.empty?
31
+ def error_code(body, context)
32
+ if matches = body.match(/<Code>(.+?)<\/Code>/)
33
+ remove_prefix(unescape(matches[1]), context)
34
+ else
35
+ http_status_error_code(context)
36
+ end
30
37
  end
31
38
 
32
- def empty_body_error_code(context)
39
+ def http_status_error_code(context)
33
40
  status_code = context.http_response.status_code
34
41
  {
35
42
  302 => 'MovedTemporarily',
@@ -42,15 +49,7 @@ module Aws
42
49
  }[status_code] || "Http#{status_code}Error"
43
50
  end
44
51
 
45
- def extract_error(context)
46
- error = MultiXml.parse(context.http_response.body_contents)
47
- %w(Response ErrorResponse Errors Error).each do |wrapper|
48
- error = error[wrapper] if error[wrapper]
49
- end
50
- [remove_prefix(context, error['Code']), error['Message']]
51
- end
52
-
53
- def remove_prefix(context, error_code)
52
+ def remove_prefix(error_code, context)
54
53
  if prefix = context.config.api.metadata('errorPrefix')
55
54
  error_code.sub(/^#{prefix}/, '')
56
55
  else
@@ -58,6 +57,18 @@ module Aws
58
57
  end
59
58
  end
60
59
 
60
+ def error_message(body)
61
+ if matches = body.match(/<Message>(.+?)<\/Message>/)
62
+ unescape(matches[1])
63
+ else
64
+ ''
65
+ end
66
+ end
67
+
68
+ def unescape(str)
69
+ CGI.unescapeHTML(str)
70
+ end
71
+
61
72
  end
62
73
  end
63
74
  end
@@ -1,139 +1,78 @@
1
- require 'multi_xml'
2
- require 'time'
3
- require 'base64'
4
-
5
1
  module Aws
6
2
  module Xml
3
+
4
+ # A SAX-style XML parser that uses a shape context to handle types.
7
5
  class Parser
8
6
 
7
+ autoload :Stack, 'aws-sdk-core/xml/parser/stack'
8
+ autoload :Frame, 'aws-sdk-core/xml/parser/frame'
9
+ autoload :ParsingError, 'aws-sdk-core/xml/parser/parsing_error'
10
+
11
+ autoload :LibxmlEngine, 'aws-sdk-core/xml/parser/engines/libxml'
12
+ autoload :NokogiriEngine, 'aws-sdk-core/xml/parser/engines/nokogiri'
13
+ autoload :OxEngine, 'aws-sdk-core/xml/parser/engines/ox'
14
+ autoload :RexmlEngine, 'aws-sdk-core/xml/parser/engines/rexml'
15
+
9
16
  # @param [Seahorse::Model::Shapes::Structure] shape
10
17
  def initialize(shape)
11
18
  @shape = shape
19
+ @engine = self.class.engine
12
20
  end
13
21
 
14
- # @param [String<xml>] xml
15
- # @param [Hash, nil] target
22
+ # @param [String] xml An XML document string to parse.
23
+ # @param [Structure] target (nil)
16
24
  # @return [Structure]
17
- def parse(xml, target = nil, &block)
18
- xml = MultiXml.parse(xml).values.first || {}
19
- yield(xml) if block_given?
20
- structure(@shape, xml, target)
21
- end
22
-
23
- private
24
-
25
- # @param [Seahorse::Model::Shapes::Structure] structure
26
- # @param [Hash] values
27
- # @param [Hash, nil] target
28
- # @return [Structure]
29
- def structure(structure, values, target = nil)
30
- target = Structure.new(structure.member_names) if target.nil?
31
- structure.members.each do |member_name, member_shape|
32
- value_key = member_key(member_shape) || member_name.to_s
33
- if values.key?(value_key)
34
- target[member_name] = parse_shape(member_shape, values[value_key])
35
- elsif member_shape.is_a?(Seahorse::Model::Shapes::List)
36
- target[member_name] = DefaultList.new
37
- elsif member_shape.is_a?(Seahorse::Model::Shapes::Map)
38
- target[member_name] = {}
39
- end
40
- end
41
- target
25
+ def parse(xml, target = nil)
26
+ xml = '<xml/>' if xml.nil? or xml.empty?
27
+ stack = Stack.new(@shape, target)
28
+ @engine.new(stack).parse(xml.to_s)
29
+ stack.result
42
30
  end
43
31
 
44
- def member_key(shape)
45
- if Seahorse::Model::Shapes::List === shape && flat?(shape)
46
- shape.member.location_name || shape.location_name
47
- else
48
- shape.location_name
49
- end
50
- end
32
+ class << self
51
33
 
52
- # @param [Seahorse::Model::Shapes::List] list
53
- # @param [Array] values
54
- # @return [Array]
55
- def list(list, values)
56
- unless flat?(list)
57
- values = values[list.member.location_name || 'member']
34
+ # @param [Symbol,Class] engine
35
+ # Must be one of the following values:
36
+ #
37
+ # * :ox
38
+ # * :libxml
39
+ # * :nokogiri
40
+ # * :rexml
41
+ #
42
+ def engine= engine
43
+ @engine = Class === engine ? engine : load_engine(engine)
58
44
  end
59
- values = [values] unless values.is_a?(Array)
60
- values.collect { |value| parse_shape(list.member, value) }
61
- end
62
45
 
63
- # @param [Seahorse::Model::Shapes::Map] map
64
- # @param [Hash] entries
65
- # @return [Hash]
66
- def map(map, entries)
67
- data = {}
68
- entries = entries['entry'] unless flat?(map)
69
- entries = [entries] unless entries.is_a?(Array)
70
- entries.each do |entry|
71
- key = entry[map.key.location_name || 'key']
72
- value = entry[map.value.location_name || 'value']
73
- data[parse_shape(map.key, key)] = parse_shape(map.value, value)
46
+ # @return [Class] Returns the default parsing engine.
47
+ # One of:
48
+ #
49
+ # * {OxEngine}
50
+ # * {LibxmlEngine}
51
+ # * {NokogiriEngine}
52
+ # * {RexmlEngine}
53
+ #
54
+ def engine
55
+ @engine
74
56
  end
75
- data
76
- end
77
57
 
78
- # @param [Seahorse::Model::Shapes::Shape] shape
79
- # @param [Object] value
80
- # @return [Object]
81
- def parse_shape(shape, value)
82
- if value.nil?
83
- case shape
84
- when Seahorse::Model::Shapes::Structure then structure(shape, {})
85
- when Seahorse::Model::Shapes::Map then {}
86
- when Seahorse::Model::Shapes::List then []
87
- when Seahorse::Model::Shapes::String then ''
88
- else nil
89
- end
90
- else
91
- case shape
92
- when Seahorse::Model::Shapes::String then string(shape, value)
93
- when Seahorse::Model::Shapes::Structure then structure(shape, value)
94
- when Seahorse::Model::Shapes::List then list(shape, value)
95
- when Seahorse::Model::Shapes::Map then map(shape, value)
96
- when Seahorse::Model::Shapes::Boolean then value == 'true'
97
- when Seahorse::Model::Shapes::Integer then value.to_i
98
- when Seahorse::Model::Shapes::Float then value.to_f
99
- when Seahorse::Model::Shapes::Timestamp then timestamp(value)
100
- when Seahorse::Model::Shapes::Blob then Base64.decode64(value)
101
- else
102
- raise "unhandled shape type: `#{shape.type}'"
103
- end
104
- end
105
- end
58
+ private
106
59
 
107
- def string(shape, value)
108
- if value.is_a?(Hash)
109
- decode_string(value)
110
- else
111
- value
60
+ def load_engine(name)
61
+ require "aws-sdk-core/xml/parser/engines/#{name}"
62
+ const_name = name[0].upcase + name[1..-1] + 'Engine'
63
+ const_get(const_name)
112
64
  end
113
- end
114
65
 
115
- def decode_string(value)
116
- case value['encoding']
117
- when 'base64' then Base64.decode64(value['__content__'])
118
- else value['__content__']
66
+ def try_load_engine(name)
67
+ load_engine(name)
68
+ rescue LoadError
69
+ false
119
70
  end
120
- end
121
71
 
122
- def timestamp(value)
123
- case value
124
- when nil then nil
125
- when /^\d+$/ then Time.at(value.to_i)
126
- else
127
- begin
128
- Time.parse(value)
129
- rescue ArgumentError
130
- raise "unhandled timestamp format `#{value}'"
131
- end
132
- end
133
72
  end
134
73
 
135
- def flat?(shape)
136
- !!shape.metadata('flattened')
74
+ self.engine = [:ox, :libxml, :nokogiri, :rexml].find do |name|
75
+ try_load_engine(name)
137
76
  end
138
77
 
139
78
  end
@@ -0,0 +1,42 @@
1
+ require 'libxml'
2
+
3
+ module Aws
4
+ module Xml
5
+ class Parser
6
+ class LibxmlEngine
7
+
8
+ include LibXML::XML::SaxParser::Callbacks
9
+
10
+ def initialize(stack)
11
+ @stack = stack
12
+ end
13
+
14
+ def parse(xml)
15
+ parser = ::LibXML::XML::SaxParser.string(xml)
16
+ parser.callbacks = self
17
+ parser.parse
18
+ end
19
+
20
+ def on_start_element_ns(element_name, attributes, *ignored)
21
+ @stack.start_element(element_name)
22
+ attributes.each do |attr_name, attr_value|
23
+ @stack.attr(attr_name, attr_value)
24
+ end
25
+ end
26
+
27
+ def on_end_element_ns(*ignored)
28
+ @stack.end_element
29
+ end
30
+
31
+ def on_characters(chars)
32
+ @stack.text(chars)
33
+ end
34
+
35
+ def on_error(msg)
36
+ @stack.error(msg)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ require 'nokogiri'
2
+
3
+ module Aws
4
+ module Xml
5
+ class Parser
6
+ class NokogiriEngine
7
+
8
+ def initialize(stack)
9
+ @stack = stack
10
+ end
11
+
12
+ def parse(xml)
13
+ Nokogiri::XML::SAX::Parser.new(self).parse(xml)
14
+ end
15
+
16
+ def xmldecl(*args); end
17
+ def start_document; end
18
+ def end_document; end
19
+ def comment(*args); end
20
+
21
+ def start_element_namespace(element_name, attributes = [], *ignored)
22
+ @stack.start_element(element_name)
23
+ attributes.each do |attr|
24
+ @stack.attr(attr.localname, attr.value)
25
+ end
26
+ end
27
+
28
+ def characters(chars)
29
+ @stack.text(chars)
30
+ end
31
+
32
+ def end_element_namespace(*ignored)
33
+ @stack.end_element
34
+ end
35
+
36
+ def error(msg)
37
+ @stack.error(msg)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end