change how origin header is treated

Now check whether the origin is in allowed_origins table,
and if not check allow_all_origins config parameter.

While here:
- add are_cors_preflight_requests_available - if true then preflight
  requests are available (default false)
This commit is contained in:
2022-09-09 01:01:39 +02:00
parent 05ecac8426
commit 6138497fe0
4 changed files with 76 additions and 51 deletions

View File

@@ -158,20 +158,23 @@ bool FunctionBase::IsCorsMethodAvailable(Request::Method method)
}
bool FunctionBase::IsCorsOriginAvailable(const std::wstring & origin_url)
bool FunctionBase::IsOriginAvailable(const std::wstring & origin_url)
{
if( config )
{
if( config->allow_all_cors_origins )
{
return true;
}
else
if( !config->allowed_origins.empty() )
{
// origin_url can be a "null" string
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
// but in such a case the "null" should be put to the config as well
return is_in_list(origin_url, config->allowed_cors_origins);
return is_in_list(origin_url, config->allowed_origins);
}
else
{
if( config->allow_all_origins )
{
return true;
}
}
}
@@ -212,15 +215,18 @@ void FunctionBase::AddAccessControlAllowOriginHeader(const std::wstring & origin
{
if( config )
{
if( config->allow_all_cors_origins )
if( !config->allowed_origins.empty() )
{
cur->request->AddHeader(Header::access_control_allow_origin, L"*");
// method IsOriginAvailable(..) was called beforehand so now we assume
// that the origin_url is permitted (and is valid as a header)
cur->request->AddHeader(Header::access_control_allow_origin, origin_url);
}
else
{
// method IsCorsOriginAvailable(..) was called beforehand so now we assume
// that the origin_url is permitted
cur->request->AddHeader(Header::access_control_allow_origin, origin_url);
if( config->allow_all_origins )
{
cur->request->AddHeader(Header::access_control_allow_origin, L"*");
}
}
}
}
@@ -307,12 +313,47 @@ void FunctionBase::AddCorsNormalRequestHeaders(const std::wstring & origin)
}
void FunctionBase::CheckCorsPreflightRequest(const std::wstring & origin, const std::wstring & method_string)
{
pt::Space * cors_headers = cur->request->headers_in.get_space_nc(L"Access_Control_Request_Headers");
Request::Method method = Request::CheckRequestMethod(method_string.c_str());
if( IsCorsMethodAvailable(method) )
{
bool cors_headers_available = true;
std::wstring * headers = nullptr;
if( cors_headers && cors_headers->is_wstr() )
{
headers = cors_headers->get_wstr();
cors_headers_available = AreCorsHeadersAvailable(*headers);
}
if( cors_headers_available )
{
AddCorsPreflightRequestHeaders(origin, method, headers);
}
else
{
if( headers )
{
log << log2 << "FunctionBase: these cors headers: " << *headers << " are not permitted in cors requests" << logend;
}
}
}
else
{
log << log2 << "FunctionBase: this method: " << method_string << " is not permitted in cors requests" << logend;
}
}
void FunctionBase::AddResponseHeadersForOrigin(const std::wstring & origin)
{
if( cur->request->method == Request::Method::options )
{
pt::Space * cors_method = cur->request->headers_in.get_space_nc(L"Access_Control_Request_Method"); // FastCGI changes '-' to '_'
pt::Space * cors_headers = cur->request->headers_in.get_space_nc(L"Access_Control_Request_Headers");
cur->request->http_status = Header::status_204_no_content;
if( cors_method && cors_method->is_wstr() )
{
@@ -321,35 +362,14 @@ void FunctionBase::AddResponseHeadersForOrigin(const std::wstring & origin)
* https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
* (we allow Access-Control-Request-Headers not to be present)
*/
Request::Method method = Request::CheckRequestMethod(cors_method->get_wstr()->c_str());
cur->request->http_status = Header::status_204_no_content;
if( IsCorsMethodAvailable(method) )
if( config->are_cors_preflight_requests_available )
{
bool cors_headers_available = true;
std::wstring * headers = nullptr;
if( cors_headers && cors_headers->is_wstr() )
{
headers = cors_headers->get_wstr();
cors_headers_available = AreCorsHeadersAvailable(*headers);
}
if( cors_headers_available )
{
AddCorsPreflightRequestHeaders(origin, method, headers);
}
else
{
if( headers )
{
log << log2 << "FunctionBase: these cors headers: " << *headers << " are not permitted in cors requests" << logend;
}
}
CheckCorsPreflightRequest(origin, *cors_method->get_wstr());
}
else
{
log << log2 << "FunctionBase: this method: " << *cors_method->get_wstr() << " is not permitted in cors requests" << logend;
log << log2 << "FunctionBase: cors requests are disabled" << logend;
}
}
else
@@ -374,7 +394,7 @@ void FunctionBase::CheckOriginHeader()
if( origin && origin->is_wstr() )
{
if( IsCorsOriginAvailable(*origin->get_wstr()) )
if( IsOriginAvailable(*origin->get_wstr()) )
{
AddResponseHeadersForOrigin(*origin->get_wstr());
}