diff --git a/src/cache.cpp b/src/cache.cpp index 6042608..e4a140b 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -346,18 +346,14 @@ bool StatCache::AddStat(const std::string& key, const headers_t& meta, bool forc SetStatCacheTime(ent.cache_date); // Set time. //copy only some keys for(auto iter = meta.cbegin(); iter != meta.cend(); ++iter){ - std::string tag = lower(iter->first); + auto tag = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; - if(tag == "content-type"){ + if(tag == "content-type" || + tag == "content-length" || + tag == "etag" || + tag == "last-modified" || + tag.is_prefix("x-amz")){ ent.meta[iter->first] = value; - }else if(tag == "content-length"){ - ent.meta[iter->first] = value; - }else if(tag == "etag"){ - ent.meta[iter->first] = value; - }else if(tag == "last-modified"){ - ent.meta[iter->first] = value; - }else if(is_prefix(tag.c_str(), "x-amz")){ - ent.meta[tag] = value; // key is lower case for "x-amz" } } @@ -403,18 +399,14 @@ bool StatCache::UpdateMetaStats(const std::string& key, const headers_t& meta) // update only meta keys for(auto metaiter = meta.cbegin(); metaiter != meta.cend(); ++metaiter){ - std::string tag = lower(metaiter->first); + auto tag = CaseInsensitiveStringView(metaiter->first); const auto& value = metaiter->second; - if(tag == "content-type"){ + if(tag == "content-type" || + tag == "content-length" || + tag == "etag" || + tag == "last-modified" || + tag.is_prefix("x-amz")){ ent->meta[metaiter->first] = value; - }else if(tag == "content-length"){ - ent->meta[metaiter->first] = value; - }else if(tag == "etag"){ - ent->meta[metaiter->first] = value; - }else if(tag == "last-modified"){ - ent->meta[metaiter->first] = value; - }else if(is_prefix(tag.c_str(), "x-amz")){ - ent->meta[tag] = value; // key is lower case for "x-amz" } } diff --git a/src/curl.cpp b/src/curl.cpp index 230f2c6..ac02857 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -3416,18 +3416,14 @@ int S3fsCurl::HeadRequest(const char* tpath, headers_t& meta) // fixme: clean this up. meta.clear(); for(auto iter = responseHeaders.cbegin(); iter != responseHeaders.cend(); ++iter){ - std::string key = lower(iter->first); + auto key = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; - if(key == "content-type"){ + if(key == "content-type" || + key == "content-length" || + key == "etag" || + key == "last-modified" || + key.is_prefix("x-amz")){ meta[iter->first] = value; - }else if(key == "content-length"){ - meta[iter->first] = value; - }else if(key == "etag"){ - meta[iter->first] = value; - }else if(key == "last-modified"){ - meta[iter->first] = value; - }else if(is_prefix(key.c_str(), "x-amz")){ - meta[key] = value; // key is lower case for "x-amz" } } return 0; @@ -3458,11 +3454,11 @@ int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool is_copy) // Make request headers for(auto iter = meta.cbegin(); iter != meta.cend(); ++iter){ - std::string key = lower(iter->first); + auto key = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; - if(is_prefix(key.c_str(), "x-amz-acl")){ + if(key.is_prefix("x-amz-acl")){ // not set value, but after set it. - }else if(is_prefix(key.c_str(), "x-amz-meta")){ + }else if(key.is_prefix("x-amz-meta")){ requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str()); }else if(key == "x-amz-copy-source"){ requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str()); @@ -3595,11 +3591,11 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd) requestHeaders = curl_slist_sort_insert(requestHeaders, "Content-Type", contype.c_str()); for(auto iter = meta.cbegin(); iter != meta.cend(); ++iter){ - std::string key = lower(iter->first); + auto key = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; - if(is_prefix(key.c_str(), "x-amz-acl")){ + if(key.is_prefix("x-amz-acl")){ // not set value, but after set it. - }else if(is_prefix(key.c_str(), "x-amz-meta")){ + }else if(key.is_prefix("x-amz-meta")){ requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str()); }else if(key == "x-amz-server-side-encryption" && value != "aws:kms"){ // skip this header, because this header is specified after logic. @@ -3920,11 +3916,11 @@ int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, std::s std::string contype = S3fsCurl::LookupMimeType(tpath); for(auto iter = meta.cbegin(); iter != meta.cend(); ++iter){ - std::string key = lower(iter->first); + auto key = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; - if(is_prefix(key.c_str(), "x-amz-acl")){ + if(key.is_prefix("x-amz-acl")){ // not set value, but after set it. - }else if(is_prefix(key.c_str(), "x-amz-meta")){ + }else if(key.is_prefix("x-amz-meta")){ requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str()); }else if(key == "x-amz-server-side-encryption" && value != "aws:kms"){ // skip this header, because this header is specified after logic. @@ -4326,7 +4322,7 @@ int S3fsCurl::CopyMultipartPostSetup(const char* from, const char* to, int part_ // Make request headers for(auto iter = meta.cbegin(); iter != meta.cend(); ++iter){ - std::string key = lower(iter->first); + auto key = CaseInsensitiveStringView(iter->first); const auto& value = iter->second; if(key == "x-amz-copy-source"){ requestHeaders = curl_slist_sort_insert(requestHeaders, iter->first.c_str(), value.c_str()); diff --git a/src/string_util.h b/src/string_util.h index 0b6b9ca..dc3a41c 100644 --- a/src/string_util.h +++ b/src/string_util.h @@ -24,6 +24,7 @@ #include #include #include +#include // // A collection of string utilities for manipulating URLs and HTTP responses. @@ -36,6 +37,14 @@ static constexpr char SPACES[] = " \t\r\n"; //------------------------------------------------------------------- // Inline functions //------------------------------------------------------------------- +class CaseInsensitiveStringView { +public: + explicit CaseInsensitiveStringView(const std::string &str) : str(str.c_str()) {} + bool operator==(const char *other) const { return strcasecmp(str, other) == 0; } + bool is_prefix(const char *prefix) const { return strncasecmp(str, prefix, strlen(prefix)) == 0; } +private: + const char *str; +}; static inline bool is_prefix(const char *str, const char *prefix) { return strncmp(str, prefix, strlen(prefix)) == 0; } static inline const char* SAFESTRPTR(const char *strptr) { return strptr ? strptr : ""; }