mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-11-19 10:45:12 +00:00
commit
ae4ae88b6d
@ -71,9 +71,13 @@ this option can not be specified with use_sse.
|
|||||||
(can specify use_rrs=1 for old version)
|
(can specify use_rrs=1 for old version)
|
||||||
.TP
|
.TP
|
||||||
\fB\-o\fR use_sse (default is disable)
|
\fB\-o\fR use_sse (default is disable)
|
||||||
use Amazon's Server Site Encryption.
|
use Amazon<6F>fs Server-Site Encryption or Server-Side Encryption with Customer-Provided Encryption Keys.
|
||||||
this option can not be specified with use_rrs.
|
this option can not be specified with use_rrs. specifying only "use_sse" or "use_sse=1" enables Server-Side Encryption.(use_sse=1 for old version)
|
||||||
(can specify use_sse=1 for old version)
|
specifying this option with file path which has some SSE-C secret key enables Server-Side Encryption with Customer-Provided Encryption Keys.(use_sse=file)
|
||||||
|
the file must be 600 permission. the file can have some lines, each line is one SSE-C key. the first line in file is used as Customer-Provided Encryption Keys for uploading and change headers etc.
|
||||||
|
if there are some keys after first line, those are used downloading object which are encripted by not first key.
|
||||||
|
so that, you can keep all SSE-C keys in file, that is SSE-C key history.
|
||||||
|
if AWSSSECKEYS environment is set, you can set SSE-C key instead of this option.
|
||||||
.TP
|
.TP
|
||||||
\fB\-o\fR passwd_file (default="")
|
\fB\-o\fR passwd_file (default="")
|
||||||
specify the path to the password file, which which takes precedence over the password in $HOME/.passwd-s3fs and /etc/passwd-s3fs
|
specify the path to the password file, which which takes precedence over the password in $HOME/.passwd-s3fs and /etc/passwd-s3fs
|
||||||
|
385
src/curl.cpp
385
src/curl.cpp
@ -51,6 +51,63 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// [TODO]
|
||||||
|
// This function uses tempolary file, but should not use it.
|
||||||
|
// For not using it, we implement function in each auth file(openssl, nss. gnutls).
|
||||||
|
//
|
||||||
|
static bool make_md5_from_string(const char* pstr, string& md5)
|
||||||
|
{
|
||||||
|
if(!pstr || '\0' == pstr[0]){
|
||||||
|
DPRN("Parameter is wrong.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FILE* fp;
|
||||||
|
if(NULL == (fp = tmpfile())){
|
||||||
|
FPRN("Could not make tmpfile.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t length = strlen(pstr);
|
||||||
|
if(length != fwrite(pstr, sizeof(char), length, fp)){
|
||||||
|
FPRN("Failed to write tmpfile.");
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int fd;
|
||||||
|
if(0 != fflush(fp) || 0 != fseek(fp, 0L, SEEK_SET) || -1 == (fd = fileno(fp))){
|
||||||
|
FPRN("Failed to make MD5.");
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// base64 md5
|
||||||
|
md5 = s3fs_get_content_md5(fd);
|
||||||
|
if(0 == md5.length()){
|
||||||
|
FPRN("Failed to make MD5.");
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // noused
|
||||||
|
static string tolower_header_name(const char* head)
|
||||||
|
{
|
||||||
|
string::size_type pos;
|
||||||
|
string name = head;
|
||||||
|
string value("");
|
||||||
|
if(string::npos != (pos = name.find(':'))){
|
||||||
|
value= name.substr(pos);
|
||||||
|
name = name.substr(0, pos);
|
||||||
|
}
|
||||||
|
name = lower(name);
|
||||||
|
name += value;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Class BodyData
|
// Class BodyData
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
@ -154,6 +211,7 @@ int S3fsCurl::retries = 3; // default
|
|||||||
bool S3fsCurl::is_public_bucket = false;
|
bool S3fsCurl::is_public_bucket = false;
|
||||||
string S3fsCurl::default_acl = "private";
|
string S3fsCurl::default_acl = "private";
|
||||||
bool S3fsCurl::is_use_rrs = false;
|
bool S3fsCurl::is_use_rrs = false;
|
||||||
|
sseckeylist_t S3fsCurl::sseckeys;
|
||||||
bool S3fsCurl::is_use_sse = false;
|
bool S3fsCurl::is_use_sse = false;
|
||||||
bool S3fsCurl::is_content_md5 = false;
|
bool S3fsCurl::is_content_md5 = false;
|
||||||
bool S3fsCurl::is_verbose = false;
|
bool S3fsCurl::is_verbose = false;
|
||||||
@ -684,6 +742,126 @@ bool S3fsCurl::SetUseRrs(bool flag)
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool S3fsCurl::PushbackSseKeys(string& onekey)
|
||||||
|
{
|
||||||
|
onekey = trim(onekey);
|
||||||
|
if(0 == onekey.size()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if('#' == onekey[0]){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// make base64
|
||||||
|
char* pbase64_key;
|
||||||
|
if(NULL == (pbase64_key = s3fs_base64((unsigned char*)onekey.c_str(), onekey.length()))){
|
||||||
|
FPRN("Failed to convert base64 from sse-c key %s", onekey.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
string base64_key = pbase64_key;
|
||||||
|
free(pbase64_key);
|
||||||
|
|
||||||
|
// make MD5
|
||||||
|
string strMd5;
|
||||||
|
if(!make_md5_from_string(onekey.c_str(), strMd5)){
|
||||||
|
FPRN("Could not make MD5 from SSE-C keys(%s).", onekey.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// mapped MD5 = SSE Key
|
||||||
|
sseckeymap_t md5map;
|
||||||
|
md5map.clear();
|
||||||
|
md5map[strMd5] = base64_key;
|
||||||
|
S3fsCurl::sseckeys.push_back(md5map);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool S3fsCurl::SetSseKeys(const char* filepath)
|
||||||
|
{
|
||||||
|
if(!filepath){
|
||||||
|
DPRN("SSE-C keys filepath is empty.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
S3fsCurl::sseckeys.clear();
|
||||||
|
|
||||||
|
ifstream ssefs(filepath);
|
||||||
|
if(!ssefs.good()){
|
||||||
|
FPRN("Could not open SSE-C keys file(%s).", filepath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while(getline(ssefs, line)){
|
||||||
|
S3fsCurl::PushbackSseKeys(line);
|
||||||
|
}
|
||||||
|
if(0 == S3fsCurl::sseckeys.size()){
|
||||||
|
FPRN("There is no SSE Key in file(%s).", filepath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool S3fsCurl::LoadEnvSseKeys(void)
|
||||||
|
{
|
||||||
|
char* envkeys = getenv("AWSSSECKEYS");
|
||||||
|
if(NULL == envkeys){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
S3fsCurl::sseckeys.clear();
|
||||||
|
|
||||||
|
istringstream fullkeys(envkeys);
|
||||||
|
string onekey;
|
||||||
|
while(getline(fullkeys, onekey, ':')){
|
||||||
|
S3fsCurl::PushbackSseKeys(onekey);
|
||||||
|
}
|
||||||
|
if(0 == S3fsCurl::sseckeys.size()){
|
||||||
|
FPRN("There is no SSE Key in environment(AWSSSECKEYS=%s).", envkeys);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If md5 is empty, returns first(current) sse key.
|
||||||
|
//
|
||||||
|
bool S3fsCurl::GetSseKey(string& md5, string& ssekey)
|
||||||
|
{
|
||||||
|
for(sseckeylist_t::const_iterator iter = S3fsCurl::sseckeys.begin(); iter != S3fsCurl::sseckeys.end(); iter++){
|
||||||
|
if(0 == md5.length() || md5 == (*iter).begin()->first){
|
||||||
|
md5 = iter->begin()->first;
|
||||||
|
ssekey = iter->begin()->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool S3fsCurl::GetSseKeyMd5(int pos, string& md5)
|
||||||
|
{
|
||||||
|
if(pos < 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(S3fsCurl::sseckeys.size() <= static_cast<size_t>(pos)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int cnt = 0;
|
||||||
|
for(sseckeylist_t::const_iterator iter = S3fsCurl::sseckeys.begin(); iter != S3fsCurl::sseckeys.end(); iter++, cnt++){
|
||||||
|
if(pos == cnt){
|
||||||
|
md5 = iter->begin()->first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int S3fsCurl::GetSseKeyCount(void)
|
||||||
|
{
|
||||||
|
return S3fsCurl::sseckeys.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool S3fsCurl::IsSseCustomMode(void)
|
||||||
|
{
|
||||||
|
return (0 < S3fsCurl::sseckeys.size());
|
||||||
|
}
|
||||||
|
|
||||||
bool S3fsCurl::SetUseSse(bool flag)
|
bool S3fsCurl::SetUseSse(bool flag)
|
||||||
{
|
{
|
||||||
bool old = S3fsCurl::is_use_sse;
|
bool old = S3fsCurl::is_use_sse;
|
||||||
@ -806,7 +984,7 @@ S3fsCurl* S3fsCurl::UploadMultipartPostRetryCallback(S3fsCurl* s3fscurl)
|
|||||||
return newcurl;
|
return newcurl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::ParallelMultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg)
|
int S3fsCurl::ParallelMultipartUploadRequest(const char* tpath, headers_t& meta, int fd)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
string upload_id;
|
string upload_id;
|
||||||
@ -832,7 +1010,7 @@ int S3fsCurl::ParallelMultipartUploadRequest(const char* tpath, headers_t& meta,
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 != (result = s3fscurl.PreMultipartPostRequest(tpath, meta, upload_id, ow_sse_flg))){
|
if(0 != (result = s3fscurl.PreMultipartPostRequest(tpath, meta, upload_id, false))){
|
||||||
close(fd2);
|
close(fd2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -911,7 +1089,7 @@ S3fsCurl* S3fsCurl::ParallelGetObjectRetryCallback(S3fsCurl* s3fscurl)
|
|||||||
// duplicate request(setup new curl object)
|
// duplicate request(setup new curl object)
|
||||||
S3fsCurl* newcurl = new S3fsCurl(s3fscurl->IsUseAhbe());
|
S3fsCurl* newcurl = new S3fsCurl(s3fscurl->IsUseAhbe());
|
||||||
if(0 != (result = newcurl->PreGetObjectRequest(
|
if(0 != (result = newcurl->PreGetObjectRequest(
|
||||||
s3fscurl->path.c_str(), s3fscurl->partdata.fd, s3fscurl->partdata.startpos, s3fscurl->partdata.size))){
|
s3fscurl->path.c_str(), s3fscurl->partdata.fd, s3fscurl->partdata.startpos, s3fscurl->partdata.size, s3fscurl->b_ssekey_md5))){
|
||||||
DPRN("failed downloading part setup(%d)", result);
|
DPRN("failed downloading part setup(%d)", result);
|
||||||
delete newcurl;
|
delete newcurl;
|
||||||
return NULL;;
|
return NULL;;
|
||||||
@ -925,6 +1103,12 @@ int S3fsCurl::ParallelGetObjectRequest(const char* tpath, int fd, off_t start, s
|
|||||||
{
|
{
|
||||||
FPRNNN("[tpath=%s][fd=%d]", SAFESTRPTR(tpath), fd);
|
FPRNNN("[tpath=%s][fd=%d]", SAFESTRPTR(tpath), fd);
|
||||||
|
|
||||||
|
string sseckeymd5("");
|
||||||
|
char* psseckeymd5;
|
||||||
|
if(NULL != (psseckeymd5 = get_object_sseckey_md5(tpath))){
|
||||||
|
sseckeymd5 = psseckeymd5;
|
||||||
|
free(psseckeymd5);
|
||||||
|
}
|
||||||
int result = 0;
|
int result = 0;
|
||||||
ssize_t remaining_bytes;
|
ssize_t remaining_bytes;
|
||||||
|
|
||||||
@ -945,7 +1129,7 @@ int S3fsCurl::ParallelGetObjectRequest(const char* tpath, int fd, off_t start, s
|
|||||||
|
|
||||||
// s3fscurl sub object
|
// s3fscurl sub object
|
||||||
S3fsCurl* s3fscurl_para = new S3fsCurl();
|
S3fsCurl* s3fscurl_para = new S3fsCurl();
|
||||||
if(0 != (result = s3fscurl_para->PreGetObjectRequest(tpath, fd, (start + size - remaining_bytes), chunk))){
|
if(0 != (result = s3fscurl_para->PreGetObjectRequest(tpath, fd, (start + size - remaining_bytes), chunk, sseckeymd5))){
|
||||||
DPRN("failed downloading part setup(%d)", result);
|
DPRN("failed downloading part setup(%d)", result);
|
||||||
delete s3fscurl_para;
|
delete s3fscurl_para;
|
||||||
return result;
|
return result;
|
||||||
@ -1053,7 +1237,8 @@ bool S3fsCurl::CheckIAMCredentialUpdate(void)
|
|||||||
S3fsCurl::S3fsCurl(bool ahbe) :
|
S3fsCurl::S3fsCurl(bool ahbe) :
|
||||||
hCurl(NULL), path(""), base_path(""), saved_path(""), url(""), requestHeaders(NULL),
|
hCurl(NULL), path(""), base_path(""), saved_path(""), url(""), requestHeaders(NULL),
|
||||||
bodydata(NULL), headdata(NULL), LastResponseCode(-1), postdata(NULL), postdata_remaining(0), is_use_ahbe(ahbe),
|
bodydata(NULL), headdata(NULL), LastResponseCode(-1), postdata(NULL), postdata_remaining(0), is_use_ahbe(ahbe),
|
||||||
retry_count(0), b_infile(NULL), b_postdata(NULL), b_postdata_remaining(0), b_partdata_startpos(0), b_partdata_size(0)
|
retry_count(0), b_infile(NULL), b_postdata(NULL), b_postdata_remaining(0), b_partdata_startpos(0), b_partdata_size(0),
|
||||||
|
b_ssekey_pos(-1), b_ssekey_md5("")
|
||||||
{
|
{
|
||||||
type = REQTYPE_UNSET;
|
type = REQTYPE_UNSET;
|
||||||
}
|
}
|
||||||
@ -1728,12 +1913,38 @@ int S3fsCurl::GetIAMCredentials(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If md5 is empty, build by first(current) sse key
|
||||||
|
//
|
||||||
|
bool S3fsCurl::AddSseKeyRequestHead(string& md5, bool is_copy)
|
||||||
|
{
|
||||||
|
if(!S3fsCurl::IsSseCustomMode()){
|
||||||
|
// Nothing to do
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
string sseckey;
|
||||||
|
if(S3fsCurl::GetSseKey(md5, sseckey)){
|
||||||
|
if(is_copy){
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-copy-source-server-side-encryption-customer-algorithm:AES256");
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("x-amz-copy-source-server-side-encryption-customer-key:" + sseckey).c_str());
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("x-amz-copy-source-server-side-encryption-customer-key-md5:" + md5).c_str());
|
||||||
|
}else{
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption-customer-algorithm:AES256");
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("x-amz-server-side-encryption-customer-key:" + sseckey).c_str());
|
||||||
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("x-amz-server-side-encryption-customer-key-md5:" + md5).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// tpath : target path for head request
|
// tpath : target path for head request
|
||||||
// bpath : saved into base_path
|
// bpath : saved into base_path
|
||||||
// savedpath : saved into saved_path
|
// savedpath : saved into saved_path
|
||||||
|
// ssekey_pos : -1 means "not use sse", 0 - X means "use sseckey" and "sseckey position".
|
||||||
|
// sseckey position 0 is latest key.
|
||||||
//
|
//
|
||||||
bool S3fsCurl::PreHeadRequest(const char* tpath, const char* bpath, const char* savedpath)
|
bool S3fsCurl::PreHeadRequest(const char* tpath, const char* bpath, const char* savedpath, int ssekey_pos)
|
||||||
{
|
{
|
||||||
FPRNINFO("[tpath=%s][bpath=%s][save=%s]", SAFESTRPTR(tpath), SAFESTRPTR(bpath), SAFESTRPTR(savedpath));
|
FPRNINFO("[tpath=%s][bpath=%s][save=%s]", SAFESTRPTR(tpath), SAFESTRPTR(bpath), SAFESTRPTR(savedpath));
|
||||||
|
|
||||||
@ -1759,6 +1970,15 @@ bool S3fsCurl::PreHeadRequest(const char* tpath, const char* bpath, const char*
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string("Date: " + date).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("Date: " + date).c_str());
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "Content-Type: ");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "Content-Type: ");
|
||||||
|
|
||||||
|
if(0 <= ssekey_pos && S3fsCurl::IsSseCustomMode()){
|
||||||
|
string md5;
|
||||||
|
if(!S3fsCurl::GetSseKeyMd5(ssekey_pos, md5) || !AddSseKeyRequestHead(md5, false)){
|
||||||
|
DPRN("Failed to set SSE-C headers for md5(%s).", md5.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b_ssekey_pos = ssekey_pos;
|
||||||
|
|
||||||
if(!S3fsCurl::IsPublicBucket()){
|
if(!S3fsCurl::IsPublicBucket()){
|
||||||
requestHeaders = curl_slist_sort_insert(
|
requestHeaders = curl_slist_sort_insert(
|
||||||
requestHeaders,
|
requestHeaders,
|
||||||
@ -1782,32 +2002,53 @@ bool S3fsCurl::PreHeadRequest(const char* tpath, const char* bpath, const char*
|
|||||||
|
|
||||||
int S3fsCurl::HeadRequest(const char* tpath, headers_t& meta)
|
int S3fsCurl::HeadRequest(const char* tpath, headers_t& meta)
|
||||||
{
|
{
|
||||||
int result;
|
int result = -1;
|
||||||
|
|
||||||
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
||||||
|
|
||||||
if(!PreHeadRequest(tpath)){
|
if(S3fsCurl::IsSseCustomMode()){
|
||||||
return -1;
|
// SSE-C mode, check all sse-c key at first
|
||||||
}
|
int pos;
|
||||||
// Requests
|
for(pos = 0; static_cast<size_t>(pos) < S3fsCurl::sseckeys.size(); pos++){
|
||||||
if(0 != (result = RequestPerform())){
|
if(0 != pos && !DestroyCurlHandle()){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if(!PreHeadRequest(tpath, NULL, NULL, pos)){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if(0 == (result = RequestPerform())){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(S3fsCurl::sseckeys.size() <= static_cast<size_t>(pos)){
|
||||||
|
// If sse-c mode is enable, s3fs fails to get head request for normal and sse object.
|
||||||
|
// So try to get head without sse-c header.
|
||||||
|
if(!DestroyCurlHandle() || !PreHeadRequest(tpath, NULL, NULL, -1) || 0 != (result = RequestPerform())){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Not sse-c mode
|
||||||
|
if(!PreHeadRequest(tpath) || 0 != (result = RequestPerform())){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// file exists in s3
|
// file exists in s3
|
||||||
// fixme: clean this up.
|
// fixme: clean this up.
|
||||||
meta.clear();
|
meta.clear();
|
||||||
for(headers_t::iterator iter = responseHeaders.begin(); iter != responseHeaders.end(); ++iter){
|
for(headers_t::iterator iter = responseHeaders.begin(); iter != responseHeaders.end(); ++iter){
|
||||||
string key = (*iter).first;
|
string key = (*iter).first;
|
||||||
string value = (*iter).second;
|
string value = (*iter).second;
|
||||||
if(key == "Content-Type"){
|
if(0 == strcasecmp(key.c_str(), "Content-Type")){
|
||||||
meta[key] = value;
|
meta[key] = value;
|
||||||
}else if(key == "Content-Length"){
|
}else if(0 == strcasecmp(key.c_str(), "Content-Length")){
|
||||||
meta[key] = value;
|
meta[key] = value;
|
||||||
}else if(key == "ETag"){
|
}else if(0 == strcasecmp(key.c_str(), "ETag")){
|
||||||
meta[key] = value;
|
meta[key] = value;
|
||||||
}else if(key == "Last-Modified"){
|
}else if(0 == strcasecmp(key.c_str(), "Last-Modified")){
|
||||||
meta[key] = value;
|
meta[key] = value;
|
||||||
}else if(key.substr(0, 5) == "x-amz"){
|
}else if(0 == strcasecmp(key.substr(0, 5).c_str(), "x-amz")){
|
||||||
meta[key] = value;
|
meta[key] = value;
|
||||||
}else{
|
}else{
|
||||||
// Check for upper case
|
// Check for upper case
|
||||||
@ -1820,7 +2061,7 @@ int S3fsCurl::HeadRequest(const char* tpath, headers_t& meta)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool ow_sse_flg)
|
int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool is_copy)
|
||||||
{
|
{
|
||||||
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
||||||
|
|
||||||
@ -1848,18 +2089,24 @@ int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool ow_sse_flg
|
|||||||
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
||||||
string key = (*iter).first;
|
string key = (*iter).first;
|
||||||
string value = (*iter).second;
|
string value = (*iter).second;
|
||||||
if(key == "Content-Type"){
|
if(0 == strcasecmp(key.c_str(), "Content-Type")){
|
||||||
ContentType = value;
|
ContentType = value;
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}else if(key.substr(0,9) == "x-amz-acl"){
|
}else if(0 == strcasecmp(key.substr(0,9).c_str(), "x-amz-acl")){
|
||||||
// not set value, but after set it.
|
// not set value, but after set it.
|
||||||
}else if(key.substr(0,10) == "x-amz-meta"){
|
}else if(0 == strcasecmp(key.substr(0,10).c_str(), "x-amz-meta")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}else if(key == "x-amz-copy-source"){
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-copy-source")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
|
||||||
}else if(!ow_sse_flg && key == "x-amz-server-side-encryption"){
|
|
||||||
// If ow_sse_flg is false, SSE inherit from meta.
|
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption")){
|
||||||
|
// skip this header, because this header is specified after logic.
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-algorithm")){
|
||||||
|
// skip this header, because this header is specified with "x-amz-...-customer-key-md5".
|
||||||
|
}else if(is_copy && 0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-key-md5")){
|
||||||
|
// Only copy mode.
|
||||||
|
if(!AddSseKeyRequestHead(value, is_copy)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// "x-amz-acl", rrs, sse
|
// "x-amz-acl", rrs, sse
|
||||||
@ -1867,8 +2114,13 @@ int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool ow_sse_flg
|
|||||||
if(S3fsCurl::is_use_rrs){
|
if(S3fsCurl::is_use_rrs){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
||||||
}
|
}
|
||||||
if(ow_sse_flg && S3fsCurl::is_use_sse){
|
if(S3fsCurl::is_use_sse){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
||||||
|
}else if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
string md5;
|
||||||
|
if(!AddSseKeyRequestHead(md5, false)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(is_use_ahbe){
|
if(is_use_ahbe){
|
||||||
// set additional header by ahbe conf
|
// set additional header by ahbe conf
|
||||||
@ -1900,7 +2152,7 @@ int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool ow_sse_flg
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg)
|
int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE* file = NULL;
|
FILE* file = NULL;
|
||||||
@ -1953,16 +2205,19 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse
|
|||||||
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
||||||
string key = (*iter).first;
|
string key = (*iter).first;
|
||||||
string value = (*iter).second;
|
string value = (*iter).second;
|
||||||
if(key == "Content-Type"){
|
if(0 == strcasecmp(key.c_str(), "Content-Type")){
|
||||||
ContentType = value;
|
ContentType = value;
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}else if(key.substr(0,9) == "x-amz-acl"){
|
}else if(0 == strcasecmp(key.substr(0,9).c_str(), "x-amz-acl")){
|
||||||
// not set value, but after set it.
|
// not set value, but after set it.
|
||||||
}else if(key.substr(0,10) == "x-amz-meta"){
|
}else if(0 == strcasecmp(key.substr(0,10).c_str(), "x-amz-meta")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
|
||||||
}else if(!ow_sse_flg && key == "x-amz-server-side-encryption"){
|
|
||||||
// If ow_sse_flg is false, SSE inherit from meta.
|
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption")){
|
||||||
|
// skip this header, because this header is specified after logic.
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-algorithm")){
|
||||||
|
// skip this header, because this header is specified after logic.
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-key-md5")){
|
||||||
|
// skip this header, because this header is specified after logic.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// "x-amz-acl", rrs, sse
|
// "x-amz-acl", rrs, sse
|
||||||
@ -1970,8 +2225,13 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse
|
|||||||
if(S3fsCurl::is_use_rrs){
|
if(S3fsCurl::is_use_rrs){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
||||||
}
|
}
|
||||||
if(ow_sse_flg && S3fsCurl::is_use_sse){
|
if(S3fsCurl::is_use_sse){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
||||||
|
}else if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
string md5;
|
||||||
|
if(!AddSseKeyRequestHead(md5, false)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(is_use_ahbe){
|
if(is_use_ahbe){
|
||||||
// set additional header by ahbe conf
|
// set additional header by ahbe conf
|
||||||
@ -2011,7 +2271,7 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size)
|
int S3fsCurl::PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size, string& ssekeymd5)
|
||||||
{
|
{
|
||||||
FPRNNN("[tpath=%s][start=%jd][size=%zd]", SAFESTRPTR(tpath), (intmax_t)start, size);
|
FPRNNN("[tpath=%s][start=%jd][size=%zd]", SAFESTRPTR(tpath), (intmax_t)start, size);
|
||||||
|
|
||||||
@ -2041,6 +2301,11 @@ int S3fsCurl::PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_
|
|||||||
range += str(start + size - 1);
|
range += str(start + size - 1);
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, range.c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, range.c_str());
|
||||||
}
|
}
|
||||||
|
if(0 < ssekeymd5.length()){
|
||||||
|
if(!AddSseKeyRequestHead(ssekeymd5, false)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!S3fsCurl::IsPublicBucket()){
|
if(!S3fsCurl::IsPublicBucket()){
|
||||||
requestHeaders = curl_slist_sort_insert(
|
requestHeaders = curl_slist_sort_insert(
|
||||||
@ -2063,6 +2328,7 @@ int S3fsCurl::PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_
|
|||||||
partdata.size = size;
|
partdata.size = size;
|
||||||
b_partdata_startpos = start;
|
b_partdata_startpos = start;
|
||||||
b_partdata_size = size;
|
b_partdata_size = size;
|
||||||
|
b_ssekey_md5 = ssekeymd5;
|
||||||
|
|
||||||
type = REQTYPE_GET;
|
type = REQTYPE_GET;
|
||||||
|
|
||||||
@ -2078,7 +2344,13 @@ int S3fsCurl::GetObjectRequest(const char* tpath, int fd, off_t start, ssize_t s
|
|||||||
if(!tpath){
|
if(!tpath){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(0 != (result = PreGetObjectRequest(tpath, fd, start, size))){
|
string sseckeymd5("");
|
||||||
|
char* psseckeymd5;
|
||||||
|
if(NULL != (psseckeymd5 = get_object_sseckey_md5(tpath))){
|
||||||
|
sseckeymd5 = psseckeymd5;
|
||||||
|
free(psseckeymd5);
|
||||||
|
}
|
||||||
|
if(0 != (result = PreGetObjectRequest(tpath, fd, start, size, sseckeymd5))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2187,7 +2459,7 @@ int S3fsCurl::ListBucketRequest(const char* tpath, const char* query)
|
|||||||
// Date: Mon, 1 Nov 2010 20:34:56 GMT
|
// Date: Mon, 1 Nov 2010 20:34:56 GMT
|
||||||
// Authorization: AWS VGhpcyBtZXNzYWdlIHNpZ25lZCBieSBlbHZpbmc=
|
// Authorization: AWS VGhpcyBtZXNzYWdlIHNpZ25lZCBieSBlbHZpbmc=
|
||||||
//
|
//
|
||||||
int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string& upload_id, bool ow_sse_flg)
|
int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string& upload_id, bool is_copy)
|
||||||
{
|
{
|
||||||
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
||||||
|
|
||||||
@ -2220,13 +2492,19 @@ int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string
|
|||||||
string key = (*iter).first;
|
string key = (*iter).first;
|
||||||
string value = (*iter).second;
|
string value = (*iter).second;
|
||||||
|
|
||||||
if(key.substr(0,9) == "x-amz-acl"){
|
if(0 == strcasecmp(key.substr(0,9).c_str(), "x-amz-acl")){
|
||||||
// not set value, but after set it.
|
// not set value, but after set it.
|
||||||
}else if(key.substr(0,10) == "x-amz-meta"){
|
}else if(0 == strcasecmp(key.substr(0,10).c_str(), "x-amz-meta")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
|
||||||
}else if(!ow_sse_flg && key == "x-amz-server-side-encryption"){
|
|
||||||
// If ow_sse_flg is false, SSE inherit from meta.
|
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption")){
|
||||||
|
// skip this header, because this header is specified after logic.
|
||||||
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-algorithm")){
|
||||||
|
// skip this header, because this header is specified with "x-amz-...-customer-key-md5".
|
||||||
|
}else if(is_copy && 0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-key-md5")){
|
||||||
|
// Only copy mode.
|
||||||
|
if(!AddSseKeyRequestHead(value, is_copy)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// "x-amz-acl", rrs, sse
|
// "x-amz-acl", rrs, sse
|
||||||
@ -2234,8 +2512,13 @@ int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string
|
|||||||
if(S3fsCurl::is_use_rrs){
|
if(S3fsCurl::is_use_rrs){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class:REDUCED_REDUNDANCY");
|
||||||
}
|
}
|
||||||
if(ow_sse_flg && S3fsCurl::is_use_sse){
|
if(S3fsCurl::is_use_sse){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-server-side-encryption:AES256");
|
||||||
|
}else if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
string md5;
|
||||||
|
if(!AddSseKeyRequestHead(md5, false)){
|
||||||
|
DPRNNN("Failed to insert sse(-c) header.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(is_use_ahbe){
|
if(is_use_ahbe){
|
||||||
// set additional header by ahbe conf
|
// set additional header by ahbe conf
|
||||||
@ -2584,12 +2867,12 @@ int S3fsCurl::CopyMultipartPostRequest(const char* from, const char* to, int par
|
|||||||
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
||||||
string key = (*iter).first;
|
string key = (*iter).first;
|
||||||
string value = (*iter).second;
|
string value = (*iter).second;
|
||||||
if(key == "Content-Type"){
|
if(0 == strcasecmp(key.c_str(), "Content-Type")){
|
||||||
ContentType = value;
|
ContentType = value;
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}else if(key == "x-amz-copy-source"){
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-copy-source")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}else if(key == "x-amz-copy-source-range"){
|
}else if(0 == strcasecmp(key.c_str(), "x-amz-copy-source-range")){
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string(key + ":" + value).c_str());
|
||||||
}
|
}
|
||||||
// NOTICE: x-amz-acl, x-amz-server-side-encryption is not set!
|
// NOTICE: x-amz-acl, x-amz-server-side-encryption is not set!
|
||||||
@ -2632,7 +2915,7 @@ int S3fsCurl::CopyMultipartPostRequest(const char* from, const char* to, int par
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::MultipartHeadRequest(const char* tpath, off_t size, headers_t& meta)
|
int S3fsCurl::MultipartHeadRequest(const char* tpath, off_t size, headers_t& meta, bool is_copy)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
string upload_id;
|
string upload_id;
|
||||||
@ -2643,7 +2926,7 @@ int S3fsCurl::MultipartHeadRequest(const char* tpath, off_t size, headers_t& met
|
|||||||
|
|
||||||
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
FPRNNN("[tpath=%s]", SAFESTRPTR(tpath));
|
||||||
|
|
||||||
if(0 != (result = PreMultipartPostRequest(tpath, meta, upload_id, false))){
|
if(0 != (result = PreMultipartPostRequest(tpath, meta, upload_id, is_copy))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DestroyCurlHandle();
|
DestroyCurlHandle();
|
||||||
@ -2669,7 +2952,7 @@ int S3fsCurl::MultipartHeadRequest(const char* tpath, off_t size, headers_t& met
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S3fsCurl::MultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg)
|
int S3fsCurl::MultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool is_copy)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
string upload_id;
|
string upload_id;
|
||||||
@ -2695,7 +2978,7 @@ int S3fsCurl::MultipartUploadRequest(const char* tpath, headers_t& meta, int fd,
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 != (result = PreMultipartPostRequest(tpath, meta, upload_id, ow_sse_flg))){
|
if(0 != (result = PreMultipartPostRequest(tpath, meta, upload_id, is_copy))){
|
||||||
close(fd2);
|
close(fd2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2748,7 +3031,7 @@ int S3fsCurl::MultipartRenameRequest(const char* from, const char* to, headers_t
|
|||||||
meta["Content-Type"] = S3fsCurl::LookupMimeType(string(to));
|
meta["Content-Type"] = S3fsCurl::LookupMimeType(string(to));
|
||||||
meta["x-amz-copy-source"] = srcresource;
|
meta["x-amz-copy-source"] = srcresource;
|
||||||
|
|
||||||
if(0 != (result = PreMultipartPostRequest(to, meta, upload_id, false))){
|
if(0 != (result = PreMultipartPostRequest(to, meta, upload_id, true))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DestroyCurlHandle();
|
DestroyCurlHandle();
|
||||||
|
34
src/curl.h
34
src/curl.h
@ -100,6 +100,8 @@ class S3fsMultiCurl;
|
|||||||
// class S3fsCurl
|
// class S3fsCurl
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
typedef std::map<std::string, std::string> iamcredmap_t;
|
typedef std::map<std::string, std::string> iamcredmap_t;
|
||||||
|
typedef std::map<std::string, std::string> sseckeymap_t;
|
||||||
|
typedef std::list<sseckeymap_t> sseckeylist_t;
|
||||||
|
|
||||||
// share
|
// share
|
||||||
#define SHARE_MUTEX_DNS 0
|
#define SHARE_MUTEX_DNS 0
|
||||||
@ -144,6 +146,7 @@ class S3fsCurl
|
|||||||
static bool is_public_bucket;
|
static bool is_public_bucket;
|
||||||
static std::string default_acl; // TODO: to enum
|
static std::string default_acl; // TODO: to enum
|
||||||
static bool is_use_rrs;
|
static bool is_use_rrs;
|
||||||
|
static sseckeylist_t sseckeys;
|
||||||
static bool is_use_sse;
|
static bool is_use_sse;
|
||||||
static bool is_content_md5;
|
static bool is_content_md5;
|
||||||
static bool is_verbose;
|
static bool is_verbose;
|
||||||
@ -182,6 +185,8 @@ class S3fsCurl
|
|||||||
int b_postdata_remaining; // backup for retrying
|
int b_postdata_remaining; // backup for retrying
|
||||||
off_t b_partdata_startpos; // backup for retrying
|
off_t b_partdata_startpos; // backup for retrying
|
||||||
ssize_t b_partdata_size; // backup for retrying
|
ssize_t b_partdata_size; // backup for retrying
|
||||||
|
bool b_ssekey_pos; // backup for retrying
|
||||||
|
std::string b_ssekey_md5; // backup for retrying
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor/destructor
|
// constructor/destructor
|
||||||
@ -214,6 +219,7 @@ class S3fsCurl
|
|||||||
|
|
||||||
static bool ParseIAMCredentialResponse(const char* response, iamcredmap_t& keyval);
|
static bool ParseIAMCredentialResponse(const char* response, iamcredmap_t& keyval);
|
||||||
static bool SetIAMCredentials(const char* response);
|
static bool SetIAMCredentials(const char* response);
|
||||||
|
static bool PushbackSseKeys(std::string& onekey);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
bool ResetHandle(void);
|
bool ResetHandle(void);
|
||||||
@ -223,7 +229,7 @@ class S3fsCurl
|
|||||||
bool GetUploadId(std::string& upload_id);
|
bool GetUploadId(std::string& upload_id);
|
||||||
int GetIAMCredentials(void);
|
int GetIAMCredentials(void);
|
||||||
|
|
||||||
int PreMultipartPostRequest(const char* tpath, headers_t& meta, std::string& upload_id, bool ow_sse_flg);
|
int PreMultipartPostRequest(const char* tpath, headers_t& meta, std::string& upload_id, bool is_copy);
|
||||||
int CompleteMultipartPostRequest(const char* tpath, std::string& upload_id, etaglist_t& parts);
|
int CompleteMultipartPostRequest(const char* tpath, std::string& upload_id, etaglist_t& parts);
|
||||||
int UploadMultipartPostSetup(const char* tpath, int part_num, std::string& upload_id);
|
int UploadMultipartPostSetup(const char* tpath, int part_num, std::string& upload_id);
|
||||||
int UploadMultipartPostRequest(const char* tpath, int part_num, std::string& upload_id);
|
int UploadMultipartPostRequest(const char* tpath, int part_num, std::string& upload_id);
|
||||||
@ -233,7 +239,7 @@ class S3fsCurl
|
|||||||
// class methods
|
// class methods
|
||||||
static bool InitS3fsCurl(const char* MimeFile = NULL);
|
static bool InitS3fsCurl(const char* MimeFile = NULL);
|
||||||
static bool DestroyS3fsCurl(void);
|
static bool DestroyS3fsCurl(void);
|
||||||
static int ParallelMultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg);
|
static int ParallelMultipartUploadRequest(const char* tpath, headers_t& meta, int fd);
|
||||||
static int ParallelGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size);
|
static int ParallelGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size);
|
||||||
static bool CheckIAMCredentialUpdate(void);
|
static bool CheckIAMCredentialUpdate(void);
|
||||||
|
|
||||||
@ -250,6 +256,12 @@ class S3fsCurl
|
|||||||
static std::string SetDefaultAcl(const char* acl);
|
static std::string SetDefaultAcl(const char* acl);
|
||||||
static bool SetUseRrs(bool flag);
|
static bool SetUseRrs(bool flag);
|
||||||
static bool GetUseRrs(void) { return S3fsCurl::is_use_rrs; }
|
static bool GetUseRrs(void) { return S3fsCurl::is_use_rrs; }
|
||||||
|
static bool SetSseKeys(const char* filepath);
|
||||||
|
static bool LoadEnvSseKeys(void);
|
||||||
|
static bool GetSseKey(std::string& md5, std::string& ssekey);
|
||||||
|
static bool GetSseKeyMd5(int pos, std::string& md5);
|
||||||
|
static int GetSseKeyCount(void);
|
||||||
|
static bool IsSseCustomMode(void);
|
||||||
static bool SetUseSse(bool flag);
|
static bool SetUseSse(bool flag);
|
||||||
static bool GetUseSse(void) { return S3fsCurl::is_use_sse; }
|
static bool GetUseSse(void) { return S3fsCurl::is_use_sse; }
|
||||||
static bool SetContentMd5(bool flag);
|
static bool SetContentMd5(bool flag);
|
||||||
@ -272,24 +284,25 @@ class S3fsCurl
|
|||||||
bool CreateCurlHandle(bool force = false);
|
bool CreateCurlHandle(bool force = false);
|
||||||
bool DestroyCurlHandle(void);
|
bool DestroyCurlHandle(void);
|
||||||
|
|
||||||
|
bool AddSseKeyRequestHead(std::string& md5, bool is_copy);
|
||||||
bool GetResponseCode(long& responseCode);
|
bool GetResponseCode(long& responseCode);
|
||||||
int RequestPerform(void);
|
int RequestPerform(void);
|
||||||
int DeleteRequest(const char* tpath);
|
int DeleteRequest(const char* tpath);
|
||||||
bool PreHeadRequest(const char* tpath, const char* bpath = NULL, const char* savedpath = NULL);
|
bool PreHeadRequest(const char* tpath, const char* bpath = NULL, const char* savedpath = NULL, int ssekey_pos = -1);
|
||||||
bool PreHeadRequest(std::string& tpath, std::string& bpath, std::string& savedpath) {
|
bool PreHeadRequest(std::string& tpath, std::string& bpath, std::string& savedpath, int ssekey_pos = -1) {
|
||||||
return PreHeadRequest(tpath.c_str(), bpath.c_str(), savedpath.c_str());
|
return PreHeadRequest(tpath.c_str(), bpath.c_str(), savedpath.c_str(), ssekey_pos);
|
||||||
}
|
}
|
||||||
int HeadRequest(const char* tpath, headers_t& meta);
|
int HeadRequest(const char* tpath, headers_t& meta);
|
||||||
int PutHeadRequest(const char* tpath, headers_t& meta, bool ow_sse_flg);
|
int PutHeadRequest(const char* tpath, headers_t& meta, bool is_copy);
|
||||||
int PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg);
|
int PutRequest(const char* tpath, headers_t& meta, int fd);
|
||||||
int PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size);
|
int PreGetObjectRequest(const char* tpath, int fd, off_t start, ssize_t size, std::string& ssekeymd5);
|
||||||
int GetObjectRequest(const char* tpath, int fd, off_t start = -1, ssize_t size = -1);
|
int GetObjectRequest(const char* tpath, int fd, off_t start = -1, ssize_t size = -1);
|
||||||
int CheckBucket(void);
|
int CheckBucket(void);
|
||||||
int ListBucketRequest(const char* tpath, const char* query);
|
int ListBucketRequest(const char* tpath, const char* query);
|
||||||
int MultipartListRequest(std::string& body);
|
int MultipartListRequest(std::string& body);
|
||||||
int AbortMultipartUpload(const char* tpath, std::string& upload_id);
|
int AbortMultipartUpload(const char* tpath, std::string& upload_id);
|
||||||
int MultipartHeadRequest(const char* tpath, off_t size, headers_t& meta);
|
int MultipartHeadRequest(const char* tpath, off_t size, headers_t& meta, bool is_copy);
|
||||||
int MultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse_flg);
|
int MultipartUploadRequest(const char* tpath, headers_t& meta, int fd, bool is_copy);
|
||||||
int MultipartRenameRequest(const char* from, const char* to, headers_t& meta, off_t size);
|
int MultipartRenameRequest(const char* from, const char* to, headers_t& meta, off_t size);
|
||||||
|
|
||||||
// methods(valiables)
|
// methods(valiables)
|
||||||
@ -309,6 +322,7 @@ class S3fsCurl
|
|||||||
int GetMultipartRetryCount(void) const { return retry_count; }
|
int GetMultipartRetryCount(void) const { return retry_count; }
|
||||||
void SetMultipartRetryCount(int retrycnt) { retry_count = retrycnt; }
|
void SetMultipartRetryCount(int retrycnt) { retry_count = retrycnt; }
|
||||||
bool IsOverMultipartRetryCount(void) const { return (retry_count >= S3fsCurl::retries); }
|
bool IsOverMultipartRetryCount(void) const { return (retry_count >= S3fsCurl::retries); }
|
||||||
|
int GetLastPreHeadSeecKeyPos(void) const { return b_ssekey_pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
|
@ -855,7 +855,7 @@ bool FdEntity::LoadFull(off_t* size, bool force_load)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FdEntity::RowFlush(const char* tpath, headers_t& meta, bool ow_sse_flg, bool force_sync)
|
int FdEntity::RowFlush(const char* tpath, headers_t& meta, bool force_sync)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@ -902,13 +902,13 @@ int FdEntity::RowFlush(const char* tpath, headers_t& meta, bool ow_sse_flg, bool
|
|||||||
if(120 > S3fsCurl::GetReadwriteTimeout()){
|
if(120 > S3fsCurl::GetReadwriteTimeout()){
|
||||||
backup = S3fsCurl::SetReadwriteTimeout(120);
|
backup = S3fsCurl::SetReadwriteTimeout(120);
|
||||||
}
|
}
|
||||||
result = S3fsCurl::ParallelMultipartUploadRequest(tpath ? tpath : path.c_str(), meta, fd, ow_sse_flg);
|
result = S3fsCurl::ParallelMultipartUploadRequest(tpath ? tpath : path.c_str(), meta, fd);
|
||||||
if(0 != backup){
|
if(0 != backup){
|
||||||
S3fsCurl::SetReadwriteTimeout(backup);
|
S3fsCurl::SetReadwriteTimeout(backup);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
S3fsCurl s3fscurl(true);
|
S3fsCurl s3fscurl(true);
|
||||||
result = s3fscurl.PutRequest(tpath ? tpath : path.c_str(), meta, fd, ow_sse_flg);
|
result = s3fscurl.PutRequest(tpath ? tpath : path.c_str(), meta, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// seek to head of file.
|
// seek to head of file.
|
||||||
|
@ -110,8 +110,8 @@ class FdEntity
|
|||||||
bool SetAllDisable(void) { return SetAllStatus(false); }
|
bool SetAllDisable(void) { return SetAllStatus(false); }
|
||||||
bool LoadFull(off_t* size = NULL, bool force_load = false);
|
bool LoadFull(off_t* size = NULL, bool force_load = false);
|
||||||
int Load(off_t start, off_t size);
|
int Load(off_t start, off_t size);
|
||||||
int RowFlush(const char* tpath, headers_t& meta, bool ow_sse_flg, bool force_sync = false);
|
int RowFlush(const char* tpath, headers_t& meta, bool force_sync = false);
|
||||||
int Flush(headers_t& meta, bool ow_sse_flg, bool force_sync = false) { return RowFlush(NULL, meta, ow_sse_flg, force_sync); }
|
int Flush(headers_t& meta, bool force_sync = false) { return RowFlush(NULL, meta, force_sync); }
|
||||||
ssize_t Read(char* bytes, off_t start, size_t size, bool force_load = false);
|
ssize_t Read(char* bytes, off_t start, size_t size, bool force_load = false);
|
||||||
ssize_t Write(const char* bytes, off_t start, size_t size);
|
ssize_t Write(const char* bytes, off_t start, size_t size);
|
||||||
};
|
};
|
||||||
|
119
src/s3fs.cpp
119
src/s3fs.cpp
@ -135,7 +135,7 @@ static xmlChar* get_base_exp(xmlDocPtr doc, const char* exp);
|
|||||||
static xmlChar* get_prefix(xmlDocPtr doc);
|
static xmlChar* get_prefix(xmlDocPtr doc);
|
||||||
static xmlChar* get_next_marker(xmlDocPtr doc);
|
static xmlChar* get_next_marker(xmlDocPtr doc);
|
||||||
static char* get_object_name(xmlDocPtr doc, xmlNodePtr node, const char* path);
|
static char* get_object_name(xmlDocPtr doc, xmlNodePtr node, const char* path);
|
||||||
static int put_headers(const char* path, headers_t& meta, bool ow_sse_flg);
|
static int put_headers(const char* path, headers_t& meta, bool is_copy);
|
||||||
static int rename_large_object(const char* from, const char* to);
|
static int rename_large_object(const char* from, const char* to);
|
||||||
static int create_file_object(const char* path, mode_t mode, uid_t uid, gid_t gid);
|
static int create_file_object(const char* path, mode_t mode, uid_t uid, gid_t gid);
|
||||||
static int create_directory_object(const char* path, mode_t mode, time_t time, uid_t uid, gid_t gid);
|
static int create_directory_object(const char* path, mode_t mode, time_t time, uid_t uid, gid_t gid);
|
||||||
@ -610,6 +610,30 @@ static int check_parent_object_access(const char* path, int mask)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This function is global, is called fom curl class(GetObject).
|
||||||
|
//
|
||||||
|
char* get_object_sseckey_md5(const char* path)
|
||||||
|
{
|
||||||
|
if(!path){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
headers_t meta;
|
||||||
|
|
||||||
|
if(0 != get_object_attribute(path, NULL, &meta)){
|
||||||
|
DPRNNN("Failed to get object(%s) headers", path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(headers_t::iterator iter = meta.begin(); iter != meta.end(); ++iter){
|
||||||
|
string key = (*iter).first;
|
||||||
|
if(0 == strcasecmp(key.c_str(), "x-amz-server-side-encryption-customer-key-md5")){
|
||||||
|
return strdup((*iter).second.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static FdEntity* get_local_fent(const char* path, bool is_load)
|
static FdEntity* get_local_fent(const char* path, bool is_load)
|
||||||
{
|
{
|
||||||
struct stat stobj;
|
struct stat stobj;
|
||||||
@ -644,7 +668,7 @@ static FdEntity* get_local_fent(const char* path, bool is_load)
|
|||||||
* ow_sse_flg is for over writing sse header by use_sse option.
|
* ow_sse_flg is for over writing sse header by use_sse option.
|
||||||
* @return fuse return code
|
* @return fuse return code
|
||||||
*/
|
*/
|
||||||
static int put_headers(const char* path, headers_t& meta, bool ow_sse_flg)
|
static int put_headers(const char* path, headers_t& meta, bool is_copy)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
S3fsCurl s3fscurl(true);
|
S3fsCurl s3fscurl(true);
|
||||||
@ -659,11 +683,11 @@ static int put_headers(const char* path, headers_t& meta, bool ow_sse_flg)
|
|||||||
|
|
||||||
if(buf.st_size >= FIVE_GB){
|
if(buf.st_size >= FIVE_GB){
|
||||||
// multipart
|
// multipart
|
||||||
if(0 != (result = s3fscurl.MultipartHeadRequest(path, buf.st_size, meta))){
|
if(0 != (result = s3fscurl.MultipartHeadRequest(path, buf.st_size, meta, is_copy))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(0 != (result = s3fscurl.PutHeadRequest(path, meta, ow_sse_flg))){
|
if(0 != (result = s3fscurl.PutHeadRequest(path, meta, is_copy))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -767,7 +791,7 @@ static int create_file_object(const char* path, mode_t mode, uid_t uid, gid_t gi
|
|||||||
meta["x-amz-meta-mtime"] = str(time(NULL));
|
meta["x-amz-meta-mtime"] = str(time(NULL));
|
||||||
|
|
||||||
S3fsCurl s3fscurl(true);
|
S3fsCurl s3fscurl(true);
|
||||||
return s3fscurl.PutRequest(path, meta, -1, false); // fd=-1 means for creating zero byte object.
|
return s3fscurl.PutRequest(path, meta, -1); // fd=-1 means for creating zero byte object.
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3fs_mknod(const char *path, mode_t mode, dev_t rdev)
|
static int s3fs_mknod(const char *path, mode_t mode, dev_t rdev)
|
||||||
@ -852,7 +876,7 @@ static int create_directory_object(const char* path, mode_t mode, time_t time, u
|
|||||||
meta["x-amz-meta-mtime"] = str(time);
|
meta["x-amz-meta-mtime"] = str(time);
|
||||||
|
|
||||||
S3fsCurl s3fscurl;
|
S3fsCurl s3fscurl;
|
||||||
return s3fscurl.PutRequest(tpath.c_str(), meta, -1, false); // fd=-1 means for creating zero byte object.
|
return s3fscurl.PutRequest(tpath.c_str(), meta, -1); // fd=-1 means for creating zero byte object.
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3fs_mkdir(const char* path, mode_t mode)
|
static int s3fs_mkdir(const char* path, mode_t mode)
|
||||||
@ -1014,7 +1038,7 @@ static int s3fs_symlink(const char* from, const char* to)
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(headers, true, true))){
|
if(0 != (result = ent->Flush(headers, true))){
|
||||||
DPRN("could not upload tmpfile(result=%d)", result);
|
DPRN("could not upload tmpfile(result=%d)", result);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
@ -1050,7 +1074,7 @@ static int rename_object(const char* from, const char* to)
|
|||||||
meta["Content-Type"] = S3fsCurl::LookupMimeType(string(to));
|
meta["Content-Type"] = S3fsCurl::LookupMimeType(string(to));
|
||||||
meta["x-amz-metadata-directive"] = "REPLACE";
|
meta["x-amz-metadata-directive"] = "REPLACE";
|
||||||
|
|
||||||
if(0 != (result = put_headers(to, meta, false))){
|
if(0 != (result = put_headers(to, meta, true))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = s3fs_unlink(from);
|
result = s3fs_unlink(from);
|
||||||
@ -1091,7 +1115,7 @@ static int rename_object_nocopy(const char* from, const char* to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->RowFlush(to, meta, false, true))){
|
if(0 != (result = ent->RowFlush(to, meta, true))){
|
||||||
DPRN("could not upload file(%s): result=%d", to, result);
|
DPRN("could not upload file(%s): result=%d", to, result);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
return result;
|
return result;
|
||||||
@ -1391,7 +1415,7 @@ static int s3fs_chmod(const char* path, mode_t mode)
|
|||||||
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
||||||
meta["x-amz-metadata-directive"] = "REPLACE";
|
meta["x-amz-metadata-directive"] = "REPLACE";
|
||||||
|
|
||||||
if(put_headers(strpath.c_str(), meta, false) != 0){
|
if(put_headers(strpath.c_str(), meta, true) != 0){
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
@ -1467,7 +1491,7 @@ static int s3fs_chmod_nocopy(const char* path, mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(meta, false, true))){
|
if(0 != (result = ent->Flush(meta, true))){
|
||||||
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
return result;
|
return result;
|
||||||
@ -1553,7 +1577,7 @@ static int s3fs_chown(const char* path, uid_t uid, gid_t gid)
|
|||||||
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
||||||
meta["x-amz-metadata-directive"] = "REPLACE";
|
meta["x-amz-metadata-directive"] = "REPLACE";
|
||||||
|
|
||||||
if(put_headers(strpath.c_str(), meta, false) != 0){
|
if(put_headers(strpath.c_str(), meta, true) != 0){
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
@ -1639,7 +1663,7 @@ static int s3fs_chown_nocopy(const char* path, uid_t uid, gid_t gid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(meta, false, true))){
|
if(0 != (result = ent->Flush(meta, true))){
|
||||||
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
return result;
|
return result;
|
||||||
@ -1711,7 +1735,7 @@ static int s3fs_utimens(const char* path, const struct timespec ts[2])
|
|||||||
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
|
||||||
meta["x-amz-metadata-directive"] = "REPLACE";
|
meta["x-amz-metadata-directive"] = "REPLACE";
|
||||||
|
|
||||||
if(put_headers(strpath.c_str(), meta, false) != 0){
|
if(put_headers(strpath.c_str(), meta, true) != 0){
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
@ -1796,7 +1820,7 @@ static int s3fs_utimens_nocopy(const char* path, const struct timespec ts[2])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(meta, false, true))){
|
if(0 != (result = ent->Flush(meta, true))){
|
||||||
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
DPRN("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
return result;
|
return result;
|
||||||
@ -1847,7 +1871,7 @@ static int s3fs_truncate(const char* path, off_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(meta, false, true))){
|
if(0 != (result = ent->Flush(meta, true))){
|
||||||
DPRN("could not upload file(%s): result=%d", path, result);
|
DPRN("could not upload file(%s): result=%d", path, result);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
return result;
|
return result;
|
||||||
@ -2002,7 +2026,7 @@ static int s3fs_flush(const char* path, struct fuse_file_info* fi)
|
|||||||
meta["x-amz-meta-mtime"] = str(ent_mtime);
|
meta["x-amz-meta-mtime"] = str(ent_mtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = ent->Flush(meta, true, false);
|
result = ent->Flush(meta, false);
|
||||||
FdManager::get()->Close(ent);
|
FdManager::get()->Close(ent);
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -2078,22 +2102,36 @@ static S3fsCurl* multi_head_retry_callback(S3fsCurl* s3fscurl)
|
|||||||
if(!s3fscurl){
|
if(!s3fscurl){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
int ssec_key_pos = s3fscurl->GetLastPreHeadSeecKeyPos();
|
||||||
|
int next_retry_count = s3fscurl->GetMultipartRetryCount() + 1;
|
||||||
|
|
||||||
if(s3fscurl->IsOverMultipartRetryCount()){
|
if(s3fscurl->IsOverMultipartRetryCount()){
|
||||||
|
if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
// If sse-c mode, start check not sse-c(ssec_key_pos = -1).
|
||||||
|
// do increment ssec_key_pos for checking all sse-c key.
|
||||||
|
next_retry_count = 0;
|
||||||
|
ssec_key_pos++;
|
||||||
|
if(S3fsCurl::GetSseKeyCount() <= ssec_key_pos){
|
||||||
DPRN("Over retry count(%d) limit(%s).", s3fscurl->GetMultipartRetryCount(), s3fscurl->GetSpacialSavedPath().c_str());
|
DPRN("Over retry count(%d) limit(%s).", s3fscurl->GetMultipartRetryCount(), s3fscurl->GetSpacialSavedPath().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
DPRN("Over retry count(%d) limit(%s).", s3fscurl->GetMultipartRetryCount(), s3fscurl->GetSpacialSavedPath().c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
S3fsCurl* newcurl = new S3fsCurl(s3fscurl->IsUseAhbe());
|
S3fsCurl* newcurl = new S3fsCurl(s3fscurl->IsUseAhbe());
|
||||||
string path = s3fscurl->GetPath();
|
string path = s3fscurl->GetPath();
|
||||||
string base_path = s3fscurl->GetBasePath();
|
string base_path = s3fscurl->GetBasePath();
|
||||||
string saved_path = s3fscurl->GetSpacialSavedPath();
|
string saved_path = s3fscurl->GetSpacialSavedPath();
|
||||||
|
|
||||||
if(!newcurl->PreHeadRequest(path, base_path, saved_path)){
|
if(!newcurl->PreHeadRequest(path, base_path, saved_path, ssec_key_pos)){
|
||||||
DPRN("Could not duplicate curl object(%s).", saved_path.c_str());
|
DPRN("Could not duplicate curl object(%s).", saved_path.c_str());
|
||||||
delete newcurl;
|
delete newcurl;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
newcurl->SetMultipartRetryCount(s3fscurl->GetMultipartRetryCount() + 1);
|
newcurl->SetMultipartRetryCount(next_retry_count);
|
||||||
|
|
||||||
return newcurl;
|
return newcurl;
|
||||||
}
|
}
|
||||||
@ -2135,6 +2173,8 @@ static int readdir_multi_head(const char* path, S3ObjList& head, void* buf, fuse
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First check for directory, start checking "not sse-c".
|
||||||
|
// If checking failed, retry to check with "sse-c" by retry callback func when sse-c mode.
|
||||||
S3fsCurl* s3fscurl = new S3fsCurl();
|
S3fsCurl* s3fscurl = new S3fsCurl();
|
||||||
if(!s3fscurl->PreHeadRequest(disppath, (*iter), disppath)){ // target path = cache key path.(ex "dir/")
|
if(!s3fscurl->PreHeadRequest(disppath, (*iter), disppath)){ // target path = cache key path.(ex "dir/")
|
||||||
DPRNNN("Could not make curl object for head request(%s).", disppath.c_str());
|
DPRNNN("Could not make curl object for head request(%s).", disppath.c_str());
|
||||||
@ -3522,23 +3562,45 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(0 == strcmp(arg, "use_sse") || 0 == STR2NCMP(arg, "use_sse=")){
|
if(0 == strcmp(arg, "use_sse") || 0 == STR2NCMP(arg, "use_sse=")){
|
||||||
off_t sse = 1;
|
|
||||||
// for an old format.
|
|
||||||
if(0 == STR2NCMP(arg, "use_sse=")){
|
if(0 == STR2NCMP(arg, "use_sse=")){
|
||||||
sse = s3fs_strtoofft(strchr(arg, '=') + sizeof(char));
|
|
||||||
}
|
|
||||||
if(0 == sse){
|
|
||||||
S3fsCurl::SetUseSse(false);
|
|
||||||
}else if(1 == sse){
|
|
||||||
if(S3fsCurl::GetUseRrs()){
|
if(S3fsCurl::GetUseRrs()){
|
||||||
fprintf(stderr, "%s: use_sse option could not be specified with use_rrs.\n", program_name.c_str());
|
fprintf(stderr, "%s: use_sse option could not be specified with use_rrs.\n", program_name.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
const char* ssecfile = &arg[strlen("use_sse=")];
|
||||||
|
if(0 == strcmp(ssecfile, "1")){
|
||||||
|
if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
fprintf (stderr, "%s: already set SSE-C key by environment, and confrict use_sse option.\n", program_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
S3fsCurl::SetUseSse(true);
|
S3fsCurl::SetUseSse(true);
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "%s: poorly formed argument to option: use_sse\n", program_name.c_str());
|
// testing sse-c, try to load AES256 keys
|
||||||
|
struct stat st;
|
||||||
|
if(0 != stat(ssecfile, &st)){
|
||||||
|
fprintf (stderr, "%s: could not open use_sse keys file(%s)\n", program_name.c_str(), ssecfile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if(st.st_mode & (S_IXUSR | S_IRWXG | S_IRWXO)){
|
||||||
|
fprintf (stderr, "%s: use_sse keys file %s should be 0600 permissions\n", program_name.c_str(), ssecfile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(!S3fsCurl::SetSseKeys(ssecfile)){
|
||||||
|
fprintf (stderr, "%s: failed to load use_sse keys file %s\n", program_name.c_str(), ssecfile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(S3fsCurl::GetUseRrs()){
|
||||||
|
fprintf(stderr, "%s: use_sse option could not be specified with use_rrs.\n", program_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(S3fsCurl::IsSseCustomMode()){
|
||||||
|
fprintf (stderr, "%s: already set SSE-C key by environment, and confrict use_sse option.\n", program_name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
S3fsCurl::SetUseSse(true);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(0 == STR2NCMP(arg, "ssl_verify_hostname=")){
|
if(0 == STR2NCMP(arg, "ssl_verify_hostname=")){
|
||||||
@ -3790,6 +3852,9 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load SSE-C Key from env
|
||||||
|
S3fsCurl::LoadEnvSseKeys();
|
||||||
|
|
||||||
// clear this structure
|
// clear this structure
|
||||||
memset(&s3fs_oper, 0, sizeof(s3fs_oper));
|
memset(&s3fs_oper, 0, sizeof(s3fs_oper));
|
||||||
|
|
||||||
|
@ -65,4 +65,6 @@
|
|||||||
|
|
||||||
#endif // HAVE_MALLOC_TRIM
|
#endif // HAVE_MALLOC_TRIM
|
||||||
|
|
||||||
|
char* get_object_sseckey_md5(const char* path);
|
||||||
|
|
||||||
#endif // S3FS_S3_H_
|
#endif // S3FS_S3_H_
|
||||||
|
@ -875,7 +875,24 @@ void show_help (void)
|
|||||||
" - this option makes Amazon's Reduced Redundancy Storage enable.\n"
|
" - this option makes Amazon's Reduced Redundancy Storage enable.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" use_sse (default is disable)\n"
|
" use_sse (default is disable)\n"
|
||||||
" - this option makes Amazon's Server Site Encryption enable.\n"
|
" - use Amazon<6F>fs Server-Site Encryption or Server-Side Encryption\n"
|
||||||
|
" with Customer-Provided Encryption Keys.\n"
|
||||||
|
" this option can not be specified with use_rrs. specifying only \n"
|
||||||
|
" \"use_sse\" or \"use_sse=1\" enables Server-Side Encryption.\n"
|
||||||
|
" (use_sse=1 for old version)\n"
|
||||||
|
" specifying this option with file path which has some SSE-C\n"
|
||||||
|
" secret key enables Server-Side Encryption with Customer-Provided\n"
|
||||||
|
" Encryption Keys.(use_sse=file)\n"
|
||||||
|
" the file must be 600 permission. the file can have some lines,\n"
|
||||||
|
" each line is one SSE-C key. the first line in file is used as\n"
|
||||||
|
" Customer-Provided Encryption Keys for uploading and changing\n"
|
||||||
|
" headers etc.\n"
|
||||||
|
" if there are some keys after first line, those are used\n"
|
||||||
|
" downloading object which are encripted by not first key.\n"
|
||||||
|
" so that, you can keep all SSE-C keys in file, that is SSE-C\n"
|
||||||
|
" key history.\n"
|
||||||
|
" if AWSSSECKEYS environment is set, you can set SSE-C key instead\n"
|
||||||
|
" of this option.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" public_bucket (default=\"\" which means disabled)\n"
|
" public_bucket (default=\"\" which means disabled)\n"
|
||||||
" - anonymously mount a public bucket when set to 1\n"
|
" - anonymously mount a public bucket when set to 1\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user