Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

XML requests and responses

  • Loading branch information...
commit e839f5a653757e76b704707926b6056f2e16f63c 1 parent d711bdf
@mboeh authored
View
1  lib/naws.rb
@@ -20,3 +20,4 @@ def self.build(message)
require 'naws/authentication'
require 'naws/response'
require 'naws/request'
+require 'naws/xml_rest_request'
View
21 lib/naws/request.rb
@@ -1,9 +1,19 @@
require 'time'
+# The base class for all AWS requests. You should not use this class directly.
+# Its subclasses provide the functionality for specific types of AWS request.
+# This class handles basic configuration, header management, URI generation,
+# and authentication.
class Naws::Request
attr_reader :path, :method, :response_class
+ # Constructs a new AWS request object.
+ # +context+ must be a Naws::Context.
+ # +params+ is a hash of arguments used to construct the XML body or query
+ # string.
+ # +options+ contains any values used to configure the request which are not
+ # included in the XML body or query string (headers, for example).
def initialize(context, params = {}, options = {})
@context = context
@params = params.dup
@@ -15,23 +25,24 @@ def initialize(context, params = {}, options = {})
freeze
end
+ # Returns a frozen hash of HTTP headers for this request.
def headers
@output_headers ||= begin
h = @headers.dup
h["x-amz-date"] = date_header
h["X-Amzn-Authorization"] = auth_header
- h
+ h.freeze
end
end
- def to_xml
- ""
- end
-
+ # Forwards this request to its context to be executed via the selected
+ # transport.
def execute
@context.execute_request(self)
end
+ # The URI to which this request will be sent, including the query string.
+ # Returns a URI object.
def uri
new_uri = @context.uri.dup
new_uri.path = new_uri.path + @path
View
6 lib/naws/response.rb
@@ -1,3 +1,9 @@
class Naws::Response
+ def initialize(options = {})
+ @status = options[:status]
+ @body = options[:body]
+ @headers = options[:headers]
+ end
+
end
View
31 lib/naws/rexml_xml_parser.rb
@@ -0,0 +1,31 @@
+require 'naws/xml_parser'
+require 'rexml/document'
+require 'rexml/xpath'
+
+class Naws::RexmlXmlParser < Naws::XmlParser
+
+ def initialize(body)
+ @doc = REXML::Document.new(body)
+ end
+
+ def each(path, &blk)
+ REXML::XPath.each(@doc, path) do |ele|
+ blk.call ele # REXML::Element quacks like we need
+ end
+ end
+
+ def get(path)
+ texts = REXML::XPath.match(@doc, path)
+ texts = texts.map{|e| e.text }
+ if texts.length == 1
+ texts[0]
+ else
+ texts
+ end
+ end
+
+ def get_attr(path, attr)
+ raise NotImplementedError
+ end
+
+end
View
27 lib/naws/xml_parser.rb
@@ -0,0 +1,27 @@
+# A simplified XML parsing interface which should be sufficient to parse the
+# fairly simple, small XML documents AWS uses. This is an abstract superclass,
+# and you should use a subclass (like Naws::RexmlXmlParser).
+class Naws::XmlParser
+
+ Element = Struct.new(:name, :attr, :text)
+
+ def initialize(body)
+ # Empty
+ end
+ protected :initialize
+
+ def each(path, &blk)
+ raise NotImplementedError, "#each not implemented in this parser!"
+ end
+
+ def get(path)
+ raise NotImplementedError, "#get not implemented in this parser!"
+ end
+
+ protected
+
+ def element(name, attr, text)
+ Element.new(name, attr, text)
+ end
+
+end
View
25 lib/naws/xml_response.rb
@@ -0,0 +1,25 @@
+require 'naws/response'
+require 'naws/rexml_xml_parser'
+
+class Naws::XmlResponse < Naws::Response
+
+ @@parser_class = Naws::RexmlXmlParser
+ def self.parser_class() @@parser_class end
+ def self.parser_class=(v) @@parser_class = v end
+
+ def initialize(options = {})
+ super
+ @document = Naws::XmlResponse.parser_class.new(@body)
+ end
+
+ def xpath_each(path, &blk)
+ @document.each(path, &blk)
+ end
+
+ def xpath(path)
+ @document.get(path)
+ end
+
+ alias [] xpath
+
+end
View
23 lib/naws/xml_rest_request.rb
@@ -0,0 +1,23 @@
+require 'naws/request'
+require 'builder'
+
+# This type of AWS request is used for REST APIs which include an XML body.
+class Naws::XmlRestRequest < Naws::Request
+
+ def to_xml
+ x = Builder::XmlMarkup.new
+ x.instruct!
+ xml x
+ end
+
+ def http_body
+ to_xml
+ end
+
+ protected
+
+ def xml(x)
+ raise NotImplementedError, "Need to implement #xml if you're inheriting from XmlRestRequest"
+ end
+
+end
View
1  naws.gemspec
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
s.description = %q{TODO: Write a gem description}
s.rubyforge_project = "naws"
+ s.add_dependency 'builder', '~> 2.0'
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
Please sign in to comment.
Something went wrong with that request. Please try again.