12#include <unordered_map>
19 : m_spApp(app), m_sWebRoot(webRoot), m_sDefaultDocument(
"index.html"), m_bStaticFilesEnabled(true) {
22 throw DotNetDupe::System::ArgumentException(
"WebApplication cannot be null");
27 : m_spApp(std::move(other.m_spApp)),
28 m_sWebRoot(std::move(other.m_sWebRoot)),
29 m_sDefaultDocument(std::move(other.m_sDefaultDocument)),
30 m_bStaticFilesEnabled(other.m_bStaticFilesEnabled) {
37 m_spApp = std::move(other.m_spApp);
38 m_sWebRoot = std::move(other.m_sWebRoot);
39 m_sDefaultDocument = std::move(other.m_sDefaultDocument);
40 m_bStaticFilesEnabled = other.m_bStaticFilesEnabled;
48 m_bStaticFilesEnabled =
true;
49 m_sDefaultDocument = defaultDocument;
56 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
57 if (s.rfind(
'.', 0) == 0) s = s.substr(1);
60 static const std::unordered_map<std::string, const char*> mimeMap = {
61 {
"html",
"text/html; charset=utf-8"}, {
"htm",
"text/html; charset=utf-8"},
62 {
"css",
"text/css; charset=utf-8"}, {
"js",
"application/javascript; charset=utf-8"},
63 {
"json",
"application/json; charset=utf-8"}, {
"png",
"image/png"},
64 {
"jpg",
"image/jpeg"}, {
"jpeg",
"image/jpeg"}, {
"gif",
"image/gif"},
65 {
"svg",
"image/svg+xml"}, {
"ico",
"image/x-icon"}, {
"txt",
"text/plain; charset=utf-8"},
66 {
"pdf",
"application/pdf"}, {
"woff",
"font/woff"}, {
"woff2",
"font/woff2"}
68 auto it = mimeMap.find(s);
70 return (it != mimeMap.end()) ? it->second :
"application/octet-stream";
76 if (!rel.empty() && (rel[0] ==
'/' || rel[0] ==
'\\')) rel = rel.substr(1);
78 if (rel.find(
"..") != std::string::npos)
return "";
94 spContext->GetResponse()->SetStatusCode(403); spContext->GetResponse()->SetContentType(
"text/plain");
95 return "403 Forbidden: Invalid file path";
99 spContext->GetResponse()->SetStatusCode(404); spContext->GetResponse()->SetContentType(
"text/plain");
100 return "404 Not Found";
105 spContext->GetResponse()->SetStatusCode(200);
107 spContext->GetResponse()->GetHeaders()[
"Content-Disposition"] =
"inline";
110 spContext->GetResponse()->SetStatusCode(500); spContext->GetResponse()->SetContentType(
"text/plain");
111 return "500 Internal Server Error: Unable to open file";
117 if (spApp->HasWebSocketRoute(ctx->GetRequest()->GetPath())) {
118 ctx->GetResponse()->SetStatusCode(426);
119 ctx->GetResponse()->SetContentType(
"text/plain");
120 ctx->GetResponse()->GetHeaders()[
"Upgrade"] =
"websocket";
121 ctx->GetResponse()->GetHeaders()[
"Connection"] =
"Upgrade";
122 return "426 Upgrade Required";
130 if (m_bStaticFilesEnabled) {
136 m_spApp->Run(url, threadCount);
Defines the exception thrown when an invalid argument is provided to a method.
Represents standard input, output, and error streams for console applications.
Provides static methods for the creation, copying, deletion, moving, and opening of a single file.
HTTP request, response, and context abstractions for WebAppCore processing pipelines.
Static file web server and application hosting wrapper for WebApplication.
static bool GetAttributes(const String &sPath, FileAttributes &attrAttributes)
static bool Exists(const String &sPath)
Determines whether the specified file exists.
static String ReadAllText(const String &sPath)
Opens a text file, reads all the text in the file, and then closes the file.
static String GetExtension(const String &sFilePath)
Returns the extension of the specified path string.
static String Combine(const std::initializer_list< String > sPaths)
Combines an array of strings into a path.
A unified smart pointer that supports both unique and shared ownership semantics.
bool IsNull() const noexcept
Checks if the SmartPointer is null.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
const char * GetRawString() const
WebAppServer(const DotNetDupe::System::SmartPointer< Builder::WebApplication > &app, const DotNetDupe::System::String &webRoot="wwwroot")
Constructs a WebAppServer wrapping the specified WebApplication host and web root path.
static DotNetDupe::System::String GetMimeType(const DotNetDupe::System::String &filePath)
Resolves the standard MIME content type string based on a file path extension.
WebAppServer & operator=(const WebAppServer &)=delete
void EnableStaticFiles(const DotNetDupe::System::String &defaultDocument="index.html")
Enables static file serving with the specified default document fallback.
void Stop()
Stops the running web server and active TCP listener.
void Run(const DotNetDupe::System::String &url="http://localhost:8080/index.html", int threadCount=10)
Starts the underlying WebApplication server listener on the specified URL and thread pool size.
FileAttributes
Provides attributes for files and directories.
static DotNetDupe::System::String HandleStaticRouteOrWebSocket(const DotNetDupe::System::SmartPointer< Builder::WebApplication > &spApp, const DotNetDupe::System::SmartPointer< Http::HttpContext > &ctx, const DotNetDupe::System::String &webRoot, const DotNetDupe::System::String &defaultDoc)
static DotNetDupe::System::String ServeStaticFile(DotNetDupe::System::SmartPointer< Http::HttpContext > spContext, const DotNetDupe::System::String &webRoot, const DotNetDupe::System::String &defaultDoc)
static DotNetDupe::System::String ResolveStaticPath(const DotNetDupe::System::String &reqPath, const DotNetDupe::System::String &webRoot, const DotNetDupe::System::String &defaultDoc)