add support for preflight requ (cors)
This commit is contained in:
parent
a34db6505d
commit
217f42b7c6
|
@ -54,6 +54,10 @@ public:
|
||||||
static constexpr const wchar_t * accept_language = L"Accept-Language";
|
static constexpr const wchar_t * accept_language = L"Accept-Language";
|
||||||
static constexpr const wchar_t * authorization = L"Authorization";
|
static constexpr const wchar_t * authorization = L"Authorization";
|
||||||
static constexpr const wchar_t * allow = L"Allow";
|
static constexpr const wchar_t * allow = L"Allow";
|
||||||
|
static constexpr const wchar_t * access_control_allow_methods = L"Access-Control-Allow-Methods";
|
||||||
|
static constexpr const wchar_t * access_control_allow_origin = L"Access-Control-Allow-Origin";
|
||||||
|
static constexpr const wchar_t * access_control_allow_headers = L"Access-Control-Allow-Headers";
|
||||||
|
static constexpr const wchar_t * access_control_max_age = L"Access-Control-Max-Age";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* headers' names lower case
|
* headers' names lower case
|
||||||
|
|
|
@ -1597,6 +1597,19 @@ return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Request::AddHeader(const wchar_t * name, long value)
|
||||||
|
{
|
||||||
|
if( !out_headers.has_key(name) )
|
||||||
|
{
|
||||||
|
out_headers.add(name, value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Request::AddHeader(const std::wstring & name, const std::wstring & value)
|
bool Request::AddHeader(const std::wstring & name, const std::wstring & value)
|
||||||
{
|
{
|
||||||
if( !out_headers.has_key(name) )
|
if( !out_headers.has_key(name) )
|
||||||
|
|
|
@ -513,6 +513,7 @@ public:
|
||||||
|
|
||||||
// RENAMEME to add_header_if_not_exists
|
// RENAMEME to add_header_if_not_exists
|
||||||
bool AddHeader(const wchar_t * name, const wchar_t * value);
|
bool AddHeader(const wchar_t * name, const wchar_t * value);
|
||||||
|
bool AddHeader(const wchar_t * name, long value);
|
||||||
bool AddHeader(const std::wstring & name, const std::wstring & value);
|
bool AddHeader(const std::wstring & name, const std::wstring & value);
|
||||||
bool AddHeader(const wchar_t * name, const pt::WTextStream & value);
|
bool AddHeader(const wchar_t * name, const pt::WTextStream & value);
|
||||||
bool AddHeader(const std::wstring & name, const pt::WTextStream & value);
|
bool AddHeader(const std::wstring & name, const pt::WTextStream & value);
|
||||||
|
|
|
@ -142,6 +142,61 @@ bool FunctionBase::HasAccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FunctionBase::IsCorsMethodAvailable(Request::Method method)
|
||||||
|
{
|
||||||
|
return method == Request::get || method == Request::head || method == Request::post || method == Request::put ||
|
||||||
|
method == Request::delete_ ||method == Request::patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FunctionBase::IsCorsOriginAvailable(const std::wstring & origin_url)
|
||||||
|
{
|
||||||
|
// true by default for all urles
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FunctionBase::AreCorsHeadersAvailable(const std::wstring & headers)
|
||||||
|
{
|
||||||
|
// true by default for all headers
|
||||||
|
// headers are comma separated
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* method is the value of Access-Control-Request-Method header sent by the client
|
||||||
|
*/
|
||||||
|
void FunctionBase::AddAccessControlAllowMethodsHeader(Request::Method method)
|
||||||
|
{
|
||||||
|
cur->request->AddHeader(Header::access_control_allow_methods, L"GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* origin_url is the value of Origin header sent by the client
|
||||||
|
*/
|
||||||
|
void FunctionBase::AddAccessControlAllowOriginHeader(const std::wstring & origin_url)
|
||||||
|
{
|
||||||
|
cur->request->AddHeader(Header::access_control_allow_origin, origin_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* headers is the value of Access-Control-Request-Headers header sent by the client
|
||||||
|
*/
|
||||||
|
void FunctionBase::AddAccessControlAllowHeadersHeader(const std::wstring & headers)
|
||||||
|
{
|
||||||
|
cur->request->AddHeader(Header::access_control_allow_headers, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FunctionBase::AddAccessControlMaxAgeHeader()
|
||||||
|
{
|
||||||
|
// default 24 hours
|
||||||
|
cur->request->AddHeader(Header::access_control_max_age, 86400);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FunctionBase::MakeGet()
|
void FunctionBase::MakeGet()
|
||||||
{
|
{
|
||||||
|
@ -174,12 +229,53 @@ void FunctionBase::MakeConnect()
|
||||||
// do nothing by default
|
// do nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FunctionBase::MakeOptions()
|
void FunctionBase::MakeOptions()
|
||||||
{
|
{
|
||||||
cur->request->http_status = Header::status_204_no_content;
|
cur->request->http_status = Header::status_204_no_content;
|
||||||
cur->request->out_headers.add(Header::allow, L"OPTIONS, GET, HEAD, POST, DELETE");
|
|
||||||
|
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");
|
||||||
|
pt::Space * cors_origin = cur->request->headers_in.get_space_nc(L"Origin");
|
||||||
|
|
||||||
|
if( cors_method && cors_origin && cors_method->is_wstr() && cors_origin->is_wstr() )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* this is a preflight request
|
||||||
|
* 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());
|
||||||
|
|
||||||
|
if( IsCorsMethodAvailable(method) && IsCorsOriginAvailable(*cors_origin->get_wstr()) )
|
||||||
|
{
|
||||||
|
bool cors_available = true;
|
||||||
|
|
||||||
|
if( cors_headers && cors_headers->is_wstr() )
|
||||||
|
{
|
||||||
|
cors_available = AreCorsHeadersAvailable(*cors_headers->get_wstr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cors_available )
|
||||||
|
{
|
||||||
|
AddAccessControlAllowMethodsHeader(method);
|
||||||
|
AddAccessControlAllowOriginHeader(*cors_origin->get_wstr());
|
||||||
|
AddAccessControlMaxAgeHeader();
|
||||||
|
|
||||||
|
if( cors_headers && cors_headers->is_wstr() )
|
||||||
|
{
|
||||||
|
AddAccessControlAllowHeadersHeader(*cors_headers->get_wstr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur->request->out_headers.add(Header::allow, L"GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FunctionBase::MakeTrace()
|
void FunctionBase::MakeTrace()
|
||||||
{
|
{
|
||||||
// do nothing by default
|
// do nothing by default
|
||||||
|
|
|
@ -111,6 +111,16 @@ public:
|
||||||
|
|
||||||
virtual bool HasAccess();
|
virtual bool HasAccess();
|
||||||
|
|
||||||
|
virtual bool IsCorsMethodAvailable(Request::Method method);
|
||||||
|
virtual bool IsCorsOriginAvailable(const std::wstring & origin_url);
|
||||||
|
virtual bool AreCorsHeadersAvailable(const std::wstring & headers);
|
||||||
|
|
||||||
|
virtual void AddAccessControlAllowMethodsHeader(Request::Method method);
|
||||||
|
virtual void AddAccessControlAllowOriginHeader(const std::wstring & origin_url);
|
||||||
|
virtual void AddAccessControlAllowHeadersHeader(const std::wstring & headers);
|
||||||
|
virtual void AddAccessControlMaxAgeHeader();
|
||||||
|
|
||||||
|
|
||||||
virtual void MakeGet();
|
virtual void MakeGet();
|
||||||
virtual void MakeHead();
|
virtual void MakeHead();
|
||||||
virtual void MakePost();
|
virtual void MakePost();
|
||||||
|
|
Loading…
Reference in New Issue