Compare case-insensitively instead of copying (#2593)

Also remove some code duplication.
This commit is contained in:
Andrew Gaul 2024-11-06 00:05:05 +09:00 committed by GitHub
parent d9ccdc4fce
commit a101b88114
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 40 deletions

View File

@ -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"
}
}

View File

@ -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());

View File

@ -24,6 +24,7 @@
#include <cstring>
#include <ctime>
#include <string>
#include <strings.h>
//
// 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 : ""; }