AWSXmlClient.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/core/client/AWSXmlClient.h>
  6. #include <aws/core/AmazonWebServiceRequest.h>
  7. #include <aws/core/auth/AWSAuthSignerProvider.h>
  8. #include <aws/core/client/AWSError.h>
  9. #include <aws/core/client/AWSErrorMarshaller.h>
  10. #include <aws/core/client/ClientConfiguration.h>
  11. #include <aws/core/client/CoreErrors.h>
  12. #include <aws/core/client/RetryStrategy.h>
  13. #include <aws/core/http/HttpClient.h>
  14. #include <aws/core/http/HttpResponse.h>
  15. #include <aws/core/http/URI.h>
  16. #include <aws/core/utils/Outcome.h>
  17. #include <aws/core/utils/xml/XmlSerializer.h>
  18. #include <aws/core/utils/memory/stl/AWSStringStream.h>
  19. #include <aws/core/utils/logging/LogMacros.h>
  20. #include <aws/core/utils/event/EventStream.h>
  21. #include <aws/core/utils/UUID.h>
  22. using namespace Aws;
  23. using namespace Aws::Client;
  24. using namespace Aws::Http;
  25. using namespace Aws::Utils;
  26. using namespace Aws::Utils::Xml;
  27. static const char AWS_XML_CLIENT_LOG_TAG[] = "AWSXmlClient";
  28. AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
  29. const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
  30. const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
  31. BASECLASS(configuration, signer, errorMarshaller)
  32. {
  33. }
  34. AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
  35. const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider,
  36. const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
  37. BASECLASS(configuration, signerProvider, errorMarshaller)
  38. {
  39. }
  40. XmlOutcome AWSXMLClient::MakeRequest(const Aws::AmazonWebServiceRequest& request,
  41. const Aws::Endpoint::AWSEndpoint& endpoint,
  42. Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
  43. const char* signerName /* = Aws::Auth::NULL_SIGNER */,
  44. const char* signerRegionOverride /* = nullptr */,
  45. const char* signerServiceNameOverride /* = nullptr */) const
  46. {
  47. const Aws::Http::URI& uri = endpoint.GetURI();
  48. if (endpoint.GetAttributes()) {
  49. signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
  50. if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
  51. signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
  52. }
  53. if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
  54. signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
  55. }
  56. if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
  57. signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
  58. }
  59. }
  60. return MakeRequest(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
  61. }
  62. XmlOutcome AWSXMLClient::MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint,
  63. const char* requestName /* = "" */,
  64. Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
  65. const char* signerName /* = Aws::Auth::NULL_SIGNER */,
  66. const char* signerRegionOverride /* = nullptr */,
  67. const char* signerServiceNameOverride /* = nullptr */) const
  68. {
  69. const Aws::Http::URI& uri = endpoint.GetURI();
  70. if (endpoint.GetAttributes()) {
  71. signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
  72. if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
  73. signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
  74. }
  75. if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
  76. signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
  77. }
  78. if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
  79. signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
  80. }
  81. }
  82. return MakeRequest(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride);
  83. }
  84. XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
  85. const Aws::AmazonWebServiceRequest& request,
  86. Http::HttpMethod method,
  87. const char* signerName,
  88. const char* signerRegionOverride,
  89. const char* signerServiceNameOverride) const
  90. {
  91. HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
  92. if (!httpOutcome.IsSuccess())
  93. {
  94. return XmlOutcome(std::move(httpOutcome));
  95. }
  96. if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
  97. {
  98. XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody());
  99. if (!xmlDoc.WasParseSuccessful())
  100. {
  101. AWS_LOGSTREAM_ERROR(AWS_XML_CLIENT_LOG_TAG, "Xml parsing for error failed with message " << xmlDoc.GetErrorMessage().c_str());
  102. return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Xml Parse Error", xmlDoc.GetErrorMessage(), false);
  103. }
  104. return XmlOutcome(AmazonWebServiceResult<XmlDocument>(std::move(xmlDoc),
  105. httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
  106. }
  107. return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
  108. }
  109. XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
  110. Http::HttpMethod method,
  111. const char* signerName,
  112. const char* requestName,
  113. const char* signerRegionOverride,
  114. const char* signerServiceNameOverride) const
  115. {
  116. HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
  117. if (!httpOutcome.IsSuccess())
  118. {
  119. return XmlOutcome(std::move(httpOutcome));
  120. }
  121. if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
  122. {
  123. return XmlOutcome(AmazonWebServiceResult<XmlDocument>(
  124. XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()),
  125. httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
  126. }
  127. return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
  128. }
  129. AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::HttpResponse>& httpResponse) const
  130. {
  131. AWSError<CoreErrors> error;
  132. if (httpResponse->HasClientError())
  133. {
  134. bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
  135. error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
  136. }
  137. else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
  138. {
  139. auto responseCode = httpResponse->GetResponseCode();
  140. auto errorCode = AWSClient::GuessBodylessErrorType(responseCode);
  141. Aws::StringStream ss;
  142. ss << "No response body.";
  143. error = AWSError<CoreErrors>(errorCode, "", ss.str(), IsRetryableHttpResponseCode(responseCode));
  144. }
  145. else
  146. {
  147. // When trying to build an AWS Error from a response which is an FStream, we need to rewind the
  148. // file pointer back to the beginning in order to correctly read the input using the XML string iterator
  149. if ((httpResponse->GetResponseBody().tellp() > 0)
  150. && (httpResponse->GetResponseBody().tellg() > 0))
  151. {
  152. httpResponse->GetResponseBody().seekg(0);
  153. }
  154. error = GetErrorMarshaller()->Marshall(*httpResponse);
  155. }
  156. error.SetResponseHeaders(httpResponse->GetHeaders());
  157. error.SetResponseCode(httpResponse->GetResponseCode());
  158. error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
  159. AWS_LOGSTREAM_ERROR(AWS_XML_CLIENT_LOG_TAG, error);
  160. return error;
  161. }