182 lines
3.8 KiB
C++
182 lines
3.8 KiB
C++
#include "CORSConfig.h"
|
|
#include <map>
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include "Global.h"
|
|
|
|
CORSConfig GlobalCORSConfig;
|
|
|
|
CORSConfig::CORSConfig()
|
|
{
|
|
max_age = 86400;
|
|
allow_cookie = false;
|
|
validate_urls = {};
|
|
validate_hosts = {};
|
|
validate_methods = { "GET", "POST", "OPTIONS" };
|
|
validate_headers =
|
|
{
|
|
"Accept",
|
|
"Accept-Language",
|
|
"Content-Language",
|
|
"Content-Type",
|
|
"Authorization",
|
|
"X-Requested-With",
|
|
"X-CSRF-Token",
|
|
"X-Client-Version",
|
|
"X-App-Id",
|
|
"X-Request-ID"
|
|
};
|
|
}
|
|
|
|
int CORSConfig::GetMaxAge() const
|
|
{
|
|
return max_age;
|
|
}
|
|
|
|
bool CORSConfig::AllowCookie() const
|
|
{
|
|
return allow_cookie;
|
|
}
|
|
|
|
std::string CORSConfig::GetValidateMethods() const
|
|
{
|
|
if (validate_methods.empty())
|
|
return std::string();
|
|
std::ostringstream oss;
|
|
size_t index = 0;
|
|
for (const auto& method : validate_methods)
|
|
{
|
|
if (index++ > 0)
|
|
oss << ", ";
|
|
oss << uns::tools::ToUpper(method); // 统一大写方法名
|
|
}
|
|
return oss.str();
|
|
}
|
|
|
|
bool CORSConfig::UrlValidate(const std::string& url) const
|
|
{
|
|
return (validate_urls.find(url) != validate_urls.end());
|
|
}
|
|
|
|
bool CORSConfig::HostValidate(const std::string& host) const
|
|
{
|
|
return (validate_hosts.find(host) != validate_hosts.end());
|
|
}
|
|
|
|
bool CORSConfig::IsMethodAllowed(const std::string method) const
|
|
{
|
|
return (validate_methods.find(method) != validate_methods.end());
|
|
}
|
|
|
|
std::string CORSConfig::GetValidateHeaders(const std::set<std::string>& headers) const
|
|
{
|
|
// build map from lowercase(validate_headers) => original form (preserve casing)
|
|
std::map<std::string, std::string> lowerToOriginal;
|
|
for (const auto& h : validate_headers)
|
|
lowerToOriginal[uns::tools::ToLower(h)] = h;
|
|
std::vector<std::string> allowedOut;
|
|
if (headers.empty())
|
|
{
|
|
// 返回服务端全部允许的头(保持 validate_headers 中的原始展示形式)
|
|
for (const auto& kv : lowerToOriginal)
|
|
allowedOut.push_back(kv.second);
|
|
}
|
|
else
|
|
{
|
|
// 交集比较(headers 已经是小写的—为了健壮性,再转换一次)
|
|
for (const auto& reqLower : headers)
|
|
{
|
|
std::string reqNorm = uns::tools::ToLower(reqLower);
|
|
auto it = lowerToOriginal.find(reqNorm);
|
|
if (it != lowerToOriginal.end())
|
|
allowedOut.push_back(it->second); // 使用原始展示形式
|
|
}
|
|
// 如果客户端请求了头(headers 非空)但交集为空,返回空字符串
|
|
}
|
|
if (allowedOut.empty())
|
|
return std::string();
|
|
// join with ", "
|
|
std::ostringstream oss;
|
|
for (size_t i = 0; i < allowedOut.size(); ++i)
|
|
{
|
|
if (i)
|
|
oss << ", ";
|
|
oss << allowedOut[i];
|
|
}
|
|
return oss.str();
|
|
}
|
|
|
|
void CORSConfig::SetMaxAge(int max_age)
|
|
{
|
|
this->max_age = max_age;
|
|
}
|
|
|
|
void CORSConfig::SetAllowCookie(bool allow)
|
|
{
|
|
allow_cookie = allow;
|
|
}
|
|
|
|
void CORSConfig::ClearValidateUrls()
|
|
{
|
|
validate_urls.clear();
|
|
}
|
|
|
|
void CORSConfig::ClearValidateHosts()
|
|
{
|
|
validate_hosts.clear();
|
|
}
|
|
|
|
void CORSConfig::ClearValidateMethods()
|
|
{
|
|
validate_methods.clear();
|
|
}
|
|
|
|
void CORSConfig::ClearValidateHeaders()
|
|
{
|
|
validate_headers.clear();
|
|
}
|
|
|
|
void CORSConfig::AddValidateUrl(const std::string& url)
|
|
{
|
|
validate_urls.insert(url);
|
|
}
|
|
|
|
void CORSConfig::AddValidateHost(const std::string& host)
|
|
{
|
|
validate_hosts.insert(host);
|
|
}
|
|
|
|
void CORSConfig::AddValidateMethod(const std::string& method)
|
|
{
|
|
validate_methods.insert(uns::tools::ToUpper(method));
|
|
}
|
|
|
|
void CORSConfig::AddValidateHeader(const std::string& header)
|
|
{
|
|
validate_headers.insert(header);
|
|
}
|
|
|
|
void CORSConfig::AddValidateUrls(const std::set<std::string>& urls)
|
|
{
|
|
for(const auto& url : urls)
|
|
validate_urls.insert(url);
|
|
}
|
|
|
|
void CORSConfig::AddValidateHosts(const std::set<std::string>& hosts)
|
|
{
|
|
for(const auto& host : hosts)
|
|
validate_hosts.insert(host);
|
|
}
|
|
|
|
void CORSConfig::AddValidateMethods(const std::set<std::string>& methods)
|
|
{
|
|
for(const auto& method : methods)
|
|
validate_methods.insert(method);
|
|
}
|
|
|
|
void CORSConfig::AddValidateHeaders(const std::set<std::string>& headers)
|
|
{
|
|
for(const auto& header : headers)
|
|
validate_headers.insert(header);
|
|
}
|