我正在使用Minio来模拟 S3 并在本地测试我的代码。我的代码是使用AWS SDK for C++编写的。
我想做的(出于测试目的)是从 Minio 获取一个对象,存储它,然后使用 PUT 请求将相同的对象发送回 Minio。PUT 请求失败并出现错误Unable to connect to endpoint
。但是,我可以使用 curl 将对象放入 Minio。
这就是我设置我的S3Client的方式(我添加了一些喜欢来解释我为什么这样做):
auto credentialsProvider = Aws::MakeShared<Aws::Auth::EnvironmentAWSCredentialsProvider>("someTag");
Aws::Client::ClientConfiguration config;
config.endpointOverride = Aws::String("172.17.0.2:9000");
config.scheme = Aws::Http::Scheme::HTTP;
// diable ssl https://github.com/aws/aws-sdk-cpp/issues/284
config.verifySSL = false;
// set region to default https://github.com/awslabs/amazon-kinesis-producer/issues/66
config.region = "us-east-1";
// disable virtual adress and signing https://stackoverflow.com/questions/47105289/how-to-override-endpoint-in-aws-sdk-cpp-to-connect-to-minio-server-at-localhost
Aws::S3::S3Client client(credentialsProvider, config, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false);
这就是我的 GET 和我的 PUT 请求的样子。GET 有效,PUT 无效:
// declare request
Aws::S3::Model::GetObjectRequest get_obj_req;
get_obj_req.WithBucket("someBucket").WithKey("someKey");
// Get works fine
auto get_object_outcome = client.GetObject(get_obj_req);
if (!get_object_outcome.IsSuccess()){
// fail does not happen
}
// write file from Minio to local file (seems to work fine)
int size = 1024;
char buffer[size];
auto &retrieved_file = get_object_outcome.GetResultWithOwnership().GetBody().read(buffer, size);
std::ofstream out("someFile");
out << std::string(buffer);
out.close();
// try to PUT the stored file again
Aws::S3::Model::PutObjectRequest put_obj_req;
const std::shared_ptr<Aws::IOStream> input_data =
Aws::MakeShared<Aws::FStream>("tag", "someFile", std::ios_base::in | std::ios_base::binary);
put_obj_req.SetBody(input_data);
put_obj_req.WithBucket("someBucket").WithKey("someKey");
put_obj_req.SetContentLength(size);
put_obj_req.SetContentType("application/octet-stream");
// PUT request
auto resp = client.PutObject(put_obj_req);
if (!resp.IsSuccess()){
// fails here
}
正如我已经提到的,我可以使用 curl 将对象放入 Minio。你可以看看这个 Gist。
旁注:我在 Docker 容器中使用 Minio。
编辑:我相信这可能是我要放置的数据的问题。如果数据有例如Content-Type
application/octet-stream
我遇到错误,但在使用 txt 文件时我没有遇到此错误。我当前的代码看起来像这样,如果我想流式传输除 chers 之外的任何内容,我假设流式传输会中断。你确定吗?
Aws::String content_tye = get_object_outcome.GetResult().GetContentType();
Aws::IOStream &retrieved_file = get_object_outcome.GetResultWithOwnership().GetBody();
retrieved_file.seekg(0, retrieved_file.end);
int retrieved_file_size = retrieved_file.tellg();
retrieved_file.seekg(0, retrieved_file.beg);
char *buffer = new char[retrieved_file_size];
retrieved_file.read(buffer, retrieved_file_size);
AWS_LOGSTREAM_INFO(TAG, "Retrieved file of size: " + Aws::Utils::StringUtils::to_string(retrieved_file_size));
Aws::StringStream stream(Aws::String(buffer));
const std::shared_ptr<Aws::IOStream> input_data =
Aws::MakeShared<Aws::StringStream>(TAG, Aws::String(buffer));