-
|
I'm using this SDK to upload files to the official S3 endpoint for testing, but no matter how I configure it, I keep getting a "SignatureDoesNotMatch" error. With the same access_key_id, secret_access_key, session_token, region, and environment, the C++ SDK can upload files correctly. Below is my code—could you please advise if there's anything I’ve misconfigured? Initialize SDK: bool S3Plugin::InitializeAwsSdk() {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Initializing AWS C SDK";
allocator_ = aws_default_allocator();
if (!allocator_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to get default allocator";
return false;
}
aws_s3_library_init(allocator_);
event_loop_group_ = aws_event_loop_group_new_default(allocator_, 1, nullptr);
if (!event_loop_group_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create event loop group";
return false;
}
aws_host_resolver_default_options resolver_options;
AWS_ZERO_STRUCT(resolver_options);
resolver_options.el_group = event_loop_group_;
static constexpr size_t kDefaultMaxEntries = 8;
resolver_options.max_entries = kDefaultMaxEntries;
host_resolver_ = aws_host_resolver_new_default(allocator_, &resolver_options);
if (!host_resolver_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create host resolver";
return false;
}
aws_client_bootstrap_options bootstrap_options;
AWS_ZERO_STRUCT(bootstrap_options);
bootstrap_options.event_loop_group = event_loop_group_;
bootstrap_options.host_resolver = host_resolver_;
client_bootstrap_ = aws_client_bootstrap_new(allocator_, &bootstrap_options);
if (!client_bootstrap_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create client bootstrap";
return false;
}
initialized_ = true;
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] AWS C SDK initialized successfully";
return true;
}Create s3 client: bool S3Plugin::UpdateS3Client(const std::string& access_key_id,
const std::string& secret_access_key,
const std::string& session_token,
const std::string& region,
const std::string& endpoint) {
if (current_access_key_id_ == access_key_id && current_secret_access_key_ == secret_access_key &&
current_session_token_ == session_token && current_region_ == region && current_endpoint_ == endpoint) {
return true;
}
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Updating S3 client with new credentials";
if (client_) {
aws_s3_client_release(client_);
client_ = nullptr;
}
if (credentials_provider_) {
aws_credentials_provider_release(credentials_provider_);
credentials_provider_ = nullptr;
}
current_access_key_id_ = access_key_id;
current_secret_access_key_ = secret_access_key;
current_session_token_ = session_token;
current_region_ = region;
current_endpoint_ = endpoint;
aws_credentials_provider_static_options credentials_options;
AWS_ZERO_STRUCT(credentials_options);
credentials_options.access_key_id = aws_byte_cursor_from_c_str(access_key_id.c_str());
credentials_options.secret_access_key = aws_byte_cursor_from_c_str(secret_access_key.c_str());
credentials_options.session_token = aws_byte_cursor_from_c_str(session_token.c_str());
credentials_provider_ = aws_credentials_provider_new_static(allocator_, &credentials_options);
if (!credentials_provider_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create credentials provider";
return false;
}
aws_s3_init_default_signing_config(
&signing_config_, aws_byte_cursor_from_c_str(current_region_.c_str()), credentials_provider_);
signing_config_.flags.use_double_uri_encode = false;
static constexpr uint64_t kDefaultPartSize = 5ULL * 1024 * 1024;
static constexpr double kDefaultThroughputGbps = 10.0;
aws_s3_client_config client_config;
AWS_ZERO_STRUCT(client_config);
client_config.region = aws_byte_cursor_from_c_str(current_region_.c_str());
client_config.client_bootstrap = client_bootstrap_;
client_config.part_size = kDefaultPartSize;
client_config.throughput_target_gbps = kDefaultThroughputGbps;
client_config.signing_config = &signing_config_;
client_ = aws_s3_client_new(allocator_, &client_config);
if (!client_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create S3 client";
return false;
}
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] S3 client updated successfully";
return true;
}Upload file: void S3Plugin::Upload(const FCSStorageUploadTask& task,
const FCSAuthorization& authorization,
const _FCSUploadInfo::UploadResultCallback& resultCallback) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Starting upload - file: " << task->info_->file_path_
<< ", bucket: " << authorization.bucket << ", object: " << authorization.objectName;
bool success = false;
std::string error_message;
do {
if (released_.load()) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Plugin is released, cannot upload";
error_message = "Plugin has been released";
break;
}
if (!client_) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] S3 client not initialized";
error_message = "S3 client not initialized";
break;
}
auto upload_context = std::make_shared<UploadContext>();
upload_context->weak_plugin_ = SharedFromThis<S3Plugin>();
upload_context->task = task;
upload_context->authorization = authorization;
uint64_t file_size = NE_BASE::NEFileSystem::GetFileSize(task->info_->file_path_);
std::string file_size_string = std::to_string(file_size);
upload_context->total_bytes = file_size;
aws_input_stream* input_stream = aws_input_stream_new_from_file(allocator_, task->info_->file_path_.c_str());
if (!input_stream) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create input stream";
error_message = "Failed to create input stream";
break;
}
std::string content_type = task->info_->content_type_;
if (content_type.empty()) {
content_type = UploadUtil::GetMineTypeFromFilePath(task->info_->file_path_);
}
aws_http_message* message = aws_http_message_new_request(allocator_);
if (!message) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create HTTP message";
aws_input_stream_release(input_stream);
error_message = "Failed to create HTTP message";
break;
}
aws_http_message_set_request_method(message, aws_http_method_put);
std::string object_path = "/" + authorization.objectName;
if (!current_endpoint_.empty())
object_path = "/" + authorization.bucket + "/" + ne_base::UrlDecode(authorization.objectName);
aws_byte_cursor path_cursor = aws_byte_cursor_from_c_str(object_path.c_str());
aws_http_message_set_request_path(message, path_cursor);
aws_http_header content_type_header = {
aws_byte_cursor_from_c_str("Content-Type"), aws_byte_cursor_from_c_str(content_type.data())};
aws_http_message_add_header(message, content_type_header);
// aws_http_header token_header = {aws_byte_cursor_from_c_str("x-amz-meta-token"),
// aws_byte_cursor_from_c_str(authorization.token.c_str())};
// aws_http_message_add_header(message, token_header);
aws_http_header content_length_header = {
aws_byte_cursor_from_c_str("Content-Length"), aws_byte_cursor_from_c_str(file_size_string.data())};
aws_http_message_add_header(message, content_length_header);
if (current_endpoint_.empty()) {
std::string default_endpoint = authorization.bucket + ".s3." + current_region_ + ".amazonaws.com";
aws_http_header host_header = {
aws_byte_cursor_from_c_str("Host"), aws_byte_cursor_from_c_str(default_endpoint.c_str())};
aws_http_message_add_header(message, host_header);
}
aws_http_message_set_body_stream(message, input_stream);
aws_s3_meta_request_options meta_request_options;
AWS_ZERO_STRUCT(meta_request_options);
meta_request_options.type = AWS_S3_META_REQUEST_TYPE_PUT_OBJECT;
meta_request_options.message = message;
meta_request_options.upload_review_callback = OnUploadReview;
meta_request_options.headers_callback = OnMetaRequestHeaders;
meta_request_options.body_callback = OnMetaRequestBody;
meta_request_options.finish_callback = OnMetaRequestFinished;
meta_request_options.progress_callback = OnMetaRequestProgress;
meta_request_options.user_data = upload_context.get();
// Set custom endpont if needed
aws_uri endpoint;
AWS_ZERO_STRUCT(endpoint);
if (!current_endpoint_.empty()) {
aws_byte_cursor uri_cursor = aws_byte_cursor_from_c_str(current_endpoint_.c_str());
aws_uri_init_parse(&endpoint, allocator_, &uri_cursor);
meta_request_options.endpoint = &endpoint;
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Using custom endpoint: " << current_endpoint_;
}
upload_context->meta_request = aws_s3_client_make_meta_request(client_, &meta_request_options);
aws_http_message_release(message);
aws_input_stream_release(input_stream);
if (!upload_context->meta_request) {
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Failed to create meta request";
error_message = "Failed to create meta request";
break;
}
task->runtime_.SetCanceller(ToWeakClosure([=]() {
CancelTask(task->GetTaskID());
if (task->info_->result_callback != nullptr) {
task->info_->result_callback(kCancel, 0, task->info_->file_path_, "");
}
}));
upload_context->download_url = ComposeDownloadUrl(
authorization.bucket, ne_base::UrlDecode(authorization.objectName), authorization.shortUrl);
std::lock_guard<std::recursive_mutex> lock(upload_tasks_mutex_);
upload_tasks_[task->GetTaskID()] = upload_context;
QLOG_APP_HAVCOMP << "[fcs][plugin][aws.s3] Upload request created successfully";
success = true;
} while (false);
if (!success && resultCallback) {
resultCallback(kError, 0, task->info_->file_path_, error_message);
}
}Upload response: <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>ASIA2FDNKLKWFQLEW2N7</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256
20250915T022109Z
20250915/ap-southeast-1/s3/aws4_request
f5f7275f9214da02513f3da4a1d46545c2336088e4791d141713f3d24880db1b</StringToSign>
<SignatureProvided>dc12c046d25866192f3b6704671ec68d58c61f8bc5031406b2dad87c2c6c6f17</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 35 30 39 31 35 54 30 32 32 31 30 39 5a 0a 32 30 32 35 30 39 31 35 2f 61 70 2d 73 6f 75 74 68 65 61 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 66 35 66 37 32 37 35 66 39 32 31 34 64 61 30 32 35 31 33 66 33 64 61 34 61 31 64 34 36 35 34 35 63 32 33 33 36 30 38 38 65 34 37 39 31 64 31 34 31 37 31 33 66 33 64 32 34 38 38 30 64 62 31 62</StringToSignBytes>
<CanonicalRequest>PUT
/MTAxMTAwMg%3D%3D/czNhcHBfNTIxNDQyNzI3NF8xNzU3OTAyODMyOTcwXzVkMmFlNDNjLTk2ZTgtNDBmZi1hMWIyLWE2ZDk3Y2Q3OTI2OCYyJjExMDAyJnl1bnhpbmltJmFwLXNvdXRoZWFzdC0x
content-length:1879
host:yunxinim.s3.ap-southeast-1.amazonaws.com
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20250915T022109Z
x-amz-security-token:IQoJb3JpZ2luX2VjEPP//////////wEaCXVzLWVhc3QtMSJGMEQCIGPC7N9+a/PRBX+Ybn3HT35JZ6UT7c4DSMVLoQfQBIxiAiBsdsY21li7MjFBFJSlU2lZdfNMlyvwRumlIxGG8FnaASqNAwhrEAUaDDY5ODE2MTQ1Mzc0MCIMLCu+7WAlQFZPCk9BKuoC9ysiWo4lN4a6lqxgQXUVphp18R6molt2Q9dFWmOWAJA+tY0XtZNUMke6O2xWhyYoqzor94c1eSg1XaciBQ9i3bWpre2wUV9n6X4R3unHsLU/qXGC59XtqExkarbwd3LA4kY78DRnE42/LBVLrdU7upK5zzqP4ls6tyWmdzyPTP6errVp/bdnPNJ0wGRS1oggnawB3ojhPb+7A7hU/6Nh3Deo6wUXrjQRJTRmJrWL7.......
content-length;host;x-amz-content-sha256;x-amz-date;x-amz-security-token
UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>.......</CanonicalRequestBytes>
<RequestId>XDXFW1PSRBTCY1GK</RequestId>
<HostId>4ZWqqcgj8GLpPNVtla2TqT/zGFTZ5R4JIAPgF2dYcm94gvrgS/oJ9bF+bDgmepi9CG6LbXZFrLriw6TU9GoreoeRTUQig3fwt4pN1osYZmI=</HostId>
</Error> |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
I have resolved the issue. The first step was to decode the objectName in the upload path. std::string object_path = "/" + ne_base::UrlDecode(authorization.objectName);and then set signing_config_.flags.use_double_uri_encode = true; |
Beta Was this translation helpful? Give feedback.
I have resolved the issue. The first step was to decode the objectName in the upload path.
and then set
use_double_uri_encodeto true.