first commit
This commit is contained in:
19
include/TessesFramework/Common.hpp
Normal file
19
include/TessesFramework/Common.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace Tesses::Framework
|
||||
{
|
||||
void TF_Init();
|
||||
void TF_ConnectToSelf(uint16_t port);
|
||||
void TF_RunEventLoop();
|
||||
void TF_RunEventLoopItteration();
|
||||
bool TF_IsRunning();
|
||||
void TF_Quit();
|
||||
}
|
||||
24
include/TessesFramework/Crypto/ClientTLSStream.hpp
Normal file
24
include/TessesFramework/Crypto/ClientTLSStream.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "../Streams/Stream.hpp"
|
||||
|
||||
|
||||
namespace Tesses::Framework::Crypto
|
||||
{
|
||||
class ClientTLSStream : public Tesses::Framework::Streams::Stream {
|
||||
void* privateData;
|
||||
static int strm_send(void* ctx,const unsigned char* buf,size_t len);
|
||||
static int strm_recv(void* ctx,unsigned char* buf,size_t len);
|
||||
public:
|
||||
static std::string GetCertChain();
|
||||
|
||||
ClientTLSStream(Tesses::Framework::Streams::Stream* innerStream, bool owns, bool verify, std::string domain);
|
||||
ClientTLSStream(Tesses::Framework::Streams::Stream* innerStream, bool owns, bool verify, std::string domain, std::string cert);
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
bool EndOfStream();
|
||||
~ClientTLSStream();
|
||||
};
|
||||
|
||||
}
|
||||
28
include/TessesFramework/Filesystem/LocalFS.hpp
Normal file
28
include/TessesFramework/Filesystem/LocalFS.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "VFS.hpp"
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class LocalFilesystem : public VFS
|
||||
{
|
||||
public:
|
||||
Tesses::Framework::Streams::Stream* OpenFile(VFSPath path, std::string mode);
|
||||
void CreateDirectory(VFSPath path);
|
||||
void DeleteDirectory(VFSPath path);
|
||||
bool RegularFileExists(VFSPath path);
|
||||
bool SymlinkExists(VFSPath path);
|
||||
bool CharacterDeviceExists(VFSPath path);
|
||||
bool BlockDeviceExists(VFSPath path);
|
||||
bool SocketFileExists(VFSPath path);
|
||||
bool FIFOFileExists(VFSPath path);
|
||||
bool DirectoryExists(VFSPath path);
|
||||
void DeleteFile(VFSPath path);
|
||||
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||
void GetPaths(VFSPath path, std::vector<VFSPath>& paths);
|
||||
void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||
void MoveFile(VFSPath src, VFSPath dest);
|
||||
void MoveDirectory(VFSPath src, VFSPath dest);
|
||||
VFSPath ReadLink(VFSPath path);
|
||||
std::string VFSPathToSystem(VFSPath path);
|
||||
VFSPath SystemToVFSPath(std::string path);
|
||||
};
|
||||
}
|
||||
53
include/TessesFramework/Filesystem/MountableFilesystem.hpp
Normal file
53
include/TessesFramework/Filesystem/MountableFilesystem.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "VFS.hpp"
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class MountableDirectory {
|
||||
public:
|
||||
std::string name;
|
||||
VFS* vfs;
|
||||
bool owns;
|
||||
std::vector<MountableDirectory*> dirs;
|
||||
void GetFS(VFSPath srcPath, VFSPath curDir, VFSPath& destRoot, VFSPath& destPath, VFS*& vfs);
|
||||
~MountableDirectory();
|
||||
};
|
||||
|
||||
class MountableFilesystem : public VFS
|
||||
{
|
||||
bool owns;
|
||||
VFS* root;
|
||||
|
||||
std::vector<MountableDirectory*> directories;
|
||||
|
||||
void GetFS(VFSPath srcPath, VFSPath& destRoot, VFSPath& destPath, VFS*& vfs);
|
||||
|
||||
|
||||
public:
|
||||
MountableFilesystem();
|
||||
MountableFilesystem(VFS* root, bool owns);
|
||||
void Mount(VFSPath path, VFS* fs, bool owns);
|
||||
void Unmount(VFSPath path);
|
||||
Tesses::Framework::Streams::Stream* OpenFile(VFSPath path, std::string mode);
|
||||
void CreateDirectory(VFSPath path);
|
||||
void DeleteDirectory(VFSPath path);
|
||||
bool SpecialFileExists(VFSPath path);
|
||||
bool FileExists(VFSPath path);
|
||||
bool RegularFileExists(VFSPath path);
|
||||
bool SymlinkExists(VFSPath path);
|
||||
bool CharacterDeviceExists(VFSPath path);
|
||||
bool BlockDeviceExists(VFSPath path);
|
||||
bool SocketFileExists(VFSPath path);
|
||||
bool FIFOFileExists(VFSPath path);
|
||||
bool DirectoryExists(VFSPath path);
|
||||
void DeleteFile(VFSPath path);
|
||||
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||
void GetPaths(VFSPath path, std::vector<VFSPath>& paths);
|
||||
void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||
void MoveFile(VFSPath src, VFSPath dest);
|
||||
void MoveDirectory(VFSPath src, VFSPath dest);
|
||||
VFSPath ReadLink(VFSPath path);
|
||||
std::string VFSPathToSystem(VFSPath path);
|
||||
VFSPath SystemToVFSPath(std::string path);
|
||||
~MountableFilesystem();
|
||||
};
|
||||
}
|
||||
19
include/TessesFramework/Filesystem/NullFilesystem.hpp
Normal file
19
include/TessesFramework/Filesystem/NullFilesystem.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "VFS.hpp"
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class NullFilesystem : public VFS
|
||||
{
|
||||
public:
|
||||
Tesses::Framework::Streams::Stream* OpenFile(VFSPath path, std::string mode);
|
||||
void CreateDirectory(VFSPath path);
|
||||
void DeleteDirectory(VFSPath path);
|
||||
bool RegularFileExists(VFSPath path);
|
||||
bool DirectoryExists(VFSPath path);
|
||||
void DeleteFile(VFSPath path);
|
||||
void GetPaths(VFSPath path, std::vector<VFSPath>& paths);
|
||||
void MoveFile(VFSPath src, VFSPath dest);
|
||||
std::string VFSPathToSystem(VFSPath path);
|
||||
VFSPath SystemToVFSPath(std::string path);
|
||||
};
|
||||
}
|
||||
38
include/TessesFramework/Filesystem/SubdirFilesystem.hpp
Normal file
38
include/TessesFramework/Filesystem/SubdirFilesystem.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "VFS.hpp"
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class SubdirFilesystem : public VFS
|
||||
{
|
||||
bool owns;
|
||||
VFS* parent;
|
||||
VFSPath path;
|
||||
VFSPath ToParent(VFSPath path);
|
||||
VFSPath FromParent(VFSPath path);
|
||||
public:
|
||||
SubdirFilesystem(VFS* parent, VFSPath path, bool owns);
|
||||
Tesses::Framework::Streams::Stream* OpenFile(VFSPath path, std::string mode);
|
||||
void CreateDirectory(VFSPath path);
|
||||
void DeleteDirectory(VFSPath path);
|
||||
bool SpecialFileExists(VFSPath path);
|
||||
bool FileExists(VFSPath path);
|
||||
bool RegularFileExists(VFSPath path);
|
||||
bool SymlinkExists(VFSPath path);
|
||||
bool CharacterDeviceExists(VFSPath path);
|
||||
bool BlockDeviceExists(VFSPath path);
|
||||
bool SocketFileExists(VFSPath path);
|
||||
bool FIFOFileExists(VFSPath path);
|
||||
bool DirectoryExists(VFSPath path);
|
||||
void DeleteFile(VFSPath path);
|
||||
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||
void GetPaths(VFSPath path, std::vector<VFSPath>& paths);
|
||||
void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||
void MoveFile(VFSPath src, VFSPath dest);
|
||||
void MoveDirectory(VFSPath src, VFSPath dest);
|
||||
void DeleteDirectoryRecurse(VFSPath path);
|
||||
VFSPath ReadLink(VFSPath path);
|
||||
std::string VFSPathToSystem(VFSPath path);
|
||||
VFSPath SystemToVFSPath(std::string path);
|
||||
~SubdirFilesystem();
|
||||
};
|
||||
}
|
||||
50
include/TessesFramework/Filesystem/VFS.hpp
Normal file
50
include/TessesFramework/Filesystem/VFS.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
#include "../Streams/Stream.hpp"
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class VFSPath {
|
||||
public:
|
||||
static VFSPath RelativeCurrentDirectory();
|
||||
bool relative;
|
||||
static std::vector<std::string> SplitPath(std::string path,bool native=false);
|
||||
std::vector<std::string> path;
|
||||
VFSPath();
|
||||
VFSPath(std::vector<std::string> path);
|
||||
VFSPath(std::string path);
|
||||
VFSPath(VFSPath p, std::string subent);
|
||||
VFSPath(VFSPath p, VFSPath p2);
|
||||
VFSPath GetParent();
|
||||
VFSPath CollapseRelativeParents();
|
||||
std::string GetFileName();
|
||||
std::string ToString();
|
||||
};
|
||||
class VFS {
|
||||
public:
|
||||
|
||||
virtual Tesses::Framework::Streams::Stream* OpenFile(VFSPath path, std::string mode)=0;
|
||||
virtual void CreateDirectory(VFSPath path)=0;
|
||||
virtual void DeleteDirectory(VFSPath path)=0;
|
||||
virtual bool RegularFileExists(VFSPath path)=0;
|
||||
virtual bool SymlinkExists(VFSPath path);
|
||||
virtual bool CharacterDeviceExists(VFSPath path);
|
||||
virtual bool BlockDeviceExists(VFSPath path);
|
||||
virtual bool SocketFileExists(VFSPath path);
|
||||
virtual bool FIFOFileExists(VFSPath path);
|
||||
virtual bool FileExists(VFSPath path);
|
||||
virtual bool SpecialFileExists(VFSPath path);
|
||||
virtual void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||
virtual void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||
virtual bool DirectoryExists(VFSPath path)=0;
|
||||
virtual void DeleteFile(VFSPath path)=0;
|
||||
virtual void DeleteDirectoryRecurse(VFSPath path);
|
||||
virtual void GetPaths(VFSPath path, std::vector<VFSPath>& paths)=0;
|
||||
virtual void MoveFile(VFSPath src, VFSPath dest)=0;
|
||||
virtual void MoveDirectory(VFSPath src, VFSPath dest);
|
||||
virtual VFSPath ReadLink(VFSPath path);
|
||||
virtual std::string VFSPathToSystem(VFSPath path)=0;
|
||||
virtual VFSPath SystemToVFSPath(std::string path)=0;
|
||||
|
||||
virtual ~VFS();
|
||||
};
|
||||
}
|
||||
13
include/TessesFramework/Http/ContentDisposition.hpp
Normal file
13
include/TessesFramework/Http/ContentDisposition.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
class ContentDisposition {
|
||||
public:
|
||||
std::string filename;
|
||||
std::string type;
|
||||
std::string fieldName;
|
||||
static bool TryParse(std::string str, ContentDisposition& cd);
|
||||
std::string ToString();
|
||||
};
|
||||
}
|
||||
25
include/TessesFramework/Http/FileServer.hpp
Normal file
25
include/TessesFramework/Http/FileServer.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "../Filesystem/VFS.hpp"
|
||||
#include "HttpServer.hpp"
|
||||
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
class FileServer : public IHttpServer
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFS* vfs;
|
||||
bool ownsVFS;
|
||||
|
||||
|
||||
bool SendFile(ServerContext& ctx,Tesses::Framework::Filesystem::VFSPath path);
|
||||
public:
|
||||
bool allowListing;
|
||||
bool spa;
|
||||
std::vector<std::string> defaultNames;
|
||||
FileServer(std::filesystem::path path,bool allowListing,bool spa);
|
||||
FileServer(std::filesystem::path path,bool allowListing, bool spa, std::vector<std::string> defaultNames);
|
||||
FileServer(Tesses::Framework::Filesystem::VFS* fs, bool owns, bool allowListing, bool spa);
|
||||
FileServer(Tesses::Framework::Filesystem::VFS* fs, bool owns, bool allowListing, bool spa, std::vector<std::string> defaultNames);
|
||||
bool Handle(ServerContext& ctx);
|
||||
~FileServer();
|
||||
};
|
||||
}
|
||||
63
include/TessesFramework/Http/HttpClient.hpp
Normal file
63
include/TessesFramework/Http/HttpClient.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "../Streams/Stream.hpp"
|
||||
#include "HttpUtils.hpp"
|
||||
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
|
||||
class HttpRequestBody {
|
||||
public:
|
||||
virtual void HandleHeaders(HttpDictionary& dict);
|
||||
virtual void Write(Tesses::Framework::Streams::Stream* strm)=0;
|
||||
};
|
||||
|
||||
class StreamHttpRequestBody : public HttpRequestBody {
|
||||
Tesses::Framework::Streams::Stream* strm;
|
||||
bool owns;
|
||||
std::string mimeType;
|
||||
public:
|
||||
StreamHttpRequestBody(Tesses::Framework::Streams::Stream* strm, bool owns, std::string mimeType);
|
||||
void HandleHeaders(HttpDictionary& dict);
|
||||
void Write(Tesses::Framework::Streams::Stream* strm);
|
||||
~StreamHttpRequestBody();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class HttpRequest {
|
||||
public:
|
||||
HttpRequest();
|
||||
std::string trusted_root_cert_bundle;
|
||||
bool ignoreSSLErrors;
|
||||
bool followRedirects;
|
||||
|
||||
std::string method;
|
||||
std::string url;
|
||||
HttpDictionary requestHeaders;
|
||||
HttpRequestBody* body;
|
||||
|
||||
static Tesses::Framework::Streams::Stream* EstablishConnection(Uri uri,bool ignoreSSLErrors,std::string trusted_root_cert_bundle);
|
||||
|
||||
void SendRequest(Tesses::Framework::Streams::Stream* strm);
|
||||
};
|
||||
|
||||
class HttpResponse {
|
||||
private:
|
||||
bool owns;
|
||||
Tesses::Framework::Streams::Stream* handleStrm;
|
||||
public:
|
||||
HttpResponse(Tesses::Framework::Streams::Stream* strm, bool owns);
|
||||
HttpResponse(HttpRequest& request);
|
||||
std::string version;
|
||||
StatusCode statusCode;
|
||||
HttpDictionary responseHeaders;
|
||||
std::string ReadAsString();
|
||||
Tesses::Framework::Streams::Stream* ReadAsStream();
|
||||
void CopyToStream(Tesses::Framework::Streams::Stream* strm);
|
||||
|
||||
~HttpResponse();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
70
include/TessesFramework/Http/HttpServer.hpp
Normal file
70
include/TessesFramework/Http/HttpServer.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "../Streams/NetworkStream.hpp"
|
||||
|
||||
#include "HttpUtils.hpp"
|
||||
#include "../Threading/Thread.hpp"
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
|
||||
class ServerContext {
|
||||
bool sent;
|
||||
Tesses::Framework::Streams::Stream* strm;
|
||||
public:
|
||||
HttpDictionary requestHeaders;
|
||||
HttpDictionary responseHeaders;
|
||||
HttpDictionary queryParams;
|
||||
std::string path;
|
||||
std::string originalPath;
|
||||
std::string method;
|
||||
StatusCode statusCode;
|
||||
std::string ip;
|
||||
uint16_t port;
|
||||
std::string version;
|
||||
bool encrypted;
|
||||
ServerContext(Tesses::Framework::Streams::Stream* strm);
|
||||
Tesses::Framework::Streams::Stream& GetStream();
|
||||
std::string GetOriginalPathWithQuery();
|
||||
std::string GetUrlWithQuery();
|
||||
bool Sent();
|
||||
bool NeedToParseFormData();
|
||||
void ParseFormData(std::function<Tesses::Framework::Streams::Stream*(std::string mime, std::string filename, std::string name)> cb);
|
||||
void ReadStream(Tesses::Framework::Streams::Stream& strm);
|
||||
void ReadStream(Tesses::Framework::Streams::Stream* strm);
|
||||
std::string ReadString();
|
||||
void SendBytes(std::vector<uint8_t> buffer);
|
||||
void SendText(std::string text);
|
||||
void SendStream(Tesses::Framework::Streams::Stream& strm);
|
||||
void SendStream(Tesses::Framework::Streams::Stream* strm);
|
||||
void SendErrorPage(bool showPath);
|
||||
void SendNotFound();
|
||||
void SendBadRequest();
|
||||
void SendException(std::exception& ex);
|
||||
Tesses::Framework::Streams::Stream* OpenResponseStream();
|
||||
Tesses::Framework::Streams::Stream* OpenRequestStream();
|
||||
ServerContext& WithHeader(std::string key, std::string value);
|
||||
ServerContext& WithSingleHeader(std::string key, std::string value);
|
||||
ServerContext& WithMimeType(std::string mime);
|
||||
ServerContext& WithContentDisposition(std::string filename, bool isInline);
|
||||
ServerContext& WriteHeaders();
|
||||
};
|
||||
|
||||
class IHttpServer {
|
||||
public:
|
||||
virtual bool Handle(ServerContext& ctx)=0;
|
||||
virtual ~IHttpServer();
|
||||
};
|
||||
|
||||
class HttpServer {
|
||||
Tesses::Framework::Streams::TcpServer* server;
|
||||
IHttpServer* http;
|
||||
Tesses::Framework::Threading::Thread* thrd;
|
||||
bool owns;
|
||||
uint16_t port;
|
||||
public:
|
||||
HttpServer(uint16_t port, IHttpServer& http);
|
||||
HttpServer(uint16_t port, IHttpServer* http, bool owns);
|
||||
void StartAccepting();
|
||||
static void Process(Tesses::Framework::Streams::Stream& strm, IHttpServer& server, std::string ip, uint16_t port, bool encrypted);
|
||||
~HttpServer();
|
||||
};
|
||||
}
|
||||
32
include/TessesFramework/Http/HttpStream.hpp
Normal file
32
include/TessesFramework/Http/HttpStream.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "../Streams/Stream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
class HttpStream : public Tesses::Framework::Streams::Stream {
|
||||
Tesses::Framework::Streams::Stream* strm;
|
||||
|
||||
size_t offset;
|
||||
size_t read;
|
||||
int64_t length;
|
||||
int64_t position;
|
||||
|
||||
bool owns;
|
||||
bool recv;
|
||||
bool http1_1;
|
||||
|
||||
bool done;
|
||||
|
||||
public:
|
||||
HttpStream(Tesses::Framework::Streams::Stream* strm, bool owns, int64_t length, bool recv, bool http1_1);
|
||||
HttpStream(Tesses::Framework::Streams::Stream& strm, int64_t length, bool recv,bool http1_1);
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
bool EndOfStream();
|
||||
int64_t GetLength();
|
||||
int64_t GetPosition();
|
||||
size_t Read(uint8_t* buffer, size_t len);
|
||||
size_t Write(const uint8_t* buffer, size_t len);
|
||||
~HttpStream();
|
||||
};
|
||||
}
|
||||
144
include/TessesFramework/Http/HttpUtils.hpp
Normal file
144
include/TessesFramework/Http/HttpUtils.hpp
Normal file
@ -0,0 +1,144 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
typedef enum StatusCode {
|
||||
Continue=100,
|
||||
SwitchingProtocols=101,
|
||||
Processing=102,
|
||||
EarlyHints=103,
|
||||
OK=200,
|
||||
Created=201,
|
||||
Accepted=202,
|
||||
NonAuthoritativeInformation=203,
|
||||
NoContent=204,
|
||||
ResetContent=205,
|
||||
PartialContent=206,
|
||||
MultiStatus=207,
|
||||
AlreadyReported=208,
|
||||
IMUsed=226,
|
||||
MultipleChoices=300,
|
||||
MovedPermanently=301,
|
||||
Found=302,
|
||||
SeeOther=303,
|
||||
NotModified=304,
|
||||
UseProxy=305,
|
||||
TemporaryRedirect=307,
|
||||
PermanentRedirect=308,
|
||||
BadRequest=400,
|
||||
Unauthorized=401,
|
||||
PaymentRequired=402,
|
||||
Forbidden=403,
|
||||
NotFound=404,
|
||||
MethodNotAllowed=405,
|
||||
NotAcceptable=406,
|
||||
ProxyAuthenticationRequired=407,
|
||||
RequestTimeout=408,
|
||||
Conflict=409,
|
||||
Gone=410,
|
||||
LengthRequired=411,
|
||||
PreconditionFailed=412,
|
||||
PayloadTooLarge=413,
|
||||
URITooLong=414,
|
||||
UnsupportedMediaType=415,
|
||||
RangeNotSatisfiable=416,
|
||||
ExpectationFailed=417,
|
||||
ImATeapot=418,
|
||||
MisdirectedRequest=421,
|
||||
UnprocessableContent=422,
|
||||
Locked=423,
|
||||
FailedDependency=424,
|
||||
TooEarly=425,
|
||||
UpgradeRequired=426,
|
||||
PreconditionRequired=428,
|
||||
TooManyRequests=429,
|
||||
RequestHeaderFieldsTooLarge=431,
|
||||
UnavailableForLegalReasons=451,
|
||||
InternalServerError=500,
|
||||
NotImplemented=501,
|
||||
BadGateway=502,
|
||||
ServiceUnavailable=503,
|
||||
GatewayTimeout=504,
|
||||
HTTPVersionNotSupported=505,
|
||||
VariantAlsoNegotiates=506,
|
||||
InsufficientStorage=507,
|
||||
LoopDetected=508,
|
||||
NotExtended=510,
|
||||
NetworkAuthenticationRequired=511
|
||||
} StatusCode;
|
||||
class HttpDictionary {
|
||||
public:
|
||||
std::map<std::string,std::vector<std::string>> kvp;
|
||||
void Clear();
|
||||
void Clear(std::string key, bool kvpExistsAfter);
|
||||
void SetValue(std::string key, std::string value);
|
||||
void SetValue(std::string key, std::vector<std::string> value);
|
||||
template<typename Itterator>
|
||||
void SetValue(std::string key, Itterator begin, Itterator end)
|
||||
{
|
||||
Clear(key,true);
|
||||
AddValue(key, begin, end);
|
||||
}
|
||||
void AddValue(std::string key, std::string value);
|
||||
void AddValue(std::string key, std::vector<std::string> value);
|
||||
|
||||
template<typename Itterator>
|
||||
void AddValue(std::string key, Itterator begin, Itterator end)
|
||||
{
|
||||
auto& ls = kvp[key];
|
||||
ls.insert(ls.end(), begin, end);
|
||||
}
|
||||
|
||||
bool TryGetFirst(std::string key, std::string& value);
|
||||
|
||||
bool TryGetFirstInt(std::string key, int64_t& value);
|
||||
|
||||
bool TryGetFirstDouble(std::string key, double& value);
|
||||
|
||||
bool GetFirstBoolean(std::string key);
|
||||
};
|
||||
|
||||
class Uri {
|
||||
public:
|
||||
std::string GetQuery();
|
||||
std::string GetPathAndQuery();
|
||||
uint16_t GetPort();
|
||||
std::string HostPort();
|
||||
bool Relative(std::string url, Uri& uri);
|
||||
std::string ToString();
|
||||
static bool TryParse(std::string url, Uri& uri);
|
||||
std::string scheme;
|
||||
std::string host;
|
||||
uint16_t port;
|
||||
std::string path;
|
||||
HttpDictionary query;
|
||||
std::string hash;
|
||||
};
|
||||
|
||||
class HttpUtils
|
||||
{
|
||||
public:
|
||||
static char NibbleToHex(uint8_t nibble);
|
||||
static uint8_t HexToNibble(char c);
|
||||
static std::string MimeType(std::filesystem::path p);
|
||||
static bool Invalid(char c);
|
||||
static std::string Sanitise(std::string text);
|
||||
static void QueryParamsDecode(HttpDictionary& dict,std::string query);
|
||||
static std::string Join(std::string joinStr, std::vector<std::string> ents);
|
||||
static std::string QueryParamsEncode(HttpDictionary& dict);
|
||||
static std::string UrlDecode(std::string v);
|
||||
static std::string UrlEncode(std::string v);
|
||||
static std::string UrlPathDecode(std::string v);
|
||||
static std::string UrlPathEncode(std::string v, bool ignoreSpace=false);
|
||||
static std::string HtmlEncode(std::string v);
|
||||
static std::vector<std::string> SplitString(std::string text, std::string delimiter,std::size_t maxCnt = std::string::npos);
|
||||
static std::string StatusCodeString(StatusCode code);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
27
include/TessesFramework/Streams/BufferedStream.hpp
Normal file
27
include/TessesFramework/Streams/BufferedStream.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "Stream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
class BufferedStream : public Stream
|
||||
{
|
||||
private:
|
||||
Stream* strm;
|
||||
bool owns;
|
||||
uint8_t* buffer;
|
||||
size_t bufferSize;
|
||||
size_t offset;
|
||||
size_t read;
|
||||
public:
|
||||
BufferedStream(Stream* strm, bool owns, size_t bufferSize=1024);
|
||||
BufferedStream(Stream& strm, size_t bufferSize=1024);
|
||||
bool EndOfStream();
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
|
||||
~BufferedStream();
|
||||
};
|
||||
|
||||
}
|
||||
27
include/TessesFramework/Streams/FileStream.hpp
Normal file
27
include/TessesFramework/Streams/FileStream.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "Stream.hpp"
|
||||
#include <cstdio>
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
class FileStream : public Stream {
|
||||
bool canRead;
|
||||
bool canWrite;
|
||||
bool canSeek;
|
||||
bool owns;
|
||||
FILE* f;
|
||||
void SetMode(std::string mode);
|
||||
public:
|
||||
FileStream(std::filesystem::path p, std::string mode);
|
||||
FileStream(FILE* f, bool owns, std::string mode , bool canSeek=true);
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
bool CanSeek();
|
||||
int64_t GetPosition();
|
||||
void Flush();
|
||||
void Seek(int64_t pos, SeekOrigin whence);
|
||||
~FileStream();
|
||||
|
||||
};
|
||||
}
|
||||
22
include/TessesFramework/Streams/MemoryStream.hpp
Normal file
22
include/TessesFramework/Streams/MemoryStream.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "Stream.hpp"
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
class MemoryStream : public Stream {
|
||||
std::vector<uint8_t> buffer;
|
||||
size_t offset;
|
||||
bool writable;
|
||||
public:
|
||||
MemoryStream(bool isWritable);
|
||||
std::vector<uint8_t>& GetBuffer();
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
bool CanSeek();
|
||||
int64_t GetLength();
|
||||
int64_t GetPosition();
|
||||
void Seek(int64_t pos, SeekOrigin whence);
|
||||
|
||||
};
|
||||
}
|
||||
43
include/TessesFramework/Streams/NetworkStream.hpp
Normal file
43
include/TessesFramework/Streams/NetworkStream.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "Stream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
class NetworkStream;
|
||||
|
||||
class TcpServer {
|
||||
int32_t sock;
|
||||
bool owns;
|
||||
bool valid;
|
||||
public:
|
||||
TcpServer(int32_t sock,bool owns);
|
||||
TcpServer(uint16_t port, int32_t backlog);
|
||||
TcpServer(std::string ip, uint16_t port, int32_t backlog);
|
||||
NetworkStream* GetStream(std::string& ip, uint16_t& port);
|
||||
~TcpServer();
|
||||
void Close();
|
||||
};
|
||||
class NetworkStream : public Stream {
|
||||
int32_t sock;
|
||||
bool owns;
|
||||
bool success;
|
||||
bool endOfStream;
|
||||
public:
|
||||
bool EndOfStream();
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
NetworkStream(bool ipV6,bool datagram);
|
||||
NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6);
|
||||
NetworkStream(int32_t sock, bool owns);
|
||||
void Listen(int32_t backlog);
|
||||
void Bind(std::string ip, uint16_t port);
|
||||
void SetBroadcast(bool bC);
|
||||
NetworkStream* Accept(std::string& ip, uint16_t& port);
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
||||
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
||||
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
||||
~NetworkStream();
|
||||
};
|
||||
}
|
||||
31
include/TessesFramework/Streams/Stream.hpp
Normal file
31
include/TessesFramework/Streams/Stream.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
enum class SeekOrigin : uint8_t {
|
||||
Begin=0,
|
||||
Current=1,
|
||||
End=2
|
||||
};
|
||||
class Stream {
|
||||
public:
|
||||
int32_t ReadByte();
|
||||
void WriteByte(uint8_t b);
|
||||
|
||||
virtual bool EndOfStream();
|
||||
virtual size_t Read(uint8_t* buff, size_t sz);
|
||||
virtual size_t Write(const uint8_t* buff, size_t sz);
|
||||
size_t ReadBlock(uint8_t* buff, size_t sz);
|
||||
void WriteBlock(const uint8_t* buff, size_t sz);
|
||||
virtual bool CanRead();
|
||||
virtual bool CanWrite();
|
||||
virtual bool CanSeek();
|
||||
virtual int64_t GetPosition();
|
||||
virtual int64_t GetLength();
|
||||
virtual void Flush();
|
||||
virtual void Seek(int64_t pos, SeekOrigin whence);
|
||||
void CopyTo(Stream* strm, size_t buffSize=1024);
|
||||
void CopyTo(Stream& strm, size_t buffSize=1024);
|
||||
virtual ~Stream();
|
||||
};
|
||||
}
|
||||
17
include/TessesFramework/TessesFramework.hpp
Normal file
17
include/TessesFramework/TessesFramework.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "Http/HttpServer.hpp"
|
||||
#include "Http/HttpClient.hpp"
|
||||
#include "Http/FileServer.hpp"
|
||||
#include "Http/ContentDisposition.hpp"
|
||||
#include "Streams/FileStream.hpp"
|
||||
#include "Streams/MemoryStream.hpp"
|
||||
#include "Streams/NetworkStream.hpp"
|
||||
#include "Streams/BufferedStream.hpp"
|
||||
#include "TextStreams/StreamReader.hpp"
|
||||
#include "TextStreams/StreamWriter.hpp"
|
||||
#include "Threading/Thread.hpp"
|
||||
#include "Filesystem/LocalFS.hpp"
|
||||
#include "Filesystem/SubdirFilesystem.hpp"
|
||||
#include "Filesystem/NullFilesystem.hpp"
|
||||
#include "Filesystem/MountableFilesystem.hpp"
|
||||
#include "Crypto/ClientTLSStream.hpp"
|
||||
19
include/TessesFramework/TextStreams/StreamReader.hpp
Normal file
19
include/TessesFramework/TextStreams/StreamReader.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "TextReader.hpp"
|
||||
#include "../Streams/Stream.hpp"
|
||||
namespace Tesses::Framework::TextStreams
|
||||
{
|
||||
class StreamReader : public TextReader
|
||||
{
|
||||
private:
|
||||
Tesses::Framework::Streams::Stream* strm;
|
||||
bool owns;
|
||||
public:
|
||||
Tesses::Framework::Streams::Stream& GetStream();
|
||||
StreamReader(Tesses::Framework::Streams::Stream& strm);
|
||||
StreamReader(Tesses::Framework::Streams::Stream* strm, bool owns);
|
||||
StreamReader(std::filesystem::path filename);
|
||||
bool ReadBlock(std::string& str,size_t sz);
|
||||
~StreamReader();
|
||||
};
|
||||
}
|
||||
19
include/TessesFramework/TextStreams/StreamWriter.hpp
Normal file
19
include/TessesFramework/TextStreams/StreamWriter.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "../Streams/Stream.hpp"
|
||||
#include "TextWriter.hpp"
|
||||
|
||||
namespace Tesses::Framework::TextStreams
|
||||
{
|
||||
class StreamWriter : public TextWriter {
|
||||
private:
|
||||
Tesses::Framework::Streams::Stream* strm;
|
||||
bool owns;
|
||||
public:
|
||||
Tesses::Framework::Streams::Stream& GetStream();
|
||||
StreamWriter(Tesses::Framework::Streams::Stream& strm);
|
||||
StreamWriter(Tesses::Framework::Streams::Stream* strm, bool owns);
|
||||
StreamWriter(std::filesystem::path filename, bool append=false);
|
||||
void WriteData(const char* text, size_t len);
|
||||
~StreamWriter();
|
||||
};
|
||||
}
|
||||
18
include/TessesFramework/TextStreams/TextReader.hpp
Normal file
18
include/TessesFramework/TextStreams/TextReader.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
#include "TextWriter.hpp"
|
||||
namespace Tesses::Framework::TextStreams
|
||||
{
|
||||
class TextReader
|
||||
{
|
||||
public:
|
||||
virtual bool ReadBlock(std::string& str,size_t sz)=0;
|
||||
int32_t ReadChar();
|
||||
std::string ReadLine();
|
||||
bool ReadLine(std::string& str);
|
||||
std::string ReadToEnd();
|
||||
void ReadToEnd(std::string& str);
|
||||
void CopyTo(TextWriter& writer, size_t bufSz=1024);
|
||||
virtual ~TextReader();
|
||||
};
|
||||
}
|
||||
16
include/TessesFramework/TextStreams/TextWriter.hpp
Normal file
16
include/TessesFramework/TextStreams/TextWriter.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "../Common.hpp"
|
||||
|
||||
namespace Tesses::Framework::TextStreams
|
||||
{
|
||||
class TextWriter {
|
||||
public:
|
||||
TextWriter();
|
||||
std::string newline;
|
||||
virtual void WriteData(const char* text, size_t len)=0;
|
||||
void Write(std::string txt);
|
||||
void WriteLine(std::string txt);
|
||||
void WriteLine();
|
||||
virtual ~TextWriter();
|
||||
};
|
||||
}
|
||||
22
include/TessesFramework/Threading/Mutex.hpp
Normal file
22
include/TessesFramework/Threading/Mutex.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#if defined(GEKKO)
|
||||
#include <ogc/mutex.h>
|
||||
#else
|
||||
#include <threads.h>
|
||||
#endif
|
||||
namespace Tesses::Framework::Threading
|
||||
{
|
||||
class Mutex {
|
||||
#if defined(GEKKO)
|
||||
mutex_t mtx;
|
||||
#else
|
||||
mtx_t mtx;
|
||||
#endif
|
||||
public:
|
||||
Mutex();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool TryLock();
|
||||
~Mutex();
|
||||
};
|
||||
}
|
||||
27
include/TessesFramework/Threading/Thread.hpp
Normal file
27
include/TessesFramework/Threading/Thread.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#if defined(GEKKO)
|
||||
#include <ogc/lwp.h>
|
||||
#else
|
||||
#include <threads.h>
|
||||
#endif
|
||||
#include <atomic>
|
||||
namespace Tesses::Framework::Threading
|
||||
{
|
||||
class Thread
|
||||
{
|
||||
std::atomic<bool> hasInvoked;
|
||||
#if defined(GEKKO)
|
||||
lwp_t thrd;
|
||||
static void* cb(void* ptr);
|
||||
#else
|
||||
thrd_t thrd;
|
||||
static int cb(void* ptr);
|
||||
#endif
|
||||
std::function<void()> fn;
|
||||
public:
|
||||
Thread(std::function<void()> fn);
|
||||
void Join();
|
||||
void Detach();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user