-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When using a coroutine controller, the response header modified by the middleware has no effect #2173
Comments
Would you like to paste your code here? |
Task<HttpResponsePtr> CORSMiddleware::invoke(const HttpRequestPtr &req, MiddlewareNextAwaiter &&next)
{
const std::string& origin = req->getHeader("Origin");
// 检查是否允许所有来源 (通配符 *)
bool allowAllOrigins = (allowedOrigins_.find("*") != allowedOrigins_.end());
spdlog::info("被调用!!!");
// 处理 OPTIONS 预检请求
if (req->method() == Options)
{
spdlog::info("CORSMiddleware invoked by {} 跨域中间件被调用", origin);
// 检查 Origin 是否被允许
if (!allowAllOrigins && allowedOrigins_.find(origin) == allowedOrigins_.end())
{
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k403Forbidden);
resp->setBody("403 Forbidden - Origin not allowed 非法跨域请求");
mcb(resp); // 返回响应,终止进一步处理
spdlog::warn("Origin {} not allowed, 403 Forbidden 非法跨域请求", origin);
return;
}
// 返回预检请求响应
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k200OK);
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
resp->addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
resp->addHeader("Access-Control-Allow-Credentials", "true");
mcb(resp); // 返回响应,终止进一步处理
return;
} or Coroutine version Task<HttpResponsePtr> CORSMiddleware::invoke(const HttpRequestPtr &req, MiddlewareNextAwaiter &&next)
{
const std::string& origin = req->getHeader("Origin");
// 检查是否允许所有来源 (通配符 *)
bool allowAllOrigins = (allowedOrigins_.find("*") != allowedOrigins_.end());
spdlog::info("被调用!!!");
// 处理 OPTIONS 预检请求
if (req->method() == Options)
{
spdlog::info("CORSMiddleware invoked by {} 跨域中间件被调用", origin);
// 检查 Origin 是否被允许
if (!allowAllOrigins && allowedOrigins_.find(origin) == allowedOrigins_.end())
{
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k403Forbidden);
resp->setBody("403 Forbidden - Origin not allowed 非法跨域请求");
spdlog::warn("Origin {} not allowed, 403 Forbidden 非法跨域请求", origin);
co_return resp; // 返回响应,终止进一步处理
}
// 返回预检请求响应
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k200OK);
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
resp->addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
resp->addHeader("Access-Control-Allow-Credentials", "true");
co_return resp; // 返回响应,终止进一步处理
}
// 继续处理普通请求,等待下一个中间件或控制器
auto resp = co_await next; // 继续请求处理
spdlog::info("普通请求");
// 在响应中添加 CORS 头
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Credentials", "true");
co_return resp; // 返回最终的响应
} header file is like class CORSMiddleware : public drogon::HttpCoroMiddleware<CORSMiddleware>
{
public:
static constexpr bool isAutoCreation = false; // 明确设置为 false
CORSMiddleware(const std::unordered_set<std::string>& allowedOrigins);
Task<HttpResponsePtr> invoke(const HttpRequestPtr &req,
MiddlewareNextAwaiter &&next) override;
private:
std::unordered_set<std::string> allowedOrigins_;
}; and I try to register it this way auto corsMiddleware = std::make_shared<YLineServer::CORSMiddleware>(config.allowed_origins);
drogon::app().registerMiddleware(corsMiddleware);
// 将协程中间件注册为 Pre-Routing Advice
// 注册 Pre-Routing Advice
drogon::app().registerPreRoutingAdvice([corsMiddleware](const HttpRequestPtr &req, AdviceCallback &&callback, AdviceChainCallback &&chainCallback) {
// 调用中间件的 invoke 方法
corsMiddleware->invoke(req,
// nextCb:继续执行下一个中间件或控制器的回调
[chainCallback = std::move(chainCallback)](const std::function<void(const HttpResponsePtr &)>& nextResponseCb) {
// 执行下一个 Pre-Routing Advice 或进入路由处理
chainCallback();
},
// mcb:终止请求并返回响应的回调
[callback = std::move(callback)](const HttpResponsePtr &resp) {
// 返回响应
callback(resp);
}
); |
When I use HttpCoroMiddleware, the middleware cannot be used. I don't know the correct way to manually register it (via registerPreRoutingAdvice). Even if register it through the ADD_PATH_TO macro, it can't work correctly. When I use HttpMiddleware, the Option request can be completed normally, but subsequent POST and other requests still cannot add the correct "Access-Control-Allow" request header information. |
Middleware in drogon is not global, after registering your middleware to framework, did you add the name of middleware to your routing path in controllers? |
yes, I tried both ‘registerPreRoutingAdvice’ and ADD_PATH_TO |
|
According to my test, option request is not automatically handled by the framework, I have to add middleware to handle it.
drogon::app().registerPreRoutingAdvice to add the route of it as a global middleware nextCb([origin, mcb = std::move(mcb), allowAllOrigins](const HttpResponsePtr& resp) mutable {
spdlog::info("normal request");
// Add CORS header to the response
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Credentials", "true");
mcb(resp); // Return the final response
});
Task<HttpResponsePtr> CORSMiddleware::invoke(const HttpRequestPtr &req, MiddlewareNextAwaiter &&next)
{
const std::string& origin = req->getHeader("Origin");
// Check if all origins are allowed (wildcard *)
bool allowAllOrigins = (allowedOrigins_.find("*") != allowedOrigins_.end());
spdlog::info("Called!!!");
// Handle OPTIONS pre-check request
if (req->method() == Options)
{
spdlog::info("CORSMiddleware invoked by {} Cross-origin middleware is called", origin);
// Check if Origin is allowed
if (!allowAllOrigins && allowedOrigins_.find(origin) == allowedOrigins_.end())
{
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k403Forbidden);
resp->setBody("403 Forbidden - Origin not allowed Illegal cross-domain request");
spdlog::warn("Origin {} not allowed, 403 Forbidden Illegal cross-domain request", origin);
co_return resp; // Return response and terminate further processing
}
// Return pre-check request response
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k200OK);
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
resp->addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
resp->addHeader("Access-Control-Allow-Credentials", "true");
co_return resp; // Return response and terminate further processing
}
// Continue processing normal requests and wait for the next middleware or controller
auto resp = co_await next; // Continue request processing
spdlog::info("Normal request");
// Add CORS header to the response
if (allowAllOrigins)
{
resp->addHeader("Access-Control-Allow-Origin", "*");
}
else
{
resp->addHeader("Access-Control-Allow-Origin", origin);
}
resp->addHeader("Access-Control-Allow-Credentials", "true");
co_return resp; // Return the final response
} But this time I don't know how to use drogon::app().registerPreRoutingAdvice to add the route of this coroutine middleware, so I manually added it in the ADD_PATH_TO macro of the controller, but this time even the Option request was not handled correctly |
|
I'm trying to use a CROS middleware with my coroutine controller, but no matter what I try, the options request goes through fine, but subsequent requests still lack the Access-Control-Allow request header. I've tried using both HttpCoroMiddleware and HttpMiddleware
The text was updated successfully, but these errors were encountered: