amazon-mws 0.1.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 (116) hide show
  1. data/.gitignore +1 -0
  2. data/README.markdown +31 -0
  3. data/Rakefile +14 -0
  4. data/VERSION +1 -0
  5. data/amazon-mws.gemspec +164 -0
  6. data/examples/xml/cancel_feed_submissions.xml +16 -0
  7. data/examples/xml/cancel_report_requests.xml +18 -0
  8. data/examples/xml/error.xml +10 -0
  9. data/examples/xml/get_feed_submission_count.xml +10 -0
  10. data/examples/xml/get_feed_submission_list.xml +16 -0
  11. data/examples/xml/get_feed_submission_list_by_next_token.xml +16 -0
  12. data/examples/xml/get_feed_submission_result.xml +30 -0
  13. data/examples/xml/get_report_count.xml +9 -0
  14. data/examples/xml/get_report_list.xml +17 -0
  15. data/examples/xml/get_report_request_count.xml +8 -0
  16. data/examples/xml/get_report_request_list.xml +120 -0
  17. data/examples/xml/get_report_request_list_by_next_token.xml +20 -0
  18. data/examples/xml/get_report_schedule_count.xml +10 -0
  19. data/examples/xml/get_report_schedule_list.xml +15 -0
  20. data/examples/xml/get_report_schedule_list_by_next_token.xml +15 -0
  21. data/examples/xml/manage_report_schedule.xml +14 -0
  22. data/examples/xml/request_report.xml +17 -0
  23. data/examples/xml/submit_feed.xml +14 -0
  24. data/examples/xml/update_report_acknowledgements.xml +18 -0
  25. data/examples/xsd/Inventory.xsd +49 -0
  26. data/examples/xsd/Item.xsd +285 -0
  27. data/examples/xsd/Listings.xsd +32 -0
  28. data/examples/xsd/OrderAcknowledgement.xsd +55 -0
  29. data/examples/xsd/OrderAdjustment.xsd +94 -0
  30. data/examples/xsd/OrderFulfillment.xsd +57 -0
  31. data/examples/xsd/Override.xsd +48 -0
  32. data/examples/xsd/Price.xsd +59 -0
  33. data/examples/xsd/ProcessingReport.xsd +87 -0
  34. data/examples/xsd/Product.xsd +220 -0
  35. data/examples/xsd/Product/AutoAccessory.xsd +807 -0
  36. data/examples/xsd/Product/Beauty.xsd +114 -0
  37. data/examples/xsd/Product/CE.xsd +544 -0
  38. data/examples/xsd/Product/CameraPhoto.xsd +2410 -0
  39. data/examples/xsd/Product/FoodAndBeverages.xsd +270 -0
  40. data/examples/xsd/Product/Gourmet.xsd +85 -0
  41. data/examples/xsd/Product/Health.xsd +189 -0
  42. data/examples/xsd/Product/Home.xsd +654 -0
  43. data/examples/xsd/Product/Jewelry.xsd +603 -0
  44. data/examples/xsd/Product/Miscellaneous.xsd +157 -0
  45. data/examples/xsd/Product/MusicalInstruments.xsd +853 -0
  46. data/examples/xsd/Product/Office.xsd +550 -0
  47. data/examples/xsd/Product/PetSupplies.xsd +40 -0
  48. data/examples/xsd/Product/ProductClothing.xsd +197 -0
  49. data/examples/xsd/Product/SWVG.xsd +238 -0
  50. data/examples/xsd/Product/Sports.xsd +308 -0
  51. data/examples/xsd/Product/TiresAndWheels.xsd +159 -0
  52. data/examples/xsd/Product/Tools.xsd +66 -0
  53. data/examples/xsd/Product/ToysBaby.xsd +241 -0
  54. data/examples/xsd/Product/Wireless.xsd +77 -0
  55. data/examples/xsd/ProductImage.xsd +39 -0
  56. data/examples/xsd/Relationship.xsd +47 -0
  57. data/examples/xsd/SettlementReport.xsd +158 -0
  58. data/examples/xsd/amzn-base.xsd +1601 -0
  59. data/examples/xsd/amzn-envelope.xsd +98 -0
  60. data/examples/xsd/amzn-header.xsd +45 -0
  61. data/lib/amazon/mws.rb +86 -0
  62. data/lib/amazon/mws/authentication.rb +9 -0
  63. data/lib/amazon/mws/authentication/query_string.rb +28 -0
  64. data/lib/amazon/mws/authentication/signature.rb +43 -0
  65. data/lib/amazon/mws/base.rb +61 -0
  66. data/lib/amazon/mws/connection.rb +99 -0
  67. data/lib/amazon/mws/connection/management.rb +94 -0
  68. data/lib/amazon/mws/connection/request_builder.rb +67 -0
  69. data/lib/amazon/mws/exceptions.rb +80 -0
  70. data/lib/amazon/mws/feed.rb +223 -0
  71. data/lib/amazon/mws/feed_builder.rb +67 -0
  72. data/lib/amazon/mws/feed_enumerations.rb +46 -0
  73. data/lib/amazon/mws/feed_submission.rb +14 -0
  74. data/lib/amazon/mws/lib/extensions.rb +162 -0
  75. data/lib/amazon/mws/lib/memoizable.rb +10 -0
  76. data/lib/amazon/mws/orders.rb +9 -0
  77. data/lib/amazon/mws/report.rb +310 -0
  78. data/lib/amazon/mws/report_enumerations.rb +44 -0
  79. data/lib/amazon/mws/report_info.rb +16 -0
  80. data/lib/amazon/mws/report_request.rb +19 -0
  81. data/lib/amazon/mws/report_schedule.rb +13 -0
  82. data/lib/amazon/mws/response.rb +32 -0
  83. data/lib/amazon/mws/response/cancel_feed_submissions_response.rb +14 -0
  84. data/lib/amazon/mws/response/cancel_report_requests_response.rb +14 -0
  85. data/lib/amazon/mws/response/get_feed_submission_count_response.rb +13 -0
  86. data/lib/amazon/mws/response/get_feed_submission_list_by_next_token_response.rb +15 -0
  87. data/lib/amazon/mws/response/get_feed_submission_list_response.rb +15 -0
  88. data/lib/amazon/mws/response/get_feed_submission_result_response.rb +54 -0
  89. data/lib/amazon/mws/response/get_report_count_response.rb +13 -0
  90. data/lib/amazon/mws/response/get_report_list_response.rb +15 -0
  91. data/lib/amazon/mws/response/get_report_request_count_response.rb +13 -0
  92. data/lib/amazon/mws/response/get_report_request_list_by_next_token_response.rb +15 -0
  93. data/lib/amazon/mws/response/get_report_request_list_response.rb +15 -0
  94. data/lib/amazon/mws/response/get_report_schedule_count_response.rb +13 -0
  95. data/lib/amazon/mws/response/get_report_schedule_list_by_next_token_response.rb +15 -0
  96. data/lib/amazon/mws/response/get_report_schedule_list_response.rb +15 -0
  97. data/lib/amazon/mws/response/manage_report_schedule_response.rb +14 -0
  98. data/lib/amazon/mws/response/request_report_response.rb +14 -0
  99. data/lib/amazon/mws/response/response_error.rb +15 -0
  100. data/lib/amazon/mws/response/submit_feed_response.rb +13 -0
  101. data/lib/amazon/mws/response/update_reports_acknowledgements_response.rb +14 -0
  102. data/lib/amazon/mws/version.rb +12 -0
  103. data/pkg/amazon-mws-0.1.0.gem +0 -0
  104. data/test/authentication_test.rb +15 -0
  105. data/test/connection_test.rb +5 -0
  106. data/test/feed_builder_test.rb +15 -0
  107. data/test/feed_submission_test.rb +32 -0
  108. data/test/feed_test.rb +64 -0
  109. data/test/query_string_test.rb +21 -0
  110. data/test/report_test.rb +29 -0
  111. data/test/request_test.rb +18 -0
  112. data/test/response_test.rb +197 -0
  113. data/test/signature_test.rb +30 -0
  114. data/test/test_config.yml +5 -0
  115. data/test/test_helper.rb +22 -0
  116. metadata +179 -0
@@ -0,0 +1,98 @@
1
+ <?xml version="1.0"?>
2
+ <!-- Revision="$Revision: #6 $" -->
3
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
4
+ <!--
5
+ $Date: 2007/01/18 $
6
+
7
+ AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
8
+ confidential and proprietary information of Amazon.com and may not be reproduced,
9
+ distributed or used, in whole or in part, for any purpose other than as necessary
10
+ to list products for sale on the www.amazon.com web site pursuant to an agreement
11
+ with Amazon.com.
12
+ -->
13
+ <xsd:include schemaLocation="amzn-base.xsd"/>
14
+ <xsd:include schemaLocation="amzn-header.xsd"/>
15
+ <xsd:include schemaLocation="FulfillmentCenter.xsd"/>
16
+ <xsd:include schemaLocation="Inventory.xsd"/>
17
+ <xsd:include schemaLocation="Listings.xsd"/>
18
+ <xsd:include schemaLocation="OrderAcknowledgement.xsd"/>
19
+ <xsd:include schemaLocation="OrderAdjustment.xsd"/>
20
+ <xsd:include schemaLocation="OrderFulfillment.xsd"/>
21
+
22
+ <xsd:include schemaLocation="Override.xsd"/>
23
+ <xsd:include schemaLocation="Price.xsd"/>
24
+ <xsd:include schemaLocation="ProcessingReport.xsd"/>
25
+ <xsd:include schemaLocation="ProductImage.xsd"/>
26
+ <xsd:include schemaLocation="Product.xsd"/>
27
+ <xsd:include schemaLocation="Relationship.xsd"/>
28
+ <xsd:include schemaLocation="SettlementReport.xsd"/>
29
+ <xsd:element name="AmazonEnvelope">
30
+ <xsd:complexType>
31
+ <xsd:sequence>
32
+ <xsd:element ref="Header"/>
33
+ <xsd:element name="MessageType">
34
+ <xsd:simpleType>
35
+ <xsd:restriction base="xsd:string">
36
+ <xsd:enumeration value="FulfillmentCenter"/>
37
+ <xsd:enumeration value="Inventory"/>
38
+ <xsd:enumeration value="Listings"/>
39
+ <xsd:enumeration value="OrderAcknowledgement"/>
40
+ <xsd:enumeration value="OrderAdjustment"/>
41
+ <xsd:enumeration value="OrderFulfillment"/>
42
+ <xsd:enumeration value="Override"/>
43
+ <xsd:enumeration value="Price"/>
44
+ <xsd:enumeration value="ProcessingReport"/>
45
+ <xsd:enumeration value="Product"/>
46
+ <xsd:enumeration value="ProductImage"/>
47
+ <xsd:enumeration value="Relationship"/>
48
+ <xsd:enumeration value="SettlementReport"/>
49
+ </xsd:restriction>
50
+ </xsd:simpleType>
51
+ </xsd:element>
52
+ <xsd:element ref="MarketplaceName" minOccurs="0">
53
+ <xsd:annotation>
54
+ <xsd:documentation>
55
+ The MarketplaceName is only supported for
56
+ Override feeds.
57
+ If included here, the MarketplaceName will
58
+ apply to all messages in the feed.
59
+ </xsd:documentation>
60
+ </xsd:annotation>
61
+ </xsd:element>
62
+ <xsd:element name="PurgeAndReplace" type="xsd:boolean" minOccurs="0"/>
63
+ <xsd:element name="EffectiveDate" type="xsd:dateTime" minOccurs="0"/>
64
+ <xsd:element name="Message" maxOccurs="unbounded">
65
+ <xsd:complexType>
66
+ <xsd:sequence>
67
+ <xsd:element name="MessageID" type="IDNumber"/>
68
+ <xsd:element name="OperationType" minOccurs="0">
69
+ <xsd:simpleType>
70
+ <xsd:restriction base="xsd:string">
71
+ <xsd:enumeration value="Update"/>
72
+ <xsd:enumeration value="Delete"/>
73
+ <xsd:enumeration value="PartialUpdate"/>
74
+ </xsd:restriction>
75
+ </xsd:simpleType>
76
+ </xsd:element>
77
+ <xsd:choice>
78
+ <xsd:element ref="FulfillmentCenter"/>
79
+ <xsd:element ref="Inventory"/>
80
+ <xsd:element ref="Listings"/>
81
+ <xsd:element ref="OrderAcknowledgement"/>
82
+ <xsd:element ref="OrderAdjustment"/>
83
+ <xsd:element ref="OrderFulfillment"/>
84
+ <xsd:element ref="Override"/>
85
+ <xsd:element ref="Price"/>
86
+ <xsd:element ref="ProcessingReport"/>
87
+ <xsd:element ref="Product"/>
88
+ <xsd:element ref="ProductImage"/>
89
+ <xsd:element ref="Relationship"/>
90
+ <xsd:element ref="SettlementReport"/>
91
+ </xsd:choice>
92
+ </xsd:sequence>
93
+ </xsd:complexType>
94
+ </xsd:element>
95
+ </xsd:sequence>
96
+ </xsd:complexType>
97
+ </xsd:element>
98
+ </xsd:schema>
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0"?>
2
+ <!-- "$Revision: #3 $" -->
3
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
4
+
5
+ <!--
6
+ $Date: 2005/04/01 $
7
+
8
+ AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
9
+ confidential and proprietary information of Amazon.com and may not be reproduced,
10
+ distributed or used, in whole or in part, for any purpose other than as necessary
11
+ to list products for sale on the www.amazon.com web site pursuant to an agreement
12
+ with Amazon.com.
13
+ -->
14
+
15
+ <xsd:include schemaLocation="amzn-base.xsd"/>
16
+
17
+ <xsd:element name="Header">
18
+ <xsd:complexType>
19
+ <xsd:sequence>
20
+
21
+ <xsd:element name="DocumentVersion">
22
+ <xsd:simpleType>
23
+ <xsd:restriction base="xsd:string">
24
+ <xsd:pattern value="\d{1,2}\.\d{1,2}"/>
25
+ </xsd:restriction>
26
+ </xsd:simpleType>
27
+ </xsd:element>
28
+
29
+ <xsd:element name="MerchantIdentifier" type="String"/>
30
+
31
+ <xsd:element name="OverrideReleaseId" minOccurs="0">
32
+ <xsd:simpleType>
33
+ <xsd:restriction base="xsd:string">
34
+ <xsd:pattern value="\d{1,4}\.\d{1,4}"/>
35
+ </xsd:restriction>
36
+ </xsd:simpleType>
37
+ </xsd:element>
38
+
39
+ </xsd:sequence>
40
+ </xsd:complexType>
41
+ </xsd:element>
42
+
43
+ </xsd:schema>
44
+
45
+
@@ -0,0 +1,86 @@
1
+ require 'rubygems'
2
+ require 'cgi'
3
+ require 'uri'
4
+ require 'openssl'
5
+ require 'net/https'
6
+ require 'time'
7
+ require 'date'
8
+ require 'hmac'
9
+ require 'hmac-sha2'
10
+ require 'base64'
11
+ require 'builder'
12
+ require "rexml/document"
13
+
14
+ # ROXML - nokogiri and roxml are the only dependencies
15
+ I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 = true
16
+ # module ROXML
17
+ # XML_PARSER = 'nokogiri' # or 'libxml'
18
+ # end
19
+ require 'roxml'
20
+ # /ROXML
21
+
22
+
23
+ $:.unshift(File.dirname(__FILE__))
24
+ require 'mws/lib/extensions'
25
+ require 'builder'
26
+ #require_library_or_gem 'mime/types', 'mime-types' unless defined? MIME::Types
27
+
28
+ module Amazon
29
+ module MWS
30
+ end
31
+ end
32
+
33
+
34
+
35
+ require 'mws/lib/memoizable'
36
+
37
+ require 'mws/feed_builder'
38
+ require 'mws/feed_enumerations'
39
+ require 'mws/feed'
40
+ require 'mws/report_enumerations'
41
+ require 'mws/report'
42
+
43
+
44
+ require 'mws/response'
45
+ require 'mws/feed_submission'
46
+ require 'mws/report_request'
47
+ require 'mws/report_info'
48
+ require 'mws/report_schedule'
49
+ Dir.glob(File.join(File.dirname(__FILE__), 'mws/response/*.rb')).each {|f| require f }
50
+
51
+ require 'mws/base'
52
+ require 'mws/version'
53
+ require 'mws/exceptions'
54
+ require 'mws/connection'
55
+ require 'mws/connection/management'
56
+ require 'mws/connection/request_builder'
57
+ require 'mws/authentication'
58
+ require 'mws/authentication/query_string'
59
+ require 'mws/authentication/signature'
60
+
61
+
62
+ Amazon::MWS::Base.class_eval do
63
+ include Amazon::MWS::Feed
64
+ include Amazon::MWS::Report
65
+ end
66
+
67
+ AWS = Amazon
68
+
69
+ require_library_or_gem 'xmlsimple', 'xml-simple' unless defined? XmlSimple
70
+ =begin
71
+ # If libxml is installed, we use the FasterXmlSimple library, that provides most of the functionality of XmlSimple
72
+ # except it uses the xml/libxml library for xml parsing (rather than REXML). If libxml isn't installed, we just fall back on
73
+ # XmlSimple.
74
+ AWS::S3::Parsing.parser =
75
+ begin
76
+ require_library_or_gem 'xml/libxml'
77
+ # Older version of libxml aren't stable (bus error when requesting attributes that don't exist) so we
78
+ # have to use a version greater than '0.3.8.2'.
79
+ raise LoadError unless XML::Parser::VERSION > '0.3.8.2'
80
+ $:.push(File.join(File.dirname(__FILE__), '..', '..', 'support', 'faster-xml-simple', 'lib'))
81
+ require_library_or_gem 'faster_xml_simple'
82
+ FasterXmlSimple
83
+ rescue LoadError
84
+ XmlSimple
85
+ end
86
+ =end
@@ -0,0 +1,9 @@
1
+ module Amazon
2
+ module MWS
3
+ class Authentication
4
+ VERSION = '2009-01-01'
5
+ # Nothing really to see here,
6
+ # please have a look at the files in the authentication folder
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ class Amazon::MWS::Authentication
2
+
3
+ class QueryString < String
4
+ def initialize(params = {})
5
+ query_params = {
6
+ 'AWSAccessKeyId' => params[:access_key],
7
+ 'Marketplace' => params[:marketplace_id],
8
+ 'Merchant' => params[:merchant_id],
9
+ 'SignatureMethod' => Signature::METHOD,
10
+ 'SignatureVersion' => Signature::VERSION,
11
+ 'Timestamp' => Time.now.iso8601,
12
+ 'Version' => Amazon::MWS::Authentication::VERSION
13
+ }
14
+
15
+ # Add any params that are passed in via uri before calculating the signature
16
+ query_params = query_params.merge(params[:query_params] || {})
17
+ # Calculate the signature
18
+ query_params['Signature'] = Signature.new(query_params, params)
19
+
20
+ self << formatted_querystring(query_params)
21
+ end
22
+
23
+ def formatted_querystring(query_params)
24
+ query_params.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&') # order doesn't matter for the actual request
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,43 @@
1
+ class Amazon::MWS::Authentication
2
+
3
+ class Signature < String#:nodoc:
4
+ extend Memoizable
5
+
6
+ VERSION = '2'
7
+ METHOD = 'HmacSHA256'
8
+
9
+ def initialize(queryparams = {}, params = {})
10
+ verb = params[:verb]
11
+ secret = params[:secret_access_key]
12
+ # Create the string to sign
13
+ string = string_to_sign(verb, canonical_querystring(queryparams))
14
+ self << sign(string, secret)
15
+ end
16
+
17
+ # Returns a signed string
18
+ def sign(string, secret_access_key)
19
+ hmac = HMAC::SHA256.new(secret_access_key)
20
+ hmac.update(string)
21
+ # chomp is important! the base64 encoded version will have a newline at the end
22
+ Base64.encode64(hmac.digest).chomp
23
+ end
24
+
25
+ memoize :sign
26
+
27
+ def string_to_sign(verb, querystring)
28
+ verb = verb.to_s.upcase
29
+ string = "#{verb}\n#{Amazon::MWS::DEFAULT_HOST}\n/\n#{querystring}"
30
+ end
31
+
32
+ memoize :string_to_sign
33
+
34
+ def canonical_querystring(params)
35
+ # Make sure we have string keys, otherwise the sort does not work
36
+ params = Hash.keys_to_s(params)
37
+ params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
38
+ end
39
+
40
+ memoize :canonical_querystring
41
+ end
42
+
43
+ end
@@ -0,0 +1,61 @@
1
+ module Amazon
2
+ module MWS
3
+ DEFAULT_HOST = "mws.amazonaws.com"
4
+
5
+ class Base
6
+ attr_accessor :connection
7
+
8
+ def self.debug; @@debug ||= false end
9
+ def self.debug=(bool); @@debug = bool end
10
+
11
+ def initialize(options ={})
12
+ @connection = Amazon::MWS::Connection.connect(options)
13
+ end
14
+
15
+ def connection
16
+ raise Amazon::MWS::NoConnectionEstablished.new if !connected?
17
+ @connection
18
+ end
19
+
20
+ def connected?
21
+ !@connection.nil?
22
+ end
23
+
24
+ def disconnect
25
+ @connection.http.finish if @connection.persistent?
26
+ @connection = nil
27
+ end
28
+
29
+ # Wraps the current connection's request method and picks the appropriate response class to wrap the response in.
30
+ # If the response is an error, it will raise that error as an exception. All such exceptions can be caught by rescuing
31
+ # their superclass, the ResponseError exception class.
32
+ #
33
+ # It is unlikely that you would call this method directly. Subclasses of Base have convenience methods for each http request verb
34
+ # that wrap calls to request.
35
+ def request(verb, path, query_params = {}, body = nil, attempts = 0, &block)
36
+ # Find the connection method in connection/management.rb which is evaled into Amazon::MWS::Base
37
+ response = @connection.request(verb, path, query_params, body, attempts, &block)
38
+
39
+ # Each calling class is responsible for formatting the result
40
+ return response
41
+ rescue InternalError, RequestTimeout
42
+ if attempts == 3
43
+ raise
44
+ else
45
+ attempts += 1
46
+ retry
47
+ end
48
+ end
49
+
50
+ # Make some convenience methods
51
+ [:get, :post, :put, :delete, :head].each do |verb|
52
+ class_eval(<<-EVAL, __FILE__, __LINE__)
53
+ def #{verb}(path, query_params = {}, body = nil, &block)
54
+ request(:#{verb}, path, query_params, body, &block)
55
+ end
56
+ EVAL
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,99 @@
1
+ module Amazon
2
+ module MWS
3
+
4
+ class Connection
5
+ # Static/Class methods
6
+ class << self
7
+ def connect(options = {})
8
+ new(options)
9
+ end
10
+ end
11
+
12
+ def initialize(params = {})
13
+ # These values are essential to establishing a connection
14
+ @server = params['server'] || Amazon::MWS::DEFAULT_HOST
15
+ @persistent = params['persistent'] || false
16
+ # These values are essential to signing requests
17
+ @access_key = params['access_key']
18
+ @secret_access_key = params['secret_access_key']
19
+ @merchant_id = params['merchant_id']
20
+ @marketplace_id = params['marketplace_id']
21
+
22
+ raise MissingConnectionOptions if [@access_key, @secret_access_key, @merchant_id, @marketplace_id].any? {|option| option.nil?}
23
+
24
+ @http = connect
25
+ end
26
+
27
+ # Create the Net::HTTP object to use for this connection
28
+ def connect
29
+ http = Net::HTTP.new(@server, 443)
30
+ http.use_ssl = true
31
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
32
+ return http
33
+ end
34
+
35
+ # Make the request, based on the apropriate request object
36
+ # Called from Amazon::MWS::Base
37
+ def request(verb, path, query_params, body = nil, attempts = 0, &block)
38
+ # presumably this is for files
39
+ body.rewind if body.respond_to?(:rewind) unless attempts.zero?
40
+ # Prepare the Proc to be called by Net::HTTP
41
+ proc = requester(verb, path, query_params, body)
42
+
43
+ if @persistent
44
+ @http.start unless @http.started?
45
+ proc.call
46
+ else
47
+ @http.start(&proc)
48
+ end
49
+ rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
50
+ @http = connect
51
+ attempts == 3 ? raise : (attempts += 1; retry)
52
+ end
53
+
54
+ # A Proc used by the request method
55
+ def requester(verb, path, query_params, body)
56
+ Proc.new do |http|
57
+ path = prepare_path(verb, path, query_params)
58
+ puts "#{path}\n\n" if AWS::MWS::Base.debug
59
+ request = build_request(verb, path, body)
60
+
61
+ @http.request(request)
62
+ end
63
+ end
64
+
65
+ # Create the signed authentication query string.
66
+ # Add this query string to the path WITHOUT prepending the server address.
67
+ def prepare_path(verb, path, query_params)
68
+ query_string = authenticate_query_string(verb, query_params)
69
+ return "#{path}?#{query_string}"
70
+ end
71
+
72
+ # Generates the authentication query string used by Amazon.
73
+ # Takes the http method and the query string of the request and returns the authenticated query string
74
+ def authenticate_query_string(verb, query_params = {})
75
+ Authentication::QueryString.new(
76
+ :verb => verb,
77
+ :query_params => query_params,
78
+ :access_key => @access_key,
79
+ :secret_access_key => @secret_access_key,
80
+ :merchant_id => @merchant_id,
81
+ :marketplace_id => @marketplace_id
82
+ )
83
+ end
84
+
85
+ # Builds up a Net::HTTP request object
86
+ def build_request(verb, path, body = nil)
87
+ builder = RequestBuilder.new(verb, path, body)
88
+ builder.add_user_agent
89
+ builder.add_content_type
90
+ builder.add_content_md5(body) unless body.nil?
91
+
92
+ return builder.request
93
+ end
94
+ end
95
+ # Connection
96
+
97
+ end
98
+ end
99
+