Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
Some checks failed
Build and Deploy on Tag / build-arch (push) Failing after 8s
Build and Deploy on Tag / update-tap (push) Failing after 4s

This commit is contained in:
2026-04-23 02:23:22 -05:00
parent 3807bc5f36
commit 4cdfbc9542
12 changed files with 392 additions and 85 deletions

View File

@@ -27,6 +27,79 @@ using namespace Tesses::Framework::TextStreams;
namespace Tesses::Framework::Http
{
void ServerSentEvents::SendEventRaw(const std::string& evt)
{
this->mtx.Lock();
for(auto& item : this->strms)
{
try {
StreamWriter writer(item);
writer.newline = "\r\n";
writer.WriteLine(evt);
}catch(...) {
}
}
this->mtx.Unlock();
}
void ServerSentEvents::SendId(const std::string& id)
{
SendCustomEvent("id",id);
}
void ServerSentEvents::SendData(const std::string& message)
{
SendCustomEvent("data", message);
}
void ServerSentEvents::SendComment(const std::string& comment)
{
SendCustomEvent("", comment);
}
void ServerSentEvents::SendCustomEvent(const std::string& etype, const std::string& message)
{
std::string text = etype + ": ";
for(auto item : message)
{
if(item == '\r') continue;
if(item == '\n') {
text += "\r\n" + etype + ": ";
}
else text += item;
}
SendEventRaw(text);
}
void ServerSentEvents::SendData(const std::string& message, const std::string& mtype)
{
std::string text = "event: " + mtype + "\r\ndata: ";
for(auto item : message)
{
if(item == '\r') continue;
if(item == '\n') {
text += "\r\ndata: ";
}
else text += item;
}
SendEventRaw(text);
}
void ServerSentEvents::SendRetry(uint32_t ms)
{
SendCustomEvent("retry", std::to_string(ms));
}
void ServerSentEvents::SendRetry(std::chrono::milliseconds ms)
{
SendCustomEvent("retry", std::to_string(ms.count()));
}
void ServerSentEvents::SendRetry(Tesses::Framework::Date::TimeSpan ts)
{
SendRetry((uint32_t)ts.TotalSeconds() * 1000);
}
class WSServer
{
public:
@@ -282,6 +355,7 @@ namespace Tesses::Framework::Http
this->conn->OnClose(false);
}
};
/*
static int _header_field(multipart_parser* p, const char *at, size_t length)
{
@@ -344,6 +418,7 @@ namespace Tesses::Framework::Http
data->currentHeaders.Clear();
return 0;
}*/
std::string ServerContext::GetUrlWithQuery()
{
if(this->queryParams.kvp.empty()) return this->path;
@@ -364,6 +439,34 @@ namespace Tesses::Framework::Http
}
}
void ServerContext::SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse)
{
this->responseHeaders.SetValue("X-Accel-Buffering","no");
this->responseHeaders.SetValue("Content-Type","text/event-stream");
this->responseHeaders.SetValue("Cache-Control","no-cache");
auto strm = this->OpenResponseStream();
if(strm == nullptr || this->method == "HEAD") return;
sse->mtx.Lock();
sse->strms.push_back(strm);
sse->mtx.Unlock();
while(!this->strm->EndOfStream())
{
TF_Sleep(10);
}
sse->mtx.Lock();
for(auto index = sse->strms.begin(); index != sse->strms.end(); index++)
{
if(*index == strm)
{
sse->strms.erase(index);
break;
}
}
sse->mtx.Unlock();
}
std::string ServerContext::ReadString()
{
if(strm == nullptr) return {};