mirror of
https://onedev.site.tesses.net/tesses-framework
synced 2026-02-08 15:55:46 +00:00
Add changeable server
This commit is contained in:
@@ -15,6 +15,7 @@ src/Http/HttpClient.cpp
|
|||||||
src/Http/HttpStream.cpp
|
src/Http/HttpStream.cpp
|
||||||
src/Http/ContentDisposition.cpp
|
src/Http/ContentDisposition.cpp
|
||||||
src/Http/WebSocket.cpp
|
src/Http/WebSocket.cpp
|
||||||
|
src/Http/ChangeableServer.cpp
|
||||||
src/Mail/Smtp.cpp
|
src/Mail/Smtp.cpp
|
||||||
src/Serialization/Json.cpp
|
src/Serialization/Json.cpp
|
||||||
src/Serialization/SQLite.cpp
|
src/Serialization/SQLite.cpp
|
||||||
|
|||||||
@@ -32,6 +32,22 @@ class MyWebServer : public IHttpServer {
|
|||||||
.SendStream(fs);
|
.SendStream(fs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(ctx.path == "/mypath.html")
|
||||||
|
{
|
||||||
|
std::string txt = "<h1>Root: " + HttpUtils::HtmlEncode(ctx.GetServerRoot()) + "</h1>";
|
||||||
|
ctx.WithMimeType("text/html").SendText(txt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(ctx.path == "/getabsolute.html")
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
if(ctx.queryParams.TryGetFirst("path",path))
|
||||||
|
{
|
||||||
|
std::string txt = "<h1>Path: " + HttpUtils::HtmlEncode(ctx.MakeAbsolute(path)) + "</h1>";
|
||||||
|
ctx.WithMimeType("text/html").SendText(txt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(ctx.path == "/streaming.html")
|
else if(ctx.path == "/streaming.html")
|
||||||
{
|
{
|
||||||
StreamWriter writer(ctx.OpenResponseStream());
|
StreamWriter writer(ctx.OpenResponseStream());
|
||||||
@@ -109,6 +125,12 @@ class MyOtherWebServer : public IHttpServer
|
|||||||
ctx.SendText(data->text);
|
ctx.SendText(data->text);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(ctx.path == "/mypath.html")
|
||||||
|
{
|
||||||
|
std::string txt = "<h1>Root: " + HttpUtils::HtmlEncode(ctx.GetServerRoot()) + "</h1>";
|
||||||
|
ctx.WithMimeType("text/html").SendText(txt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ namespace Tesses::Framework
|
|||||||
mtx.Lock();
|
mtx.Lock();
|
||||||
for(std::shared_ptr<Event<TArgs...>>& item : this->items)
|
for(std::shared_ptr<Event<TArgs...>>& item : this->items)
|
||||||
{
|
{
|
||||||
if(item.get() == event.get()) return;
|
if(item.get() == event.get()) {
|
||||||
|
mtx.Unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->items.push_back(event);
|
this->items.push_back(event);
|
||||||
mtx.Unlock();
|
mtx.Unlock();
|
||||||
@@ -56,10 +59,11 @@ namespace Tesses::Framework
|
|||||||
if(i->get() == event.get())
|
if(i->get() == event.get())
|
||||||
{
|
{
|
||||||
this->items.erase(i);
|
this->items.erase(i);
|
||||||
|
mtx.Unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtx.Lock();
|
mtx.Unlock();
|
||||||
}
|
}
|
||||||
void Invoke(TArgs... args)
|
void Invoke(TArgs... args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,5 @@ namespace Tesses::Framework::Filesystem
|
|||||||
|
|
||||||
void Chmod(VFSPath path, uint32_t mode);
|
void Chmod(VFSPath path, uint32_t mode);
|
||||||
|
|
||||||
void Close();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
14
include/TessesFramework/Http/ChangeableServer.hpp
Normal file
14
include/TessesFramework/Http/ChangeableServer.hpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "HttpServer.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::Framework::Http
|
||||||
|
{
|
||||||
|
class ChangeableServer {
|
||||||
|
public:
|
||||||
|
ChangeableServer();
|
||||||
|
ChangeableServer(std::shared_ptr<IHttpServer> original);
|
||||||
|
std::shared_ptr<IHttpServer> server;
|
||||||
|
bool Handle(ServerContext& ctx);
|
||||||
|
~ChangeableServer();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -56,8 +56,15 @@ namespace Tesses::Framework::Http
|
|||||||
ServerContext& WithMimeType(std::string mime);
|
ServerContext& WithMimeType(std::string mime);
|
||||||
ServerContext& WithContentDisposition(std::string filename, bool isInline);
|
ServerContext& WithContentDisposition(std::string filename, bool isInline);
|
||||||
ServerContext& WriteHeaders();
|
ServerContext& WriteHeaders();
|
||||||
|
ServerContext& WithLocationHeader(std::string url);
|
||||||
|
ServerContext& WithLocationHeader(std::string url,StatusCode sc);
|
||||||
void StartWebSocketSession(std::function<void(std::function<void(WebSocketMessage&)>,std::function<void()>,std::function<void()>)> onOpen, std::function<void(WebSocketMessage&)> onReceive, std::function<void(bool)> onClose);
|
void StartWebSocketSession(std::function<void(std::function<void(WebSocketMessage&)>,std::function<void()>,std::function<void()>)> onOpen, std::function<void(WebSocketMessage&)> onReceive, std::function<void(bool)> onClose);
|
||||||
void StartWebSocketSession(std::shared_ptr<WebSocketConnection> connection);
|
void StartWebSocketSession(std::shared_ptr<WebSocketConnection> connection);
|
||||||
|
std::string GetServerRoot();
|
||||||
|
std::string MakeAbsolute(std::string path);
|
||||||
|
void SendRedirect(std::string url);
|
||||||
|
void SendRedirect(std::string url, StatusCode sc);
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* GetServerContentData(std::string tag)
|
T* GetServerContentData(std::string tag)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Tesses::Framework::Streams
|
|||||||
virtual void Flush();
|
virtual void Flush();
|
||||||
virtual void Seek(int64_t pos, SeekOrigin whence);
|
virtual void Seek(int64_t pos, SeekOrigin whence);
|
||||||
void CopyTo(std::shared_ptr<Stream> strm, size_t buffSize=1024);
|
void CopyTo(std::shared_ptr<Stream> strm, size_t buffSize=1024);
|
||||||
|
void CopyToLimit(std::shared_ptr<Stream> strm,uint64_t len, size_t buffSize=1024);
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
virtual ~Stream();
|
virtual ~Stream();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Http/CallbackServer.hpp"
|
#include "Http/CallbackServer.hpp"
|
||||||
#include "Http/MountableServer.hpp"
|
#include "Http/MountableServer.hpp"
|
||||||
#include "Http/ContentDisposition.hpp"
|
#include "Http/ContentDisposition.hpp"
|
||||||
|
#include "Http/ChangeableServer.hpp"
|
||||||
#include "Streams/FileStream.hpp"
|
#include "Streams/FileStream.hpp"
|
||||||
#include "Streams/MemoryStream.hpp"
|
#include "Streams/MemoryStream.hpp"
|
||||||
#include "Streams/NetworkStream.hpp"
|
#include "Streams/NetworkStream.hpp"
|
||||||
|
|||||||
@@ -21,12 +21,7 @@ namespace Tesses::Framework::Filesystem
|
|||||||
for(auto item : this->directories) delete item;
|
for(auto item : this->directories) delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MountableFilesystem::Close()
|
|
||||||
{
|
|
||||||
this->root=nullptr;
|
|
||||||
for(auto item : this->directories) delete item;
|
|
||||||
this->directories.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MountableFilesystem::GetFS(VFSPath srcPath, VFSPath& destRoot, VFSPath& destPath, std::shared_ptr<VFS>& vfs)
|
void MountableFilesystem::GetFS(VFSPath srcPath, VFSPath& destRoot, VFSPath& destPath, std::shared_ptr<VFS>& vfs)
|
||||||
|
|||||||
22
src/Http/ChangeableServer.cpp
Normal file
22
src/Http/ChangeableServer.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "TessesFramework/Http/ChangeableServer.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::Framework::Http {
|
||||||
|
ChangeableServer::ChangeableServer() : ChangeableServer(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ChangeableServer::ChangeableServer(std::shared_ptr<IHttpServer> original)
|
||||||
|
{
|
||||||
|
this->server = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChangeableServer::Handle(ServerContext& ctx)
|
||||||
|
{
|
||||||
|
if(this->server) this->server->Handle(ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ChangeableServer::~ChangeableServer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "TessesFramework/Threading/Mutex.hpp"
|
#include "TessesFramework/Threading/Mutex.hpp"
|
||||||
#include "TessesFramework/Common.hpp"
|
#include "TessesFramework/Common.hpp"
|
||||||
#include "TessesFramework/TextStreams/StdIOWriter.hpp"
|
#include "TessesFramework/TextStreams/StdIOWriter.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/VFSFix.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/VFS.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using FileStream = Tesses::Framework::Streams::FileStream;
|
using FileStream = Tesses::Framework::Streams::FileStream;
|
||||||
@@ -801,7 +803,7 @@ namespace Tesses::Framework::Http
|
|||||||
this->strm->WriteBlock(buffer,read);
|
this->strm->WriteBlock(buffer,read);
|
||||||
|
|
||||||
begin += read;
|
begin += read;
|
||||||
} while(read > 0);
|
} while(read > 0 && !this->strm->EndOfStream());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -858,6 +860,26 @@ namespace Tesses::Framework::Http
|
|||||||
this->responseHeaders.SetValue("Content-Disposition",cd.ToString());
|
this->responseHeaders.SetValue("Content-Disposition",cd.ToString());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
ServerContext& ServerContext::WithLocationHeader(std::string url)
|
||||||
|
{
|
||||||
|
return WithSingleHeader("Location", this->MakeAbsolute(url));
|
||||||
|
}
|
||||||
|
ServerContext& ServerContext::WithLocationHeader(std::string url,StatusCode sc)
|
||||||
|
{
|
||||||
|
this->statusCode = sc;
|
||||||
|
return WithSingleHeader("Location", this->MakeAbsolute(url));
|
||||||
|
}
|
||||||
|
void ServerContext::SendRedirect(std::string url)
|
||||||
|
{
|
||||||
|
WithLocationHeader(url);
|
||||||
|
this->WriteHeaders();
|
||||||
|
}
|
||||||
|
void ServerContext::SendRedirect(std::string url,StatusCode sc)
|
||||||
|
{
|
||||||
|
WithLocationHeader(url,sc);
|
||||||
|
this->WriteHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
void ServerContext::SendNotFound()
|
void ServerContext::SendNotFound()
|
||||||
{
|
{
|
||||||
if(sent) return;
|
if(sent) return;
|
||||||
@@ -1053,5 +1075,22 @@ namespace Tesses::Framework::Http
|
|||||||
svr.Start();
|
svr.Start();
|
||||||
thrd.Join();
|
thrd.Join();
|
||||||
}
|
}
|
||||||
|
std::string ServerContext::GetServerRoot()
|
||||||
|
{
|
||||||
|
if(this->originalPath == this->path) return "/";
|
||||||
|
Tesses::Framework::Filesystem::VFSPath originalPath=this->originalPath;
|
||||||
|
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path=this->path;
|
||||||
|
if(originalPath.path.size() <= path.path.size()) return "/";
|
||||||
|
|
||||||
|
originalPath.path.resize(originalPath.path.size() - path.path.size());
|
||||||
|
return originalPath.ToString();
|
||||||
|
}
|
||||||
|
std::string ServerContext::MakeAbsolute(std::string path)
|
||||||
|
{
|
||||||
|
if(path.find("http://") == 0 || path.find("https://") == 0 || path.find("/") == 0) return path;
|
||||||
|
Tesses::Framework::Filesystem::VFSPath path2 = GetServerRoot();
|
||||||
|
path2 = path2 / path;
|
||||||
|
return path2.CollapseRelativeParents().ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
buffer += read;
|
buffer += read;
|
||||||
len -= read;
|
len -= read;
|
||||||
} while(read > 0);
|
} while(read > 0 && !this->EndOfStream());
|
||||||
}
|
}
|
||||||
bool Stream::CanRead()
|
bool Stream::CanRead()
|
||||||
{
|
{
|
||||||
@@ -97,6 +97,27 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stream::CopyToLimit(std::shared_ptr<Stream> strm,uint64_t len, size_t buffSize)
|
||||||
|
{
|
||||||
|
size_t read;
|
||||||
|
uint8_t* buffer = new uint8_t[buffSize];
|
||||||
|
uint64_t offset = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(offset >= len) break;
|
||||||
|
read = (size_t)std::min(len-offset,(uint64_t)buffSize);
|
||||||
|
|
||||||
|
read = this->Read(buffer,read);
|
||||||
|
strm->WriteBlock(buffer, read);
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
|
||||||
|
} while(read > 0 && !strm->EndOfStream());
|
||||||
|
strm->Flush();
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void Stream::CopyTo(std::shared_ptr<Stream> strm, size_t buffSize)
|
void Stream::CopyTo(std::shared_ptr<Stream> strm, size_t buffSize)
|
||||||
{
|
{
|
||||||
size_t read;
|
size_t read;
|
||||||
@@ -107,7 +128,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
read = this->Read(buffer,buffSize);
|
read = this->Read(buffer,buffSize);
|
||||||
strm->WriteBlock(buffer, read);
|
strm->WriteBlock(buffer, read);
|
||||||
|
|
||||||
} while(read > 0);
|
} while(read > 0 && !strm->EndOfStream());
|
||||||
strm->Flush();
|
strm->Flush();
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user