aws-sdk-core 2.0.33 → 2.0.34

Sign up to get free protection for your applications and to get access to all the features.
@@ -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