mirror of
https://git.tesses.org/tesses50/tessesframework.git
synced 2026-06-01 18:15:31 +00:00
Make streams and vfs and http shared_ptr
This commit is contained in:
@@ -15,23 +15,20 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
FileServer::FileServer(std::filesystem::path path,bool allowListing, bool spa, std::vector<std::string> defaultNames)
|
||||
{
|
||||
LocalFilesystem* lfs=new LocalFilesystem();
|
||||
SubdirFilesystem* sdfs=new SubdirFilesystem(lfs,lfs->SystemToVFSPath(path.string()),true);
|
||||
std::shared_ptr<SubdirFilesystem> sdfs=std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(path.string()));
|
||||
this->vfs = sdfs;
|
||||
this->spa = spa;
|
||||
|
||||
this->ownsVFS=true;
|
||||
this->allowListing = allowListing;
|
||||
this->defaultNames = defaultNames;
|
||||
}
|
||||
FileServer::FileServer(Tesses::Framework::Filesystem::VFS* fs, bool owns, bool allowListing,bool spa) : FileServer(fs,owns,allowListing,spa,{"index.html","default.html","index.htm","default.htm"})
|
||||
FileServer::FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs, bool allowListing,bool spa) : FileServer(fs,allowListing,spa,{"index.html","default.html","index.htm","default.htm"})
|
||||
{
|
||||
|
||||
}
|
||||
FileServer::FileServer(Tesses::Framework::Filesystem::VFS* fs, bool owns, bool allowListing, bool spa, std::vector<std::string> defaultNames)
|
||||
FileServer::FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs, bool allowListing, bool spa, std::vector<std::string> defaultNames)
|
||||
{
|
||||
this->vfs = fs;
|
||||
this->ownsVFS = owns;
|
||||
this->allowListing = allowListing;
|
||||
this->defaultNames = defaultNames;
|
||||
this->spa = spa;
|
||||
@@ -49,8 +46,6 @@ namespace Tesses::Framework::Http
|
||||
retVal = true;
|
||||
|
||||
}
|
||||
|
||||
delete strm;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -130,7 +125,6 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
FileServer::~FileServer()
|
||||
{
|
||||
if(this->ownsVFS)
|
||||
delete this->vfs;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Tesses::Framework::Http
|
||||
dict.SetValue("Content-Type",this->mimeType);
|
||||
dict.SetValue("Content-Length",std::to_string(this->text.size()));
|
||||
}
|
||||
void TextHttpRequestBody::Write(Tesses::Framework::Streams::Stream* strm)
|
||||
void TextHttpRequestBody::Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
strm->WriteBlock((const uint8_t*)this->text.c_str(),this->text.size());
|
||||
}
|
||||
@@ -50,10 +50,9 @@ namespace Tesses::Framework::Http
|
||||
|
||||
}
|
||||
|
||||
StreamHttpRequestBody::StreamHttpRequestBody(Stream* strm, bool owns, std::string mimeType)
|
||||
StreamHttpRequestBody::StreamHttpRequestBody(std::shared_ptr<Stream> strm, std::string mimeType)
|
||||
{
|
||||
this->strm = strm;
|
||||
this->owns = owns;
|
||||
this->mimeType = mimeType;
|
||||
}
|
||||
void StreamHttpRequestBody::HandleHeaders(HttpDictionary& dict)
|
||||
@@ -63,14 +62,12 @@ namespace Tesses::Framework::Http
|
||||
if(len > -1) dict.AddValue("Content-Length",std::to_string(len));
|
||||
|
||||
}
|
||||
void StreamHttpRequestBody::Write(Tesses::Framework::Streams::Stream* strm)
|
||||
void StreamHttpRequestBody::Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
this->strm->CopyTo(strm);
|
||||
}
|
||||
StreamHttpRequestBody::~StreamHttpRequestBody()
|
||||
{
|
||||
if(this->owns)
|
||||
delete this->strm;
|
||||
}
|
||||
HttpRequest::HttpRequest()
|
||||
{
|
||||
@@ -82,7 +79,7 @@ namespace Tesses::Framework::Http
|
||||
this->requestHeaders.SetValue("Connection","close");
|
||||
}
|
||||
|
||||
void HttpRequest::SendRequest(Tesses::Framework::Streams::Stream* strm)
|
||||
void HttpRequest::SendRequest(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
Uri uri;
|
||||
if(!Uri::TryParse(this->url, uri)) return;
|
||||
@@ -109,7 +106,7 @@ namespace Tesses::Framework::Http
|
||||
request.append("\r\n");
|
||||
|
||||
|
||||
StreamWriter writer(strm, false);
|
||||
StreamWriter writer(strm);
|
||||
writer.Write(request);
|
||||
|
||||
if(body != nullptr)
|
||||
@@ -117,52 +114,51 @@ namespace Tesses::Framework::Http
|
||||
body->Write(strm);
|
||||
}
|
||||
}
|
||||
Stream* HttpRequest::EstablishConnection(Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
std::shared_ptr<Stream> HttpRequest::EstablishConnection(Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
{
|
||||
if(uri.scheme == "http:" || uri.scheme == "ws:")
|
||||
{
|
||||
return new NetworkStream(uri.host,uri.GetPort(),false,false,false);
|
||||
return std::make_shared<NetworkStream>(uri.host,uri.GetPort(),false,false,false);
|
||||
}
|
||||
else if(uri.scheme == "https:" || uri.scheme == "wss:")
|
||||
{
|
||||
auto netStrm = new NetworkStream(uri.host,uri.GetPort(),false,false,false);
|
||||
auto netStrm = std::make_shared<NetworkStream>(uri.host,uri.GetPort(),false,false,false);
|
||||
if(netStrm == nullptr) return nullptr;
|
||||
return new ClientTLSStream(netStrm, true, !ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
return std::make_shared<ClientTLSStream>(netStrm, !ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
Stream* HttpRequest::EstablishUnixPathConnection(std::string unixPath,Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
std::shared_ptr<Stream> HttpRequest::EstablishUnixPathConnection(std::string unixPath,Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
{
|
||||
if(uri.scheme == "http:" || uri.scheme == "ws:")
|
||||
{
|
||||
return new NetworkStream(unixPath,false);
|
||||
return std::make_shared<NetworkStream>(unixPath,false);
|
||||
}
|
||||
else if(uri.scheme == "https:" || uri.scheme == "wss:")
|
||||
{
|
||||
auto netStrm = new NetworkStream(unixPath,false);
|
||||
auto netStrm = std::make_shared <NetworkStream>(unixPath,false);
|
||||
if(netStrm == nullptr) return nullptr;
|
||||
return new ClientTLSStream(netStrm, true, !ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
return std::make_shared<ClientTLSStream>(netStrm, !ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
Tesses::Framework::Streams::Stream* HttpResponse::GetInternalStream()
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> HttpResponse::GetInternalStream()
|
||||
{
|
||||
return this->handleStrm;
|
||||
}
|
||||
|
||||
HttpResponse::~HttpResponse()
|
||||
{
|
||||
if(this->owns)
|
||||
delete this->handleStrm;
|
||||
|
||||
}
|
||||
|
||||
HttpResponse::HttpResponse(Stream* strm, bool owns)
|
||||
HttpResponse::HttpResponse(std::shared_ptr<Stream> strm)
|
||||
{
|
||||
this->handleStrm=nullptr;
|
||||
this->owns=owns;
|
||||
StreamReader reader(strm, false);
|
||||
StreamReader reader(strm);
|
||||
std::string statusLine;
|
||||
if(!reader.ReadLine(statusLine)) return;
|
||||
auto statusLinesPart = HttpUtils::SplitString(statusLine," ",3);
|
||||
@@ -178,7 +174,6 @@ namespace Tesses::Framework::Http
|
||||
auto v = HttpUtils::SplitString(line,": ", 2);
|
||||
if(v.size() != 2)
|
||||
{
|
||||
delete strm;
|
||||
return;
|
||||
}
|
||||
this->responseHeaders.AddValue(v[0],v[1]);
|
||||
@@ -222,7 +217,7 @@ namespace Tesses::Framework::Http
|
||||
request.append("\r\n");
|
||||
|
||||
|
||||
StreamWriter writer(strm, false);
|
||||
StreamWriter writer(strm);
|
||||
writer.Write(request);
|
||||
|
||||
if(req.body != nullptr)
|
||||
@@ -230,7 +225,7 @@ namespace Tesses::Framework::Http
|
||||
req.body->Write(strm);
|
||||
}
|
||||
|
||||
StreamReader reader(strm, false);
|
||||
StreamReader reader(strm);
|
||||
std::string statusLine;
|
||||
if(!reader.ReadLine(statusLine)) break;
|
||||
auto statusLinesPart = HttpUtils::SplitString(statusLine," ",3);
|
||||
@@ -246,7 +241,6 @@ namespace Tesses::Framework::Http
|
||||
auto v = HttpUtils::SplitString(line,": ", 2);
|
||||
if(v.size() != 2)
|
||||
{
|
||||
delete strm;
|
||||
return;
|
||||
}
|
||||
this->responseHeaders.AddValue(v[0],v[1]);
|
||||
@@ -264,7 +258,6 @@ namespace Tesses::Framework::Http
|
||||
url = uri2.ToString();
|
||||
|
||||
|
||||
delete strm;
|
||||
continue;
|
||||
}
|
||||
this->handleStrm = strm;
|
||||
@@ -275,18 +268,18 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
auto strm = ReadAsStream();
|
||||
if(strm == nullptr) return {};
|
||||
StreamReader r(strm, true);
|
||||
StreamReader r(strm);
|
||||
return r.ReadToEnd();
|
||||
}
|
||||
void HttpResponse::CopyToStream(Stream* strm)
|
||||
void HttpResponse::CopyToStream(std::shared_ptr<Stream> strm)
|
||||
{
|
||||
if(strm == nullptr) return;
|
||||
auto src = ReadAsStream();
|
||||
if(src == nullptr) return;
|
||||
src->CopyTo(*strm);
|
||||
delete src;
|
||||
src->CopyTo(strm);
|
||||
|
||||
}
|
||||
Stream* HttpResponse::ReadAsStream()
|
||||
std::shared_ptr<Stream> HttpResponse::ReadAsStream()
|
||||
{
|
||||
if(this->handleStrm == nullptr) return nullptr;
|
||||
int64_t length = -1;
|
||||
@@ -295,10 +288,10 @@ namespace Tesses::Framework::Http
|
||||
length = -1;
|
||||
}
|
||||
|
||||
return new HttpStream(this->handleStrm,false,length,true,version=="HTTP/1.1");
|
||||
return std::make_shared<HttpStream>(this->handleStrm,length,true,version=="HTTP/1.1");
|
||||
}
|
||||
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream* strm)
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
if(strm == nullptr) throw std::runtime_error("strm is null");
|
||||
HttpRequest request;
|
||||
@@ -310,26 +303,17 @@ namespace Tesses::Framework::Http
|
||||
if(response.statusCode < 200 || response.statusCode > 299) throw std::runtime_error("Status code does not indicate success: " + std::to_string(response.statusCode) + " " + HttpUtils::StatusCodeString(response.statusCode));
|
||||
response.CopyToStream(strm);
|
||||
}
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream& strm)
|
||||
{
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,&strm);
|
||||
}
|
||||
|
||||
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(vfs == nullptr) throw std::runtime_error("vfs is null");
|
||||
auto strm = vfs->OpenFile(path,"wb");
|
||||
if(strm == nullptr) throw std::runtime_error("strm is null");
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,strm);
|
||||
delete strm;
|
||||
}
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
auto strm = vfs.OpenFile(path,"wb");
|
||||
if(strm == nullptr) throw std::runtime_error("strm is null");
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,strm);
|
||||
delete strm;
|
||||
|
||||
}
|
||||
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple(unixSocket,url,Tesses::Framework::Filesystem::LocalFS,path);
|
||||
@@ -345,23 +329,17 @@ namespace Tesses::Framework::Http
|
||||
if(response.statusCode < 200 || response.statusCode > 299) throw std::runtime_error("Status code does not indicate success: " + std::to_string(response.statusCode) + " " + HttpUtils::StatusCodeString(response.statusCode));
|
||||
return response.ReadAsString();
|
||||
}
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream* strm)
|
||||
{
|
||||
DownloadUnixSocketToStreamSimple("",url,strm);
|
||||
}
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream& strm)
|
||||
void DownloadToStreamSimple(std::string url, std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
|
||||
{
|
||||
DownloadUnixSocketToStreamSimple("",url,strm);
|
||||
}
|
||||
|
||||
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple("",url,vfs,path);
|
||||
}
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
void DownloadToFileSimple(std::string url, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple("",url,vfs,path);
|
||||
}
|
||||
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple("",url,path);
|
||||
@@ -381,22 +359,15 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketUnixSocketClient("",url,requestHeaders,wsc,cb);
|
||||
}
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketUnixSocketClient(unixSocket,url,requestHeaders, &wsc,cb);
|
||||
}
|
||||
|
||||
|
||||
class WSClient {
|
||||
public:
|
||||
std::atomic<bool> closed;
|
||||
Threading::Mutex mtx;
|
||||
|
||||
WebSocketConnection* conn;
|
||||
Stream* strm;
|
||||
std::shared_ptr<WebSocketConnection> conn;
|
||||
std::shared_ptr<Stream> strm;
|
||||
void close()
|
||||
{
|
||||
mtx.Lock();
|
||||
@@ -557,7 +528,7 @@ namespace Tesses::Framework::Http
|
||||
return true;
|
||||
}
|
||||
|
||||
WSClient(Tesses::Framework::Streams::Stream* strm,WebSocketConnection* conn)
|
||||
WSClient(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,std::shared_ptr<WebSocketConnection> conn)
|
||||
{
|
||||
this->strm = strm;
|
||||
this->conn = conn;
|
||||
@@ -626,12 +597,12 @@ namespace Tesses::Framework::Http
|
||||
};
|
||||
|
||||
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, std::shared_ptr<WebSocketConnection> wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketUnixSocketClient("",url,requestHeaders,wsc,cb);
|
||||
}
|
||||
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, std::shared_ptr<WebSocketConnection> wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
HttpRequest req;
|
||||
req.url = url;
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace Tesses::Framework::Http
|
||||
public:
|
||||
Threading::Mutex mtx;
|
||||
ServerContext* ctx;
|
||||
WebSocketConnection* conn;
|
||||
Stream* strm;
|
||||
std::shared_ptr<WebSocketConnection> conn;
|
||||
std::shared_ptr<Stream> strm;
|
||||
std::atomic_bool hasInit;
|
||||
std::atomic<bool> closed;
|
||||
void close()
|
||||
@@ -42,7 +42,6 @@ namespace Tesses::Framework::Http
|
||||
strm->WriteByte(firstByte);
|
||||
strm->WriteByte(0);
|
||||
|
||||
delete strm;
|
||||
this->strm = nullptr;
|
||||
mtx.Unlock();
|
||||
this->conn->OnClose(true);
|
||||
@@ -180,11 +179,11 @@ namespace Tesses::Framework::Http
|
||||
return true;
|
||||
}
|
||||
|
||||
WSServer(ServerContext* ctx,WebSocketConnection* conn)
|
||||
WSServer(ServerContext* ctx,std::shared_ptr<WebSocketConnection> conn)
|
||||
{
|
||||
this->ctx = ctx;
|
||||
this->conn = conn;
|
||||
this->strm = &this->ctx->GetStream();
|
||||
this->strm = this->ctx->GetStream();
|
||||
this->hasInit=false;
|
||||
|
||||
|
||||
@@ -352,27 +351,23 @@ namespace Tesses::Framework::Http
|
||||
if(this->queryParams.kvp.empty()) return this->originalPath;
|
||||
return this->originalPath + "?" + HttpUtils::QueryParamsEncode(this->queryParams);
|
||||
}
|
||||
void ServerContext::ReadStream(Stream* strm)
|
||||
void ServerContext::ReadStream(std::shared_ptr<Stream> strm)
|
||||
{
|
||||
if(strm == nullptr) return;
|
||||
auto strm2 = this->OpenRequestStream();
|
||||
if(strm2 != nullptr)
|
||||
{
|
||||
strm2->CopyTo(strm);
|
||||
delete strm2;
|
||||
}
|
||||
}
|
||||
void ServerContext::ReadStream(Stream& strm)
|
||||
{
|
||||
ReadStream(&strm);
|
||||
}
|
||||
|
||||
std::string ServerContext::ReadString()
|
||||
{
|
||||
if(strm == nullptr) return {};
|
||||
auto strm2 = this->OpenRequestStream();
|
||||
if(strm2 != nullptr)
|
||||
{
|
||||
TextStreams::StreamReader reader(strm2,true);
|
||||
TextStreams::StreamReader reader(strm2);
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
return {};
|
||||
@@ -389,7 +384,7 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool parseUntillBoundaryEnd(Tesses::Framework::Streams::Stream* src, Tesses::Framework::Streams::Stream* dest, std::string boundary)
|
||||
static bool parseUntillBoundaryEnd(std::shared_ptr<Tesses::Framework::Streams::Stream> src, std::shared_ptr<Tesses::Framework::Streams::Stream> dest, std::string boundary)
|
||||
{
|
||||
bool hasMore=true;
|
||||
#if defined(_WIN32)
|
||||
@@ -466,7 +461,7 @@ namespace Tesses::Framework::Http
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
static bool parseSection(ServerContext* ctx, std::string boundary, std::function<Tesses::Framework::Streams::Stream*(std::string mime, std::string filename, std::string name)> cb)
|
||||
static bool parseSection(ServerContext* ctx, std::string boundary, std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(std::string mime, std::string filename, std::string name)> cb)
|
||||
{
|
||||
HttpDictionary req;
|
||||
StreamReader reader(ctx->GetStream());
|
||||
@@ -489,10 +484,10 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
if(cd1.filename.empty())
|
||||
{
|
||||
MemoryStream ms(true);
|
||||
std::shared_ptr<MemoryStream> ms=std::make_shared<MemoryStream>(true);
|
||||
|
||||
bool retVal = parseUntillBoundaryEnd(&ctx->GetStream(),&ms,boundary);
|
||||
auto& buff = ms.GetBuffer();
|
||||
bool retVal = parseUntillBoundaryEnd(ctx->GetStream(),ms,boundary);
|
||||
auto& buff = ms->GetBuffer();
|
||||
|
||||
ctx->queryParams.AddValue(cd1.fieldName, std::string(buff.begin(),buff.end()));
|
||||
|
||||
@@ -502,16 +497,16 @@ namespace Tesses::Framework::Http
|
||||
else
|
||||
{
|
||||
auto strm = cb(ct, cd1.filename, cd1.fieldName);
|
||||
if(strm == nullptr) strm = new Stream();
|
||||
bool retVal = parseUntillBoundaryEnd(&ctx->GetStream(),strm,boundary);
|
||||
delete strm;
|
||||
if(strm == nullptr) strm = std::make_shared<Stream>();
|
||||
bool retVal = parseUntillBoundaryEnd(ctx->GetStream(),strm,boundary);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServerContext::ParseFormData(std::function<Tesses::Framework::Streams::Stream*(std::string mime, std::string filename, std::string name)> cb)
|
||||
void ServerContext::ParseFormData(std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(std::string mime, std::string filename, std::string name)> cb)
|
||||
{
|
||||
std::string ct;
|
||||
if(this->requestHeaders.TryGetFirst("Content-Type",ct))
|
||||
@@ -525,51 +520,33 @@ namespace Tesses::Framework::Http
|
||||
if(res == std::string::npos) return;
|
||||
ct = "--" + ct.substr(res+9);
|
||||
}
|
||||
Stream nullStrm;
|
||||
parseUntillBoundaryEnd(this->strm,&nullStrm, ct);
|
||||
std::shared_ptr<Stream> nullStrm=std::make_shared<Stream>();
|
||||
parseUntillBoundaryEnd(this->strm,nullStrm, ct);
|
||||
|
||||
while(parseSection(this, ct, cb));
|
||||
}
|
||||
HttpServer::HttpServer(Tesses::Framework::Streams::TcpServer& tcpServer, IHttpServer& http, bool showIPs) : HttpServer(&tcpServer,false,&http,false,showIPs)
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(Tesses::Framework::Streams::TcpServer* tcpServer, bool ownsTCP, IHttpServer& http, bool showIPs) : HttpServer(tcpServer,ownsTCP,&http,false,showIPs)
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(Tesses::Framework::Streams::TcpServer& tcpServer, IHttpServer* http, bool ownsHttpServer, bool showIPs) : HttpServer(&tcpServer,false,http,ownsHttpServer,showIPs)
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(Tesses::Framework::Streams::TcpServer* tcpServer, bool ownsTCP, IHttpServer* http, bool ownsHttpServer, bool showIPs)
|
||||
HttpServer::HttpServer(std::shared_ptr<Tesses::Framework::Streams::TcpServer> tcpServer, std::shared_ptr<IHttpServer> http, bool showIPs)
|
||||
{
|
||||
this->server = tcpServer;
|
||||
this->ownsTCP = ownsTCP;
|
||||
this->http = http;
|
||||
this->ownsHttp = ownsHttpServer;
|
||||
|
||||
this->showIPs = showIPs;
|
||||
this->thrd=nullptr;
|
||||
this->showARTL = showIPs;
|
||||
}
|
||||
|
||||
|
||||
HttpServer::HttpServer(uint16_t port, IHttpServer* http, bool owns, bool showIPs) : HttpServer(new TcpServer(port,10),true,http,owns,showIPs)
|
||||
HttpServer::HttpServer(uint16_t port, std::shared_ptr<IHttpServer> http, bool showIPs) : HttpServer(std::make_shared<TcpServer>(port,10),http,showIPs)
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(uint16_t port, IHttpServer& http,bool showIPs) : HttpServer(port,&http,false,showIPs)
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(std::string unixPath, IHttpServer* http, bool owns) : HttpServer(new TcpServer(unixPath,10),true,http,owns,false)
|
||||
|
||||
HttpServer::HttpServer(std::string unixPath, std::shared_ptr<IHttpServer> http) : HttpServer(std::make_shared<TcpServer>(unixPath,10),http,false)
|
||||
{
|
||||
this->showARTL=true;
|
||||
}
|
||||
HttpServer::HttpServer(std::string unixPath, IHttpServer& http) : HttpServer(unixPath,&http,false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint16_t HttpServer::GetPort()
|
||||
{
|
||||
@@ -577,7 +554,7 @@ namespace Tesses::Framework::Http
|
||||
return server->GetPort();
|
||||
return 0;
|
||||
}
|
||||
Stream* ServerContext::OpenResponseStream()
|
||||
std::shared_ptr<Stream> ServerContext::OpenResponseStream()
|
||||
{
|
||||
if(sent) return nullptr;
|
||||
int64_t length = -1;
|
||||
@@ -588,14 +565,14 @@ namespace Tesses::Framework::Http
|
||||
this->responseHeaders.SetValue("Transfer-Encoding","chunked");
|
||||
|
||||
this->WriteHeaders();
|
||||
return new HttpStream(this->strm,false,length,false,version == "HTTP/1.1");
|
||||
return std::make_shared<HttpStream>(this->strm,length,false,version == "HTTP/1.1");
|
||||
}
|
||||
Stream* ServerContext::OpenRequestStream()
|
||||
std::shared_ptr<Stream> ServerContext::OpenRequestStream()
|
||||
{
|
||||
int64_t length = -1;
|
||||
if(!this->requestHeaders.TryGetFirstInt("Content-Length",length))
|
||||
length = -1;
|
||||
return new HttpStream(this->strm,false,length,true,version == "HTTP/1.1");
|
||||
return std::make_shared<HttpStream>(this->strm,length,true,version == "HTTP/1.1");
|
||||
}
|
||||
void HttpServer::StartAccepting()
|
||||
{
|
||||
@@ -622,9 +599,9 @@ namespace Tesses::Framework::Http
|
||||
TF_LOG("Before entering socket thread");
|
||||
Threading::Thread thrd2([sock,http,ip,port]()->void {
|
||||
TF_LOG("In thread to process");
|
||||
HttpServer::Process(*sock,*http,ip,port,false);
|
||||
HttpServer::Process(sock,http,ip,port,false);
|
||||
TF_LOG("In thread after process");
|
||||
delete sock;
|
||||
|
||||
});
|
||||
TF_LOG("Before attach");
|
||||
thrd2.Detach();
|
||||
@@ -664,16 +641,13 @@ namespace Tesses::Framework::Http
|
||||
this->thrd->Join();
|
||||
delete this->thrd;
|
||||
}
|
||||
if(this->ownsHttp)
|
||||
delete http;
|
||||
if(this->ownsTCP)
|
||||
delete this->server;
|
||||
|
||||
}
|
||||
IHttpServer::~IHttpServer()
|
||||
{
|
||||
|
||||
}
|
||||
ServerContext::ServerContext(Stream* strm)
|
||||
ServerContext::ServerContext(std::shared_ptr<Stream> strm)
|
||||
{
|
||||
this->statusCode = OK;
|
||||
this->strm = strm;
|
||||
@@ -681,14 +655,14 @@ namespace Tesses::Framework::Http
|
||||
this->queryParams.SetCaseSensitive(true);
|
||||
this->responseHeaders.AddValue("Server","TessesFrameworkWebServer");
|
||||
}
|
||||
Stream& ServerContext::GetStream()
|
||||
std::shared_ptr<Stream> ServerContext::GetStream()
|
||||
{
|
||||
return *this->strm;
|
||||
return this->strm;
|
||||
}
|
||||
void ServerContext::SendBytes(std::vector<uint8_t> buff)
|
||||
{
|
||||
MemoryStream strm(false);
|
||||
strm.GetBuffer() = buff;
|
||||
std::shared_ptr<MemoryStream> strm=std::make_shared<MemoryStream>(false);
|
||||
strm->GetBuffer() = buff;
|
||||
SendStream(strm);
|
||||
}
|
||||
ServerContext& ServerContext::WithLastModified(Date::DateTime dt)
|
||||
@@ -699,8 +673,9 @@ namespace Tesses::Framework::Http
|
||||
|
||||
void ServerContext::SendText(std::string text)
|
||||
{
|
||||
MemoryStream strm(false);
|
||||
auto& buff= strm.GetBuffer();
|
||||
std::shared_ptr<MemoryStream> strm=std::make_shared<MemoryStream>(false);
|
||||
|
||||
auto& buff= strm->GetBuffer();
|
||||
buff.insert(buff.end(),text.begin(),text.end());
|
||||
SendStream(strm);
|
||||
}
|
||||
@@ -711,11 +686,7 @@ namespace Tesses::Framework::Http
|
||||
|
||||
WithMimeType("text/html").SendText(errorHtml);
|
||||
}
|
||||
void ServerContext::SendStream(Stream* strm)
|
||||
{
|
||||
if(strm == nullptr) return;
|
||||
SendStream(*strm);
|
||||
}
|
||||
|
||||
ServerContext::~ServerContext()
|
||||
{
|
||||
for(auto item : this->data)
|
||||
@@ -727,14 +698,14 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
|
||||
}
|
||||
void ServerContext::SendStream(Stream& strm)
|
||||
void ServerContext::SendStream(std::shared_ptr<Stream> strm)
|
||||
{
|
||||
if(sent) return;
|
||||
if(!strm.CanRead()) throw std::runtime_error("Cannot read from stream");
|
||||
if(strm.EndOfStream()) throw std::runtime_error("End of stream");
|
||||
if(strm.CanSeek())
|
||||
if(!strm->CanRead()) throw std::runtime_error("Cannot read from stream");
|
||||
if(strm->EndOfStream()) throw std::runtime_error("End of stream");
|
||||
if(strm->CanSeek())
|
||||
{
|
||||
int64_t len=strm.GetLength();
|
||||
int64_t len=strm->GetLength();
|
||||
std::string range={};
|
||||
if(this->requestHeaders.TryGetFirst("Range",range))
|
||||
{
|
||||
@@ -815,7 +786,7 @@ namespace Tesses::Framework::Http
|
||||
this->WithSingleHeader("Content-Range","bytes " + std::to_string(begin) + "-" + std::to_string(end) + "/" + std::to_string(len));
|
||||
this->statusCode = PartialContent;
|
||||
this->WriteHeaders();
|
||||
strm.Seek(begin,SeekOrigin::Begin);
|
||||
strm->Seek(begin,SeekOrigin::Begin);
|
||||
|
||||
uint8_t buffer[1024];
|
||||
|
||||
@@ -825,7 +796,7 @@ namespace Tesses::Framework::Http
|
||||
myLen = (end - begin)+1;
|
||||
if(myLen < read) read = (size_t)myLen;
|
||||
if(read == 0) break;
|
||||
read = strm.Read(buffer,read);
|
||||
read = strm->Read(buffer,read);
|
||||
if(read == 0) break;
|
||||
this->strm->WriteBlock(buffer,read);
|
||||
|
||||
@@ -848,7 +819,7 @@ namespace Tesses::Framework::Http
|
||||
this->WithSingleHeader("Accept-Range","bytes");
|
||||
this->WithSingleHeader("Content-Length",std::to_string(len));
|
||||
this->WriteHeaders();
|
||||
strm.CopyTo(*this->strm);
|
||||
strm->CopyTo(this->strm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,7 +828,7 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
auto chunkedStream = this->OpenResponseStream();
|
||||
this->strm->CopyTo(chunkedStream);
|
||||
delete chunkedStream;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -920,7 +891,7 @@ namespace Tesses::Framework::Http
|
||||
if(this->sent) return *this;
|
||||
this->sent = true;
|
||||
|
||||
StreamWriter writer(this->strm,false);
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine("HTTP/1.1 " + std::to_string((int)statusCode) + " " + HttpUtils::StatusCodeString(statusCode));
|
||||
for(auto& hdr : responseHeaders.kvp)
|
||||
@@ -935,14 +906,14 @@ namespace Tesses::Framework::Http
|
||||
|
||||
return *this;
|
||||
}
|
||||
void HttpServer::Process(Stream& strm, IHttpServer& server, std::string ip, uint16_t port, bool encrypted)
|
||||
void HttpServer::Process(std::shared_ptr<Stream> strm, std::shared_ptr<IHttpServer> server, std::string ip, uint16_t port, bool encrypted)
|
||||
{
|
||||
TF_LOG("In process");
|
||||
while(true)
|
||||
{
|
||||
BufferedStream bStrm(strm);
|
||||
std::shared_ptr<BufferedStream> bStrm = std::make_shared<BufferedStream>(strm);
|
||||
StreamReader reader(bStrm);
|
||||
ServerContext ctx(&bStrm);
|
||||
ServerContext ctx(bStrm);
|
||||
ctx.ip = ip;
|
||||
ctx.port = port;
|
||||
ctx.encrypted = encrypted;
|
||||
@@ -1002,13 +973,13 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
size_t len = (size_t)length;
|
||||
uint8_t* buffer = new uint8_t[len];
|
||||
len = bStrm.ReadBlock(buffer,len);
|
||||
len = bStrm->ReadBlock(buffer,len);
|
||||
std::string query((const char*)buffer,len);
|
||||
delete[] buffer;
|
||||
HttpUtils::QueryParamsDecode(ctx.queryParams, query);
|
||||
}
|
||||
|
||||
if(!server.Handle(ctx))
|
||||
if(!server->Handle(ctx))
|
||||
{
|
||||
ctx.SendNotFound();
|
||||
}
|
||||
@@ -1047,7 +1018,7 @@ namespace Tesses::Framework::Http
|
||||
if(HttpUtils::ToLower(connection) != "keep-alive") return;
|
||||
}
|
||||
|
||||
if(bStrm.EndOfStream()) {
|
||||
if(bStrm->EndOfStream()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1059,16 +1030,16 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
void ServerContext::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)
|
||||
{
|
||||
CallbackWebSocketConnection wsc(onOpen,onReceive,onClose);
|
||||
std::shared_ptr<CallbackWebSocketConnection> wsc = std::make_shared<CallbackWebSocketConnection>(onOpen,onReceive,onClose);
|
||||
StartWebSocketSession(wsc);
|
||||
}
|
||||
|
||||
void ServerContext::StartWebSocketSession(WebSocketConnection& connection)
|
||||
void ServerContext::StartWebSocketSession(std::shared_ptr<WebSocketConnection> connection)
|
||||
{
|
||||
WSServer svr(this,&connection);
|
||||
WSServer svr(this,connection);
|
||||
Threading::Thread thrd([&svr,&connection]()->void{
|
||||
try {
|
||||
connection.OnOpen([&svr](WebSocketMessage& msg)->void {
|
||||
connection->OnOpen([&svr](WebSocketMessage& msg)->void {
|
||||
svr.send_msg(&msg);
|
||||
},[&svr]()->void {
|
||||
std::vector<uint8_t> p = {(uint8_t)'p',(uint8_t)'i',(uint8_t)'n',(uint8_t)'g'};
|
||||
|
||||
@@ -7,10 +7,9 @@ using StreamWriter = Tesses::Framework::TextStreams::StreamWriter;
|
||||
using StreamReader = Tesses::Framework::TextStreams::StreamReader;
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
HttpStream::HttpStream(Tesses::Framework::Streams::Stream* strm, bool owns, int64_t length, bool recv, bool http1_1)
|
||||
HttpStream::HttpStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm, int64_t length, bool recv, bool http1_1)
|
||||
{
|
||||
this->strm = strm;
|
||||
this->owns = owns;
|
||||
this->length = length;
|
||||
this->recv = recv;
|
||||
this->http1_1 = http1_1;
|
||||
@@ -18,10 +17,6 @@ namespace Tesses::Framework::Http
|
||||
this->read = 0;
|
||||
this->position = 0;
|
||||
this->done=false;
|
||||
}
|
||||
HttpStream::HttpStream(Tesses::Framework::Streams::Stream& strm, int64_t length, bool recv,bool http1_1) : HttpStream(&strm,false,length,recv,http1_1)
|
||||
{
|
||||
|
||||
}
|
||||
bool HttpStream::CanRead()
|
||||
{
|
||||
@@ -79,14 +74,14 @@ namespace Tesses::Framework::Http
|
||||
this->position += len;
|
||||
if(this->offset >= this->read)
|
||||
{
|
||||
StreamReader reader(this->strm, false);
|
||||
StreamReader reader(this->strm);
|
||||
reader.ReadLine();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamReader reader(this->strm, false);
|
||||
StreamReader reader(this->strm);
|
||||
std::string line = reader.ReadLine();
|
||||
if(!line.empty())
|
||||
{
|
||||
@@ -141,7 +136,7 @@ namespace Tesses::Framework::Http
|
||||
std::stringstream strm;
|
||||
strm << std::hex << len;
|
||||
|
||||
StreamWriter writer(this->strm,false);
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine(strm.str());
|
||||
|
||||
@@ -160,11 +155,10 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
if(this->length == -1 && this->http1_1)
|
||||
{
|
||||
StreamWriter writer(this->strm,false);
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine("0");
|
||||
writer.WriteLine();
|
||||
}
|
||||
if(this->owns) delete this->strm;
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,18 @@ bool MountableServer::StartsWith(Filesystem::VFSPath fullPath, Filesystem::VFSPa
|
||||
}
|
||||
return true;
|
||||
}
|
||||
MountableServer::MountableServer() : MountableServer(nullptr,false)
|
||||
MountableServer::MountableServer() : MountableServer(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
MountableServer::MountableServer(IHttpServer* root, bool owns)
|
||||
MountableServer::MountableServer(std::shared_ptr<IHttpServer> root)
|
||||
{
|
||||
this->root = root;
|
||||
this->owns = owns;
|
||||
}
|
||||
MountableServer::MountableServer(IHttpServer& root) : MountableServer(&root,false)
|
||||
|
||||
void MountableServer::Mount(std::string path, std::shared_ptr<IHttpServer> server)
|
||||
{
|
||||
|
||||
}
|
||||
void MountableServer::Mount(std::string path, IHttpServer* server, bool owns)
|
||||
{
|
||||
this->servers.insert(this->servers.begin(), std::pair<std::string,std::pair<bool,IHttpServer*>>(path, std::pair<bool,IHttpServer*>(owns,server)));
|
||||
}
|
||||
void MountableServer::Mount(std::string path, IHttpServer& server)
|
||||
{
|
||||
Mount(path,&server,false);
|
||||
this->servers.insert(this->servers.begin(), std::pair<std::string,std::shared_ptr<IHttpServer>>(path, server));
|
||||
}
|
||||
void MountableServer::Unmount(std::string path)
|
||||
{
|
||||
@@ -50,7 +42,6 @@ void MountableServer::Unmount(std::string path)
|
||||
auto& item = *i;
|
||||
if(item.first == path)
|
||||
{
|
||||
if(item.second.first) delete item.second.second;
|
||||
this->servers.erase(i);
|
||||
return;
|
||||
}
|
||||
@@ -64,7 +55,7 @@ bool MountableServer::Handle(ServerContext& ctx)
|
||||
if(StartsWith(oldPath, item.first))
|
||||
{
|
||||
ctx.path = Subpath(oldPath, item.first);
|
||||
if(item.second.second->Handle(ctx))
|
||||
if(item.second->Handle(ctx))
|
||||
{
|
||||
ctx.path = oldPath;
|
||||
return true;
|
||||
@@ -79,7 +70,5 @@ bool MountableServer::Handle(ServerContext& ctx)
|
||||
}
|
||||
MountableServer::~MountableServer()
|
||||
{
|
||||
if(this->owns) delete this->root;
|
||||
for(auto svr : this->servers) if(svr.second.first) delete svr.second.second;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user