-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Changes to enable Smithy S3 CRT #3352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -206,6 +206,10 @@ namespace client | |
| virtual bool AdjustClockSkew(HttpResponseOutcome& outcome, const AuthSchemeOption& authSchemeOption) const = 0; | ||
| virtual IdentityOutcome ResolveIdentity(const AwsSmithyClientAsyncRequestContext& ctx) const = 0; | ||
| virtual GetContextEndpointParametersOutcome GetContextEndpointParameters(const AwsSmithyClientAsyncRequestContext& ctx) const = 0; | ||
| AwsSmithyClientBase::ResolveEndpointOutcome ResolveEndpointFromRequest( | ||
| Aws::AmazonWebServiceRequest const * const request, | ||
| const char* requestName, | ||
| EndpointUpdateCallback&& endpointCallback) const; | ||
|
|
||
| /* AwsSmithyClientT class binds its config reference to this pointer, so don't remove const and don't re-allocate it. | ||
| * This is done to avoid duplication of config object between this base and actual service template classes. | ||
|
|
@@ -220,6 +224,13 @@ namespace client | |
| std::shared_ptr<smithy::client::UserAgentInterceptor> m_userAgentInterceptor; | ||
| private: | ||
| void UpdateAuthSchemeFromEndpoint(const Aws::Endpoint::AWSEndpoint& endpoint, AuthSchemeOption& authscheme) const; | ||
|
|
||
| bool ResolveIdentityAuth( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| std::shared_ptr<AwsSmithyClientAsyncRequestContext>& pRequestCtx, | ||
| ResponseHandlerFunc&& responseHandler, | ||
| EndpointUpdateCallback&& endpointCallback | ||
| ) const; | ||
|
|
||
| }; | ||
| } // namespace client | ||
| } // namespace smithy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -177,49 +177,19 @@ AwsSmithyClientBase::BuildHttpRequest(const std::shared_ptr<AwsSmithyClientAsync | |
| return httpRequest; | ||
| } | ||
|
|
||
| void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* const request, | ||
| const char* requestName, | ||
| Aws::Http::HttpMethod method, | ||
| EndpointUpdateCallback&& endpointCallback, | ||
| ResponseHandlerFunc&& responseHandler, | ||
| std::shared_ptr<Aws::Utils::Threading::Executor> pExecutor) const | ||
|
|
||
| bool AwsSmithyClientBase::ResolveIdentityAuth( | ||
| std::shared_ptr<AwsSmithyClientAsyncRequestContext>& pRequestCtx, | ||
| ResponseHandlerFunc&& responseHandler, | ||
| EndpointUpdateCallback&& endpointCallback | ||
| ) const | ||
| { | ||
| if(!responseHandler) | ||
| { | ||
| assert(!"Missing a mandatory response handler!"); | ||
| AWS_LOGSTREAM_FATAL(AWS_SMITHY_CLIENT_LOG, "Unable to continue AWSClient request: response handler is missing!"); | ||
| return; | ||
| } | ||
|
|
||
| std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx = | ||
| Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG); | ||
| if (!pRequestCtx) | ||
| { | ||
| AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr"); | ||
| auto outcome = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/)); | ||
| pExecutor->Submit([outcome, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(outcome)); | ||
| } ); | ||
| return; | ||
| } | ||
| pRequestCtx->m_pExecutor = pExecutor; | ||
| pRequestCtx->m_pRequest = request; | ||
| if (requestName) | ||
| pRequestCtx->m_requestName = requestName; | ||
| else if (pRequestCtx->m_pRequest) | ||
| pRequestCtx->m_requestName = pRequestCtx->m_pRequest->GetServiceRequestName(); | ||
| pRequestCtx->m_method = method; | ||
| pRequestCtx->m_retryCount = 0; | ||
| pRequestCtx->m_invocationId = Aws::Utils::UUID::PseudoRandomUUID(); | ||
| auto authSchemeOptionOutcome = this->SelectAuthSchemeOption(*pRequestCtx); | ||
| if (!authSchemeOptionOutcome.IsSuccess()) | ||
| { | ||
| pExecutor->Submit([authSchemeOptionOutcome, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(authSchemeOptionOutcome)); | ||
| } ); | ||
| return; | ||
| responseHandler(std::move(authSchemeOptionOutcome)); | ||
| return false; | ||
| } | ||
| pRequestCtx->m_authSchemeOption = std::move(authSchemeOptionOutcome.GetResultWithOwnership()); | ||
| assert(pRequestCtx->m_authSchemeOption.schemeId); | ||
|
|
@@ -228,26 +198,23 @@ void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* c | |
| auto identityOutcome = this->ResolveIdentity(*pRequestCtx); | ||
| if (!identityOutcome.IsSuccess()) | ||
| { | ||
| pExecutor->Submit([identityOutcome, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(identityOutcome)); | ||
| }); | ||
| return; | ||
| responseHandler(std::move(identityOutcome)); | ||
| return false; | ||
| } | ||
|
|
||
| pRequestCtx->m_awsIdentity = std::move(identityOutcome.GetResultWithOwnership()); | ||
|
|
||
| // get endpoint params from operation context | ||
| const auto contextEndpointParameters = this->GetContextEndpointParameters(*pRequestCtx); | ||
|
|
||
| if (!contextEndpointParameters.IsSuccess()) | ||
| { | ||
| pExecutor->Submit([contextEndpointParameters, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(contextEndpointParameters.GetError())); | ||
| }); | ||
| return; | ||
| responseHandler(std::move(contextEndpointParameters.GetError())); | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| Aws::Endpoint::EndpointParameters epParams = request ? request->GetEndpointContextParams() : Aws::Endpoint::EndpointParameters(); | ||
| Aws::Endpoint::EndpointParameters epParams = pRequestCtx->m_pRequest ? pRequestCtx->m_pRequest->GetEndpointContextParams() : Aws::Endpoint::EndpointParameters(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The helper function just houses the code to select auth scheme, resolve identity and resolve endpoint. |
||
| const auto authSchemeEpParams = pRequestCtx->m_authSchemeOption.endpointParameters(); | ||
| epParams.insert(epParams.end(), authSchemeEpParams.begin(), authSchemeEpParams.end()); | ||
| const auto contextParams = contextEndpointParameters.GetResult(); | ||
|
|
@@ -260,25 +227,63 @@ void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* c | |
| epResolutionOutcome.GetError().GetExceptionName(), | ||
| epResolutionOutcome.GetError().GetMessage(), | ||
| false}); | ||
|
|
||
| pExecutor->Submit([epOutcome, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(epOutcome)); | ||
| } ); | ||
| return; | ||
| responseHandler(std::move(epOutcome)); | ||
| return false; | ||
| } | ||
| pRequestCtx->m_endpoint = std::move(epResolutionOutcome.GetResultWithOwnership()); | ||
|
|
||
| if (!Aws::Utils::IsValidHost(pRequestCtx->m_endpoint.GetURI().GetAuthority())) | ||
| { | ||
| AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Invalid DNS Label found in URI host"); | ||
| auto outcome = HttpResponseOutcome(ClientError(CoreErrors::VALIDATION, "", "Invalid DNS Label found in URI host", false/*retryable*/)); | ||
| responseHandler(std::move(outcome)); | ||
| return false; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the helper function just houses the code to select auth, resolve identity and then resolve endpoint, this validation code is the existing check we have to ensure endpoint resolved is valid or not. In case it is not valid, it reflects that in the outcome. |
||
| } | ||
| return true; | ||
| } | ||
|
|
||
| void AwsSmithyClientBase::MakeRequestAsync(Aws::AmazonWebServiceRequest const* const request, | ||
| const char* requestName, | ||
| Aws::Http::HttpMethod method, | ||
| EndpointUpdateCallback&& endpointCallback, | ||
| ResponseHandlerFunc&& responseHandler, | ||
| std::shared_ptr<Aws::Utils::Threading::Executor> pExecutor) const | ||
| { | ||
| if(!responseHandler) | ||
| { | ||
| assert(!"Missing a mandatory response handler!"); | ||
| AWS_LOGSTREAM_FATAL(AWS_SMITHY_CLIENT_LOG, "Unable to continue AWSClient request: response handler is missing!"); | ||
| return; | ||
| } | ||
|
|
||
| std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx = | ||
| Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG, request, requestName, pExecutor ); | ||
| if (!pRequestCtx) | ||
| { | ||
| AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr"); | ||
| auto outcome = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/)); | ||
| pExecutor->Submit([outcome, responseHandler]() mutable | ||
| { | ||
| responseHandler(std::move(outcome)); | ||
| } ); | ||
| return; | ||
| } | ||
|
|
||
| pRequestCtx->m_method = method; | ||
| ResponseHandlerFunc modifiedResponseHandler = [&](HttpResponseOutcome&& outcome){ | ||
| auto capturedOutcome = std::make_shared<HttpResponseOutcome>(std::move(outcome)); | ||
| pExecutor->Submit([capturedOutcome, &responseHandler]() | ||
| { | ||
| responseHandler(std::move(*capturedOutcome)); | ||
| }); | ||
| }; | ||
|
|
||
| if(!ResolveIdentityAuth( | ||
| pRequestCtx, | ||
| std::move(modifiedResponseHandler), | ||
| std::move(endpointCallback))) | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure which handler is being referred to, but 'responseHandler' is being called. This is tested with S3-crt and S3-crt express integration and unit tests |
||
| return; | ||
| } | ||
| pRequestCtx->m_requestInfo.attempt = 1; | ||
| pRequestCtx->m_requestInfo.maxAttempts = 0; | ||
| pRequestCtx->m_interceptorContext = Aws::MakeShared<InterceptorContext>(AWS_SMITHY_CLIENT_LOG, *request); | ||
|
|
@@ -682,4 +687,39 @@ void AwsSmithyClientBase::AppendToUserAgent(const Aws::String& valueToAppend) | |
| { | ||
| assert(m_userAgentInterceptor); | ||
| m_userAgentInterceptor->AddLegacyFeaturesToUserAgent(valueToAppend); | ||
| } | ||
|
|
||
| /* | ||
| blocking API to resolve endpoint from request | ||
| */ | ||
| AwsSmithyClientBase::ResolveEndpointOutcome AwsSmithyClientBase::ResolveEndpointFromRequest( | ||
| Aws::AmazonWebServiceRequest const * const request, | ||
| const char* requestName, | ||
| EndpointUpdateCallback&& endpointCallback) const | ||
| { | ||
| ResolveEndpointOutcome outcome = ClientError(CoreErrors::INTERNAL_FAILURE, "", "Response handler was not called", false); | ||
| ResponseHandlerFunc responseHandler = [&outcome](HttpResponseOutcome&& asyncOutcome) | ||
| { | ||
| outcome = std::move(asyncOutcome); | ||
| }; | ||
|
|
||
| std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx = Aws::MakeShared<AwsSmithyClientAsyncRequestContext>(AWS_SMITHY_CLIENT_LOG, request, requestName, nullptr); | ||
| if (!pRequestCtx) | ||
| { | ||
| AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to allocate an AwsSmithyClientAsyncRequestContext under a shared ptr"); | ||
| auto result = HttpResponseOutcome(ClientError(CoreErrors::MEMORY_ALLOCATION, "", "Failed to allocate async request context", false/*retryable*/)); | ||
| responseHandler(std::move(result)); | ||
| } | ||
| else | ||
| { | ||
| if(this->ResolveIdentityAuth( | ||
| pRequestCtx, | ||
| std::move(responseHandler), | ||
| std::move(endpointCallback) | ||
| )) | ||
| { | ||
| outcome = std::move(pRequestCtx->m_endpoint); | ||
| } | ||
| } | ||
| return outcome; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This defaults initialization of few members which was previously being done in request processing