120 lines
2.9 KiB
C++
120 lines
2.9 KiB
C++
#include "common/Cors.h"
|
|
|
|
#include <drogon/drogon.h>
|
|
|
|
namespace visione::cors
|
|
{
|
|
namespace
|
|
{
|
|
std::vector<std::string> allowedOrigins()
|
|
{
|
|
auto cfg = drogon::app().getCustomConfig();
|
|
std::vector<std::string> origins;
|
|
|
|
if (cfg.isMember("cors") && cfg["cors"].isObject())
|
|
{
|
|
auto &c = cfg["cors"];
|
|
if (c.isMember("allowed_origin"))
|
|
{
|
|
auto &v = c["allowed_origin"];
|
|
if (v.isArray())
|
|
{
|
|
for (const auto &el : v)
|
|
{
|
|
if (el.isString())
|
|
origins.emplace_back(el.asString());
|
|
}
|
|
}
|
|
else if (v.isString())
|
|
{
|
|
origins.emplace_back(v.asString());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (origins.empty())
|
|
origins.emplace_back("http://localhost:5173");
|
|
|
|
return origins;
|
|
}
|
|
|
|
bool isAllowed(const drogon::HttpRequestPtr &request)
|
|
{
|
|
auto origin = request->getHeader("Origin");
|
|
if (origin.empty())
|
|
return false;
|
|
|
|
auto origins = allowedOrigins();
|
|
for (const auto &o : origins)
|
|
{
|
|
if (o == "*" || o == origin)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void addHeaders(const drogon::HttpRequestPtr &request,
|
|
const drogon::HttpResponsePtr &response)
|
|
{
|
|
auto origin = request->getHeader("Origin");
|
|
if (origin.empty())
|
|
return;
|
|
|
|
auto origins = allowedOrigins();
|
|
bool allowAll = false;
|
|
bool matched = false;
|
|
for (const auto &o : origins)
|
|
{
|
|
if (o == "*")
|
|
{
|
|
allowAll = true;
|
|
break;
|
|
}
|
|
if (o == origin)
|
|
{
|
|
matched = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!allowAll && !matched)
|
|
return;
|
|
|
|
if (allowAll)
|
|
response->addHeader("Access-Control-Allow-Origin", "*");
|
|
else
|
|
response->addHeader("Access-Control-Allow-Origin", origin);
|
|
|
|
response->addHeader("Access-Control-Allow-Credentials", "true");
|
|
response->addHeader("Access-Control-Allow-Methods",
|
|
"GET,POST,PATCH,DELETE,OPTIONS");
|
|
response->addHeader("Access-Control-Allow-Headers",
|
|
"Authorization,Content-Type");
|
|
response->addHeader("Vary", "Origin");
|
|
}
|
|
} // namespace
|
|
|
|
void configure()
|
|
{
|
|
drogon::app().registerSyncAdvice(
|
|
[](const drogon::HttpRequestPtr &request) -> drogon::HttpResponsePtr {
|
|
if (request->method() != drogon::Options)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
auto response = drogon::HttpResponse::newHttpResponse();
|
|
response->setStatusCode(drogon::k204NoContent);
|
|
addHeaders(request, response);
|
|
return response;
|
|
});
|
|
|
|
drogon::app().registerPostHandlingAdvice(
|
|
[](const drogon::HttpRequestPtr &request,
|
|
const drogon::HttpResponsePtr &response) {
|
|
addHeaders(request, response);
|
|
});
|
|
}
|
|
} // namespace visione::cors
|
|
|