mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
feat(web): delete a reply's temporary file once it is sent
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,9 @@ struct HTTPReply {
|
|||||||
// When set on a 200 reply, this file is streamed from disk as the body (with contentType and headers) instead of
|
// When set on a 200 reply, this file is streamed from disk as the body (with contentType and headers) instead of
|
||||||
// message, so large downloads never sit in memory
|
// message, so large downloads never sit in memory
|
||||||
std::string file{};
|
std::string file{};
|
||||||
|
// Delete `file` once it's being sent (a temporary file made for this reply). Where an open file can't be deleted
|
||||||
|
// (Windows) it stays, so whoever makes such files should also clear out old ones.
|
||||||
|
bool removeFile{};
|
||||||
// Set by Web::Defer: the handler answers later, from another thread (DeferredReply), so nothing is sent now
|
// Set by Web::Defer: the handler answers later, from another thread (DeferredReply), so nothing is sent now
|
||||||
std::shared_ptr<DeferredState> deferred{};
|
std::shared_ptr<DeferredState> deferred{};
|
||||||
};
|
};
|
||||||
|
|||||||
11
dWeb/Web.cpp
11
dWeb/Web.cpp
@@ -266,6 +266,13 @@ namespace {
|
|||||||
return reply.message.size();
|
return reply.message.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A temporary file the reply sent: gone once mongoose has it open (on Windows, left for its maker to clear out)
|
||||||
|
void RemoveSentFile(const HTTPReply& reply) {
|
||||||
|
if (!reply.removeFile || reply.file.empty()) return;
|
||||||
|
std::error_code ec;
|
||||||
|
std::filesystem::remove(reply.file, ec);
|
||||||
|
}
|
||||||
|
|
||||||
void CountRequest(const std::string& route, uint16_t status, TrafficClock::time_point started, uint64_t bytes) {
|
void CountRequest(const std::string& route, uint16_t status, TrafficClock::time_point started, uint64_t bytes) {
|
||||||
const auto micros = std::chrono::duration_cast<std::chrono::microseconds>(TrafficClock::now() - started).count();
|
const auto micros = std::chrono::duration_cast<std::chrono::microseconds>(TrafficClock::now() - started).count();
|
||||||
TrafficStats::Local().Http(TrafficStats::Now(), route, status, static_cast<uint64_t>(std::max<int64_t>(micros, 0)), bytes);
|
TrafficStats::Local().Http(TrafficStats::Now(), route, status, static_cast<uint64_t>(std::max<int64_t>(micros, 0)), bytes);
|
||||||
@@ -505,6 +512,7 @@ void HandleHTTPMessage(mg_connection* connection, const mg_http_message* http_ms
|
|||||||
|
|
||||||
SendReply(connection, reply, http_msg);
|
SendReply(connection, reply, http_msg);
|
||||||
CountRequest(trafficRoute, static_cast<uint16_t>(reply.status), started, ReplyBytes(reply));
|
CountRequest(trafficRoute, static_cast<uint16_t>(reply.status), started, ReplyBytes(reply));
|
||||||
|
RemoveSentFile(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -780,13 +788,14 @@ void Web::SendDeferredReplies() {
|
|||||||
for (auto& finished : g_Deferred.Drain()) {
|
for (auto& finished : g_Deferred.Drain()) {
|
||||||
mg_connection* connection = mgr.conns;
|
mg_connection* connection = mgr.conns;
|
||||||
while (connection && connection->id != finished.connection) connection = connection->next;
|
while (connection && connection->id != finished.connection) connection = connection->next;
|
||||||
if (!connection || connection->is_closing) continue;
|
if (!connection || connection->is_closing) { RemoveSentFile(finished.reply); continue; }
|
||||||
// Clears is_resp once the reply is out, so mongoose reads the connection's next request again
|
// Clears is_resp once the reply is out, so mongoose reads the connection's next request again
|
||||||
SendReply(connection, finished.reply, nullptr);
|
SendReply(connection, finished.reply, nullptr);
|
||||||
if (const auto timing = g_DeferredTiming.find(finished.connection); timing != g_DeferredTiming.end()) {
|
if (const auto timing = g_DeferredTiming.find(finished.connection); timing != g_DeferredTiming.end()) {
|
||||||
CountRequest(timing->second.route, static_cast<uint16_t>(finished.reply.status), timing->second.started, ReplyBytes(finished.reply));
|
CountRequest(timing->second.route, static_cast<uint16_t>(finished.reply.status), timing->second.started, ReplyBytes(finished.reply));
|
||||||
g_DeferredTiming.erase(timing);
|
g_DeferredTiming.erase(timing);
|
||||||
}
|
}
|
||||||
|
RemoveSentFile(finished.reply);
|
||||||
if (finished.close) connection->is_draining = 1;
|
if (finished.close) connection->is_draining = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user