-
-
Notifications
You must be signed in to change notification settings - Fork 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
Unable to refresh custom 404 page #1979
Comments
I think we don't need to pursue extreme performance in these cases. An atomic shared pointer is enough. @an-tao drogon/lib/src/HttpAppFrameworkImpl.cc Lines 975 to 1000 in 4cbac30
|
You could use The custom handler will be invoked every time, no internal caching. PS: To make it into use, do not call |
Performance-wise will newFileResponse calls in the custom error handler be cached? Say the custom error handler is set to always return HttpResponse::newFileResponse(drogon::app().getDocumentRoot() + "/index.html"); And we have 10000 active requests every second to |
You could use the setExpiredTime mehtod of HttpResponse to achieve that. |
Thank you @an-tao and @hwc0919, using a combination of I don't know whether this issue can be closed, it needs proper documentation to let users know |
This does not seem to be the way to do this: static void postConfigure()
{
/// vue.js integration (SPA)
auto resp = HttpResponse::newFileResponse(
drogon::app().getDocumentRoot() + "/index.html",
"",
drogon::CT_TEXT_HTML,
"text/html"
);
resp->setExpiredTime(drogon::app().staticFilesCacheTime());
drogon::app()
.setCustomErrorHandler(
[
resp = std::move(resp)
](HttpStatusCode, const HttpRequestPtr&)
{
return resp;
}
);
}
int main()
{
drogon::app()
.loadConfigFile("./config.json");
postConfigure();
drogon::app()
.run();
} The response will always be the old cached index.html page. Will it be cached if the auto resp = HttpResponse::newFileResponse(... is moved into the custom error handler? I can't find any cache map lookup mechanism for file responses in the framework to safely do this without worrying about it hitting the OS file lookups every time |
You should move the newFileResponse code to the handler and cache the old response by yourself. |
I found The only way without reimplementing the static file router would be to create individual pages with HttpSimpleControllers and have each one call Seems we have to use an atomic |
For other SPA developers, this is the snippet that may be of help to you static std::atomic<HttpResponsePtr> indexHtml;
static void updateIndexHtml()
{
::indexHtml = HttpResponse::newFileResponse(
drogon::app().getDocumentRoot() + "/index.html",
"",
drogon::CT_TEXT_HTML,
"text/html"
);
}
static void postConfigure()
{
/// vue.js integration (SPA)
updateIndexHtml();
drogon::app()
.setCustomErrorHandler(
[](HttpStatusCode, const HttpRequestPtr&)
{
return ::indexHtml.load();
}
)
/// WebSocket notification of frontend change
.registerHandler(
"/api/_/dist", // <- can be anything you like
[](const HttpRequestPtr &req,
std::function<void (const HttpResponsePtr&)>&& callback)
{
if(!req->peerAddr().isLoopbackIp())
{
callback(HttpResponse::newNotFoundResponse(std::move(req)));
return;
}
updateIndexHtml();
callback(HttpResponse::newHttpResponse(drogon::k200OK, drogon::CT_NONE));
// TODO: Notify the frontend clients to refresh their pages
}
)
;
}
int main()
{
drogon::app()
.loadConfigFile("./config.json")
;
postConfigure();
drogon::app()
.run()
;
} You will need some client code somewhere to trigger the curl -d '' http://localhost:8080/api/_/dist If you need to trigger it remotely, you can remove the check if(!req->peerAddr().isLoopbackIp())
{
callback(HttpResponse::newNotFoundResponse(std::move(req)));
return;
} However, beware of the security risk of removing that check, as anybody could hit that API endpoint and consume your server's resources from constant reloading of the index.html file |
You can use an timer to check the md5 change or edit time of the file. |
Thank you for the suggestion, in my use case there is a custom CI/CD app made with Drogon that gets triggered by GitHub webhooks, which performs a So performance-wise this atomic variable is enough for this application. If other developers needed automatic refresh, they have to go the MD5 route |
Describe the bug
In a real-time system, the 404 page may get updated, and since the custom 404 page is cached in Drogon, we have to call
drogon::app().setCustom404Page
to refresh its content, however, this doesn't happen.For SPAs this is a significant issue, as the only way to refresh its content is through restarting the server.
To Reproduce
Steps to reproduce the behavior:
drogon::app().setCustom404Page
and point it to the 404 filedrogon::app().setCustom404Page
and returns 200 OKExpected behavior
Either the 404 shouldn't be cached, or we should be allowed to refresh it.
Desktop (please complete the following information):
The text was updated successfully, but these errors were encountered: