diff --git a/CMakeLists.txt b/CMakeLists.txt index 2569751..394c81b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ add_library(unswsc SHARED SafeRNG.cpp # 安全随机数生成器 HTTPObjects.cpp # webcc对象包装兼容层 PathTraversal.cpp # 路径穿越防御 + TempFileManager.cpp # 临时文件管理器 ) # target_link_libraries(unswsc PRIVATE stduuid) diff --git a/CORSProcessor.cpp b/CORSProcessor.cpp index dc83165..eafd8e4 100644 --- a/CORSProcessor.cpp +++ b/CORSProcessor.cpp @@ -82,13 +82,13 @@ uns::ResponsePtr CORSProcessor::Processor(uns::RequestPtr request) std::string host = request->HasHeader("Host") ? request->GetHeader("Host") : ""; if ((!host.empty()) && (!GlobalCORSConfig.HostValidate(host))) { - SCLOG_WARNING("Rejected by Host check: %s", host.c_str()); + SCLOGF_WARNING("Rejected by Host check: {}", host); return uns::ResponseBuilder().Forbidden().EmptyBody()(); } if(!GlobalCORSConfig.UrlValidate(origin)) { - SCLOG_WARNING("Invalid CORS Origin: %s", origin.c_str()); + SCLOGF_WARNING("Invalid CORS Origin: {}", origin); return uns::ResponseBuilder().Forbidden().EmptyBody()(); } @@ -101,7 +101,7 @@ uns::ResponsePtr CORSProcessor::Processor(uns::RequestPtr request) for(const auto& method : acrm_values) if(!GlobalCORSConfig.IsMethodAllowed(method)) { - SCLOG_WARNING("Invalid CORS Method: %s (All Methods: %d)", method.c_str(), acrm.c_str()); + SCLOGF_WARNING("Invalid CORS Method: {} (All Methods: {})", method, acrm); return uns::ResponseBuilder().NotAcceptable().EmptyBody()(); } @@ -120,7 +120,7 @@ uns::ResponsePtr CORSProcessor::Processor(uns::RequestPtr request) auto valid_headers = GlobalCORSConfig.GetValidateHeaders(acrh_values); if((!acrh_values.empty()) && valid_headers.empty()) { - SCLOG_WARNING("Invalid CORS Header(s): %s", acrh.c_str()); + SCLOGF_WARNING("Invalid CORS Header(s): {}", acrh); return uns::ResponseBuilder().NotAcceptable().EmptyBody()(); } @@ -131,7 +131,7 @@ uns::ResponsePtr CORSProcessor::Processor(uns::RequestPtr request) return uns::ResponseBuilder().Forbidden().EmptyBody()(); } - SCLOG_INFO("CORS preflight allow origin=%s methods=%s headers=%s cred=%d", origin.c_str(), allow_methods_value.c_str(), valid_headers.c_str(), GlobalCORSConfig.AllowCookie() ? 1 : 0); + SCLOGF_INFO("CORS preflight allow origin={} methods={} headers={} cred={}", origin, allow_methods_value, valid_headers, GlobalCORSConfig.AllowCookie() ? 1 : 0); return uns::ResponseBuilder().CORS_Full(origin, acrh_values).NoContent().EmptyBody()(); } diff --git a/DataTransfer.cpp b/DataTransfer.cpp index 1dd2d69..f04afc4 100644 --- a/DataTransfer.cpp +++ b/DataTransfer.cpp @@ -10,7 +10,7 @@ DataTransfer::DataTransfer(const std::string& tr) void DataTransfer::Init(const std::string& tr) { temp_root = tr; - SCLOG_DEBUG("GDT-TempRoot: %s", temp_root.c_str()); + SCLOGF_DEBUG("GDT-TempRoot: {}", temp_root); } bool DataTransfer::ItemExist(const std::string& file) @@ -23,7 +23,7 @@ bool DataTransfer::InsertItem(const std::string& file) if (ItemExist(file)) return false; files.insert({ file, true }); - SCLOG_INFO("GDT: Item [%s] Inserted", file.c_str()); + SCLOGF_INFO("GDT: Item [{}] Inserted", file); return true; } @@ -32,7 +32,7 @@ bool DataTransfer::RemoveItem(const std::string& file) if (!ItemExist(file)) return false; files.erase(file); - SCLOG_INFO("GDT: Item [%s] Removed", file.c_str()); + SCLOGF_INFO("GDT: Item [{}] Removed", file); return true; } @@ -48,7 +48,7 @@ void DataTransfer::DeactivateItem(const std::string& file) if (!ItemExist(file)) return; files[file] = false; - SCLOG_INFO("GDT: Item [%s] Deactivated", file.c_str()); + SCLOGF_INFO("GDT: Item [{}] Deactivated", file); } bool DataTransfer::CopyItemTo(const std::string& file, const std::string& dest_path) @@ -59,19 +59,19 @@ bool DataTransfer::CopyItemTo(const std::string& file, const std::string& dest_p std::error_code error; if(!fs::exists(dest_path)) { - SCLOG_ERROR("GDT: Can't Copy File (Target Path [%s] Not Exist)", dest_path.c_str()); + SCLOGF_ERROR("GDT: Can't Copy File (Target Path [{}] Not Exist)", dest_path); return false; } fs::path dest(dest_path); fs::path dest_file = dest / file; if(fs::copy_file(MakePath(file), dest_file, fs::copy_options::overwrite_existing, error)) { - SCLOG_INFO("GDT: File Copied To [%s]", dest_file.c_str()); + SCLOGF_INFO("GDT: File Copied To [{}]", dest_file); return true; } else { - SCLOG_ERROR("Failed To Delete File [%s], Error: %s (%d)", dest_file.c_str(), error.message().c_str(), error.value()); + SCLOGF_ERROR("Failed To Delete File [{}], Error: {} ({})", dest_file, error.message(), error.value()); return false; } } @@ -85,12 +85,12 @@ bool DataTransfer::CopyItemAS(const std::string& file, const std::string& dest) fs::path dest_file = dest; if(fs::copy_file(MakePath(file), dest_file, fs::copy_options::overwrite_existing, error)) { - SCLOG_INFO("GDT: File Copied To [%s]", dest_file.c_str()); + SCLOGF_INFO("GDT: File Copied To [{}]", dest_file); return true; } else { - SCLOG_ERROR("Failed To Delete File [%s], Error: %s (%d)", dest_file.c_str(), error.message().c_str(), error.value()); + SCLOGF_ERROR("Failed To Delete File [{}], Error: {} ({})", dest_file, error.message(), error.value()); return false; } } @@ -111,14 +111,14 @@ bool DataTransfer::RemoveAllCacheFiles() std::string filepath = MakePath(file); if (!fs::exists(filepath, error)) { - SCLOG_WARNING("File [%s] Not Exist, Skip", filepath.c_str()); + SCLOGF_WARNING("File [{}] Not Exist, Skip", filepath); continue; } if (fs::remove(filepath, error)) - SCLOG_INFO("File [%s] Deleted", filepath.c_str()); + SCLOGF_INFO("File [{}] Deleted", filepath); else { - SCLOG_ERROR("Failed To Delete File [%s], Error: %s (%d)", filepath.c_str(), error.message().c_str(), error.value()); + SCLOGF_ERROR("Failed To Delete File [{}], Error: {} ({})", filepath, error.message(), error.value()); result = false; } } @@ -137,14 +137,14 @@ fs_scan: if (fs::remove_all(entry.path(), error)) { dirs_deleted++; - SCLOG_WARNING("Found Directory [%s] In Cache Directory, Deleted", entry.path().string().c_str()); + SCLOGF_WARNING("Found Directory [{}] In Cache Directory, Deleted", entry.path().string()); } else - SCLOG_ERROR("Found Directory [%s] In Cache Directory, Failed To Delete. Error: %s (%d)", entry.path().string().c_str(), error.message().c_str(), error.value()); + SCLOGF_ERROR("Found Directory [{}] In Cache Directory, Failed To Delete. Error: {} ({})", entry.path().string(), error.message(), error.value()); } catch (const std::exception& e) { - SCLOG_ERROR("Found Directory [%s] In Cache Directory, Failed To Delete. Exception: %s", entry.path().string().c_str(), e.what()); + SCLOGF_ERROR("Found Directory [{}] In Cache Directory, Failed To Delete. Exception: {}", entry.path().string(), e.what()); } } else if (entry.is_regular_file()) @@ -153,16 +153,16 @@ fs_scan: if (fs::remove(entry.path(), error)) { files_deleted++; - SCLOG_INFO("File [%s] Deleted", entry.path().string().c_str()); + SCLOGF_INFO("File [{}] Deleted", entry.path().string()); } else { - SCLOG_ERROR("Failed To Delete File [%s], Error: %s (%d)", entry.path().string().c_str(), error.message().c_str(), error.value()); + SCLOGF_ERROR("Failed To Delete File [{}], Error: {} ({})", entry.path().string(), error.message(), error.value()); result = false; } } } - SCLOG_INFO("Filesystem Scan Finished, %d/%d Dir(s) And %d/%d Files(s) Deleted", dirs_deleted, dirs, files_deleted, files); + SCLOGF_INFO("Filesystem Scan Finished, {}/{} Dir(s) And {}/{} Files(s) Deleted", dirs_deleted, dirs, files_deleted, files); SCLOG_INFO("Cache Clear Finished"); return result; } diff --git a/FileReceiver.cpp b/FileReceiver.cpp index 4ae6033..42932e2 100644 --- a/FileReceiver.cpp +++ b/FileReceiver.cpp @@ -13,8 +13,10 @@ public: bool HTMLResponse = false; std::string TempRoot; IPTablePtr BlockedIPs = nullptr; - WebFileInfoVec FileInfo; + TempFileManager FileManager; FileProcessorCallback Callback = nullptr; + std::jthread FileProcesser; + std::chrono::seconds FileTimeout = 300s, FileMaxProcTimeout = 600s; }; FileReceiver::FileReceiver() : pimpl(std::make_unique()) @@ -27,11 +29,11 @@ bool FileReceiver::CallFileProcesser() { if (pimpl->Callback == nullptr) return false; - std::thread thFileProcesser(pimpl->Callback, pimpl->FileInfo, pimpl->TempRoot); //Use copy construst to avoid repeat data process. - if (!thFileProcesser.joinable()) + pimpl->FileProcesser = std::jthread(pimpl->Callback, std::ref(pimpl->FileManager), pimpl->TempRoot); + if (!pimpl->FileProcesser.joinable()) return false; - thFileProcesser.detach(); - pimpl->FileInfo.clear(); + pimpl->FileProcesser.detach(); + //pimpl->FileInfo.clear(); SCLOGF_TRACE("FileProcesser Function (Address: {}) Started.", pimpl->Callback); return true; } @@ -39,19 +41,19 @@ bool FileReceiver::CallFileProcesser() void FileReceiver::SetResponseMode(bool html) { pimpl->HTMLResponse = html; - SCLOG_DEBUG("FileReceiver init mode: %s", (html ? "html" : "json")); + SCLOGF_DEBUG("FileReceiver init mode: {}", (html ? "html" : "json")); } void FileReceiver::SetCORSEnable(bool enable) { pimpl->EnableCORS = enable; - SCLOG_DEBUG("FileReceiver CORS mode: %s", (enable ? "enabled" : "disabled")); + SCLOGF_DEBUG("FileReceiver CORS mode: {}", (enable ? "enabled" : "disabled")); } void FileReceiver::SetTempRoot(std::string temp_root) { pimpl->TempRoot = temp_root; - SCLOG_TRACE("FR-TempRoot: %s", pimpl->TempRoot.c_str()); + SCLOGF_TRACE("FR-TempRoot: {}", pimpl->TempRoot); return; } @@ -73,7 +75,7 @@ void FileReceiver::AppenedBlockedIP(DateTime::Span block_time, std::string ip) IPList li{ ip }; pimpl->BlockedIPs->Appened(expr_time, li); pimpl->BlockedIPs->Update(); - SCLOG_INFO("IP: [%s] has been blocked untill {%s}", ip.c_str(), std::string(expr_time).c_str()); + SCLOGF_INFO("IP: [{}] has been blocked untill {{{}}}", ip, std::string(expr_time)); return; } @@ -108,13 +110,24 @@ bool FileReceiver::WriteFile(const std::string& path, const std::string& bytes) std::ofstream stream{ path, std::ios::binary }; if (stream.fail()) { - SCLOG_WARNING("Failed to write file [%s]: can't open stream", path.c_str()); + SCLOGF_WARNING("Failed to write file [{}]: can't open stream", path); return false; } stream.write(bytes.data(), bytes.size()); - if (stream.fail()) - SCLOG_WARNING("Failed to write file [%s]: can't write to stream", path.c_str()); - return !stream.fail(); + bool fail = stream.fail(); + if (fail) + SCLOGF_WARNING("Failed to write file [{}]: can't write to stream", path); + else + SCLOGF_TRACE("Wrote {siz-b} to file [{}]", bytes.size(), path); + return !fail; +} + +void FileReceiver::SetFileTimeout(std::chrono::seconds timeout, std::chrono::seconds max_proc_timeout) noexcept +{ + if (timeout.count() > 0) + pimpl->FileTimeout = timeout; + if (max_proc_timeout.count() > 0) + pimpl->FileMaxProcTimeout = max_proc_timeout; } uns::PathTraversalDefenceLevel FileReceiver::PTDefence() @@ -128,20 +141,36 @@ bool FileReceiver::IsPathSafe(const std::string& raw_path) return false; } +bool FileReceiver::IsHeaderValid(uns::RequestPtr request) +{ + return true; +} + std::string FileReceiver::EncodeUploadResult() { - Json::Value root; - Json::FastWriter writer; - root["AcceptedCount"] = pimpl->FileInfo.size(); - root["AcceptedFiles"] = Json::Value(Json::arrayValue); - for (auto& ele : pimpl->FileInfo) + try { - Json::Value sub; - sub["FileName"] = ele.GetStorageFileName(); - sub["UploadTime"] = ele.GetUploadTime().GetTimeStamp(); - root["AcceptedFiles"].append(sub); + Json::Value root; + Json::FastWriter writer; + // 1. 从管理器安全获取当前所有文件的快照 + auto file_infos = pimpl->FileManager.GetAllFileInfos(); + // 2. 组装 JSON 数据 + root["AcceptedCount"] = static_cast(file_infos.size()); + root["AcceptedFiles"] = Json::Value(Json::arrayValue); + for (const auto& ele : file_infos) + { + Json::Value sub; + sub["FileName"] = ele.GetStorageFileName(); + sub["UploadTime"] = ele.GetUploadTime().GetTimeStamp(); + root["AcceptedFiles"].append(sub); + } + return writer.write(root); + } + catch (...) + { + // 极致异常安全兜底:如果 Json 报错或内存写满,返回一个合法的空 JSON 字符串 + return "{\"AcceptedCount\":0,\"AcceptedFiles\":[]}"; } - return writer.write(root); } std::string FileReceiver::EncodeUploadResultHTML() @@ -162,16 +191,32 @@ std::string FileReceiver::EncodeUploadResultHTML() )"; - std::string tmp; - for (auto& ele : pimpl->FileInfo) - tmp += "[" + ele.GetStorageFileName() + "] - {" + ele.GetUploadTime().Format("%Y-%m-%d %H:%M:%S") + "}
"; - size_t html_size = strlen(html) + tmp.size() + 10; - char* result = new char[html_size]; - memset(result, 0, sizeof(result)); - sprintf(result, html, pimpl->FileInfo.size(), tmp.c_str()); - tmp = std::string(result); - delete[] result; - return tmp; + try + { + // 1. 获取文件快照 + auto file_infos = pimpl->FileManager.GetAllFileInfos(); + // 2. 拼接文件列表 HTML + std::string tmp; + for (const auto& ele : file_infos) + tmp += "[" + ele.GetStorageFileName() + "] - {" + ele.GetUploadTime().Format("%Y-%m-%d %H:%M:%S") + "}
"; + // 3. 动态安全计算所需缓冲区大小(32字节用于容纳 %lld 的数字展开) + size_t html_size = strlen(html) + tmp.size() + 32; + // 利用 std::string 管理缓冲区内存(RAII 机制,无论发生什么都会自动释放,绝不泄漏) + std::string result_str(html_size, '\0'); + // 使用安全的 snprintf 写入 string 内部缓冲区 + int written = snprintf(result_str.data(), result_str.size(), html, static_cast(file_infos.size()), tmp.c_str()); + if (written > 0) + { + result_str.resize(written); // 裁剪掉尾部多余的 \0 + return result_str; + } + return "HTML generation failed"; + } + catch (...) + { + // 异常安全兜底 + return "

Upload Result Error

"; + } } uns::ResponsePtr FileReceiver::Execute(uns::RequestPtr request) @@ -181,7 +226,7 @@ uns::ResponsePtr FileReceiver::Execute(uns::RequestPtr request) if(request->GetImpl()->webcc_req->HasHeader("X-Real-IP")) x_real_ip = request->GetImpl()->webcc_req->GetHeader("X-Real-IP"); std::string req_ip = (x_real_ip.empty() ? request->GetImpl()->webcc_req->address() : x_real_ip); - SCLOG_DEBUG("Request recived, ip: [%s], method: %s", req_ip.c_str(), request->GetImpl()->webcc_req->method().c_str()); + SCLOGF_DEBUG("Request recived, ip: [{}], method: {}", req_ip, request->GetImpl()->webcc_req->method()); // path test std::string path = request->GetImpl()->webcc_req->url().path(); auto status = PathTraversal::AnalyzeUrlTraversal(path); @@ -245,7 +290,9 @@ uns::ResponsePtr FileReceiver::Execute(uns::RequestPtr request) SCLOGF_DEBUG("File recived: [{}], {} bytes", form->GetFileName(), form->GetDataSize()); WebFileInfo info(form->GetFileNameS(), form->GetDataSize()); WriteFile(info.MakePath(pimpl->TempRoot), form->GetData()); - pimpl->FileInfo.push_back(info); + //pimpl->FileInfo.push_back(info); + if (!pimpl->FileManager.RegisterFile(info, pimpl->FileTimeout, pimpl->FileMaxProcTimeout)) + SCLOGF_WARNING("FileManager.RegisterFile Error, File: {}, TempRoot: {}", form->GetFileName(), pimpl->TempRoot); } std::string resp_body = (pimpl->HTMLResponse ? EncodeUploadResultHTML() : EncodeUploadResult()); CallFileProcesser(); diff --git a/FileReceiver.h b/FileReceiver.h index e1b782a..6d95641 100644 --- a/FileReceiver.h +++ b/FileReceiver.h @@ -2,10 +2,10 @@ #include "Global.h" #include "IPTable.h" #include -#include "WebFileInfo.h" #include "HTTPObjects.h" +#include "TempFileManager.h" -using FileProcessorCallback = std::function; +using FileProcessorCallback = std::function; class UNSWSC_DLL_EXPORT FileReceiver { @@ -29,12 +29,19 @@ public: uns::HTTPMethod GetMethod(uns::RequestPtr request); void AppenedBlockedIP(DateTime::Span block_time, std::string ip); bool WriteFile(const std::string& path, const std::string& bytes); + void SetFileTimeout(std::chrono::seconds timeout = 0s, std::chrono::seconds max_proc_timeout = 0s) noexcept; public: + // 请求信息预检,重载以在保存文件之前检查请求体 virtual uns::Status PreCheckRequest(uns::RequestPtr request) = 0; + // 表单预检,重载以在处理表单前检查表单 virtual bool PreCheckForm(uns::FormPartPtr form) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); public: // 核心驱动入口:供内部适配器调用的实际执行流 diff --git a/Global.cpp b/Global.cpp index 0e6c70b..704915a 100644 --- a/Global.cpp +++ b/Global.cpp @@ -167,7 +167,7 @@ std::string uns::tools::ToLower(const std::string& s) return r; } -std::string uns::tools::CalculateFileHashSHA256(const std::string & file) +std::string uns::tools::CalculateFileHashSHA256(const std::string& file) { // 1. 以二进制模式打开文件 std::ifstream ifs(file, std::ios::binary); @@ -175,7 +175,7 @@ std::string uns::tools::CalculateFileHashSHA256(const std::string & file) return std::string(); // 2. 初始化 OpenSSL EVP 上下文,使用智能指针自动管理内存释放 std::unique_ptr ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free); - if (!ctx) + if (!ctx) return std::string(); // 3. 指定使用 SHA256 算法 if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr) != 1) @@ -205,7 +205,100 @@ std::string uns::tools::CalculateFileHashSHA256(const std::string & file) return hex_result; } -bool uns::secure::IsSafePath(const std::string & safe_path, const std::string & requested_path) +Json::Value uns::tools::SafeJsonDecode(const std::string& str) +{ + try + { + Json::Value root; + Json::Reader reader; + if (!reader.parse(str, root, false)) + return Json::nullValue; + else + return root; + } + catch (...) + { + return Json::nullValue; + } +} + +namespace +{ + template inline constexpr bool always_false_v = false; + + template + T do_sto(const std::basic_string& str, std::size_t* pos, int base) + { + if constexpr (std::is_same_v) + return std::stoi(str, pos, base); + else if constexpr (std::is_same_v) + return std::stol(str, pos, base); + else if constexpr (std::is_same_v) + return std::stoll(str, pos, base); + else if constexpr (std::is_same_v) + return std::stoul(str, pos, base); + else if constexpr (std::is_same_v) + return std::stoull(str, pos, base); + else if constexpr (std::is_same_v) + return std::stof(str, pos); + else if constexpr (std::is_same_v) + return std::stod(str, pos); + else if constexpr (std::is_same_v) + return std::stold(str, pos); + else + static_assert(always_false_v, "不支持的转换类型!"); + } +} + +template +std::optional uns::tools::SafeStoX(const std::basic_string& str, std::size_t* pos, int base) +{ + try + { + return do_sto(str, pos, base); + } + catch (...) + { + return std::nullopt; + } +} + +template +std::optional uns::tools::SafeStoX(std::basic_string_view str, std::size_t* pos, int base) +{ + return SafeStoX(std::basic_string(str), pos, base); +} + +bool uns::secure::IsSafePath(const std::string& safe_path, const std::string& requested_path) { return PathTraversal::IsSafePath(safe_path, requested_path); } + +namespace uns +{ + namespace tools + { + // ------------------------------------------------------------- + // 显式模板实例化(注意:必须放在命名空间内部!) + // ------------------------------------------------------------- +#define INSTANTIATE_SAFE_STO(T, CharT) \ + template std::optional UNSWSC_DLL_EXPORT SafeStoX(const std::basic_string&, std::size_t*, int); \ + template std::optional UNSWSC_DLL_EXPORT SafeStoX(std::basic_string_view, std::size_t*, int); + +#define INSTANTIATE_ALL_NUMERIC_TYPES(CharT) \ + INSTANTIATE_SAFE_STO(int, CharT) \ + INSTANTIATE_SAFE_STO(long, CharT) \ + INSTANTIATE_SAFE_STO(long long, CharT) \ + INSTANTIATE_SAFE_STO(unsigned long, CharT) \ + INSTANTIATE_SAFE_STO(unsigned long long, CharT) \ + INSTANTIATE_SAFE_STO(float, CharT) \ + INSTANTIATE_SAFE_STO(double, CharT) \ + INSTANTIATE_SAFE_STO(long double, CharT) + + INSTANTIATE_ALL_NUMERIC_TYPES(char) + INSTANTIATE_ALL_NUMERIC_TYPES(wchar_t) + +#undef INSTANTIATE_ALL_NUMERIC_TYPES +#undef INSTANTIATE_SAFE_STO + } +} diff --git a/Global.h b/Global.h index 21cb029..f8c32c1 100644 --- a/Global.h +++ b/Global.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "Export.h" #include "DateTime.h" @@ -35,6 +36,11 @@ constexpr auto G_ERROR_PAGE = R"( // inline constexpr std::string_view G_HTTP_STD_WEEK[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +namespace Json +{ + class Value; +} + namespace uns { enum HTTPMethod @@ -65,6 +71,8 @@ namespace uns inline constexpr std::string_view resh_acma = "Access-Control-Max-Age"; }; + inline constexpr auto url_all = R"(/[\s\S]*)"; + using POSTArgs = std::map; std::string UNSWSC_DLL_EXPORT EncodeErrorPage(int code); @@ -93,6 +101,23 @@ namespace uns std::string UNSWSC_DLL_EXPORT ToLower(const std::string& s); std::string UNSWSC_DLL_EXPORT CalculateFileHashSHA256(const std::string& file); + + Json::Value UNSWSC_DLL_EXPORT SafeJsonDecode(const std::string& str); + + template + std::optional UNSWSC_DLL_EXPORT SafeStoX(const std::basic_string& str, std::size_t* pos = nullptr, int base = 10); + template + std::optional UNSWSC_DLL_EXPORT SafeStoX(std::basic_string_view str, std::size_t* pos = nullptr, int base = 10); + template + inline std::optional SafeStoX(const CharT* str, std::size_t* pos = nullptr, int base = 10) + { +#if defined(__cpp_char8_t) + if constexpr (std::is_same_v) + return SafeStoX(std::basic_string(reinterpret_cast(str)), pos, base); // 只有 u8"..." (char8_t) 强制转为 char 版本的 SafeStoX 处理 + else +#endif + return SafeStoX(std::basic_string(str), pos, base); // 普通 "..." (char) 和 L"..." (wchar_t) 保持各自类型,构造对应的 basic_string + } } namespace secure @@ -103,7 +128,7 @@ namespace uns * @param requested_path 客户端传入的、解码后的目标子路径 * @return true 安全(在沙盒内);false 不安全(企图穿越或路径非法) */ - bool IsSafePath(const std::string& safe_path, const std::string& requested_path); + bool IsSafePath(const std::string& safe_path, const std::string& requested_path); } }; diff --git a/LogArg.h b/LogArg.h index 53f7af5..11b0e43 100644 --- a/LogArg.h +++ b/LogArg.h @@ -6,6 +6,7 @@ #include #include "Export.h" #include +#include #include #include @@ -217,6 +218,8 @@ namespace uns else if constexpr (std::is_pointer_v) value = static_cast(val); // 7. 标准库容器(关键点:利用 Lambda 闭包在不引入 fmt 的情况下擦除容器类型!) + else if constexpr (std::is_same::value) + value = ConvertWStringToUtf8(val.generic_wstring()); else if constexpr (is_container::value) { value = RangeCapturer{ &val, [] (const void* p, std::vector& out) diff --git a/ProcessorAdapter.h b/ProcessorAdapter.h index 1d03cf7..78bc0cf 100644 --- a/ProcessorAdapter.h +++ b/ProcessorAdapter.h @@ -33,7 +33,7 @@ namespace uns } // 完美的把 webcc 的驱动流,翻译给用户的纯净业务类 - webcc::ResponsePtr Handle(webcc::RequestPtr request) final + webcc::ResponsePtr Handle(webcc::RequestPtr request) override final { try { @@ -53,7 +53,7 @@ namespace uns return uns::ResponseBuilder().InternalServerError()()->GetImpl()->webcc_res; //Default 500 } - bool Stream(const std::string& method) final + bool Stream(const std::string& method) override final { try { @@ -70,7 +70,25 @@ namespace uns return false; //Default false } - void ApplyIpUpdate(IPTablePtr blocked_ips) override + bool ValidateHeader(webcc::RequestPtr request) override final + { + try + { + auto uns_req = uns::RequestPtr(new uns::Request(std::make_unique(request))); + return user_processor->IsHeaderValid(uns_req); + } + catch (const std::exception& e) + { + SCLOGF_ERROR("Unhandled Exception in ServerProcessorAdapter(ValidateHeader): {}", e.what()); + } + catch (...) + { + SCLOGF_FATAL("Unhandled Unknown Exception in ServerProcessorAdapter(ValidateHeader)"); + } + return true; //Default true + } + + void ApplyIpUpdate(IPTablePtr blocked_ips) override final { try { @@ -98,7 +116,7 @@ namespace uns } // 完美的把 webcc 的驱动流,翻译给用户的纯净业务类 - webcc::ResponsePtr Handle(webcc::RequestPtr request) final + webcc::ResponsePtr Handle(webcc::RequestPtr request) override final { try { @@ -118,13 +136,31 @@ namespace uns return uns::ResponseBuilder().InternalServerError()()->GetImpl()->webcc_res; //Default 500 } - bool Stream(const std::string& method) final + bool Stream(const std::string& method) override final { // 所有数据都不能由webcc进行串流,否则将无法从request中获取文件 return false; } - void ApplyIpUpdate(IPTablePtr blocked_ips) override + bool ValidateHeader(webcc::RequestPtr request) override final + { + try + { + auto uns_req = uns::RequestPtr(new uns::Request(std::make_unique(request))); + return user_reciver->IsHeaderValid(uns_req); + } + catch (const std::exception& e) + { + SCLOGF_ERROR("Unhandled Exception in FileReceiverAdapter(ValidateHeader): {}", e.what()); + } + catch (...) + { + SCLOGF_FATAL("Unhandled Unknown Exception in FileReceiverAdapter(ValidateHeader)"); + } + return true; //Default true + } + + void ApplyIpUpdate(IPTablePtr blocked_ips) override final { try { @@ -152,7 +188,7 @@ namespace uns } // 完美的把 webcc 的驱动流,翻译给用户的纯净业务类 - webcc::ResponsePtr Handle(webcc::RequestPtr request) final + webcc::ResponsePtr Handle(webcc::RequestPtr request) override final { try { @@ -172,13 +208,31 @@ namespace uns return uns::ResponseBuilder().InternalServerError()()->GetImpl()->webcc_res; //Default 500 } - bool Stream(const std::string& method) final + bool Stream(const std::string& method) override final { // 所有数据都不能由webcc进行串流,否则将无法从request中获取文件 return false; } - void ApplyIpUpdate(IPTablePtr blocked_ips) override + bool ValidateHeader(webcc::RequestPtr request) override final + { + try + { + auto uns_req = uns::RequestPtr(new uns::Request(std::make_unique(request))); + return user_reciver->IsHeaderValid(uns_req); + } + catch (const std::exception& e) + { + SCLOGF_ERROR("Unhandled Exception in SyncFileReceiverAdapter(ValidateHeader): {}", e.what()); + } + catch (...) + { + SCLOGF_FATAL("Unhandled Unknown Exception in SyncFileReceiverAdapter(ValidateHeader)"); + } + return true; //Default true + } + + void ApplyIpUpdate(IPTablePtr blocked_ips) override final { try { diff --git a/ServerCore.cpp b/ServerCore.cpp index b255d26..b02e318 100644 --- a/ServerCore.cpp +++ b/ServerCore.cpp @@ -41,7 +41,7 @@ public: { if (server == nullptr) return; - server->set_buffer_size(10240); + server->set_buffer_size(65535); SCLOGF_INFO("ServerCore thread ready: {} Worker(s), {} Loop(s)", worker_thread, loop_thread); server->Run(worker_thread, loop_thread); return; @@ -142,9 +142,9 @@ bool ServerCore::AppenedProcessor(std::string url, ServerProcessorPtr ptr, std:: auto adapter = std::make_shared(ptr); bool bret = pimpl->ccServer->Route(webcc::UrlRegex(url), adapter, Impl::ConvertMethods(methods)); if (bret) - SCLOG_INFO("ServerProcessor added. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_INFO("ServerProcessor added. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); else - SCLOG_ERROR("ServerProcessor add faliure. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_ERROR("ServerProcessor add faliure. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); return bret; } @@ -156,9 +156,9 @@ bool ServerCore::AppenedFileReceiver(std::string url, FileReceiverPtr ptr, std:: auto adapter = std::make_shared(ptr); bool bret = pimpl->ccServer->Route(webcc::UrlRegex(url), adapter, Impl::ConvertMethods(methods)); if (bret) - SCLOG_INFO("FileReceiver added. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_INFO("FileReceiver added. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); else - SCLOG_ERROR("FileReceiver add faliure. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_ERROR("FileReceiver add faliure. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); return bret; } @@ -169,9 +169,9 @@ bool ServerCore::AppenedFileReceiver(std::string url, SyncFileReceiverPtr ptr, s auto adapter = std::make_shared(ptr); bool bret = pimpl->ccServer->Route(webcc::UrlRegex(url), adapter, Impl::ConvertMethods(methods)); if (bret) - SCLOG_INFO("SyncFileReceiver added. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_INFO("SyncFileReceiver added. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); else - SCLOG_ERROR("SyncFileReceiver add faliure. URL: [%s], Method code: <%s>", url.c_str(), uns::toBinary(methods, 10).c_str()); + SCLOGF_ERROR("SyncFileReceiver add faliure. URL: [{}], Method code: <{}>", url, uns::toBinary(methods, 10)); return bret; } diff --git a/ServerCore.h b/ServerCore.h index 61e4685..bce4d40 100644 --- a/ServerCore.h +++ b/ServerCore.h @@ -1,4 +1,4 @@ -/* +/* * Unknown Network Service Web Server Core * Version 1.2.2 * diff --git a/ServerLogger.cpp b/ServerLogger.cpp index 1336b13..01087b5 100644 --- a/ServerLogger.cpp +++ b/ServerLogger.cpp @@ -5,6 +5,7 @@ #include #include #include +#include // 格式化用的辅助函数 @@ -168,6 +169,144 @@ std::string uns::toBinary(unsigned long number, int bits) return "0b" + res; } +bool StartsWith(std::string_view str, std::string_view prefix) +{ + if (str.size() < prefix.size()) + return false; + return str.compare(0, prefix.size(), prefix) == 0; +} + +bool IsSizeUnit(std::string_view str) +{ + if (str == "bit") + return true; + if (str.empty()) + return false; + char last = str.back(); + return last == 'b' || last == 'B'; +} + +bool IsNonNegativeInteger(std::string_view str, int& value) +{ + if (str.empty()) + return false; + int result = 0; + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result); + if (ec != std::errc() || ptr != str.data() + str.size()) + return false; + if (result < 0) + return false; + value = result; + return true; +} + +std::pair ParseSizeFormat(std::string_view input) +{ + constexpr std::pair default_value = { "B", 2 }; + if (!StartsWith(input, "siz")) + return { std::string(default_value.first), default_value.second }; + + std::string_view body = input.substr(3); + if (body.empty() || body.front() != '-') + return { std::string(default_value.first), default_value.second }; + + body.remove_prefix(1); + size_t first_dash = body.find('-'); + if (first_dash == std::string_view::npos) + { + // siz-xx 或 siz-x + if (IsSizeUnit(body)) + return { std::string(body), 2 }; + int precision = 0; + if (IsNonNegativeInteger(body, precision)) + return { "B", precision }; + return { std::string(default_value.first), default_value.second }; + } + + // siz-xx-y + std::string_view unit = body.substr(0, first_dash); + std::string_view precision_str = body.substr(first_dash + 1); + if (!IsSizeUnit(unit)) + return { std::string(default_value.first), default_value.second }; + int precision = 0; + if (!IsNonNegativeInteger(precision_str, precision)) + return { std::string(default_value.first), default_value.second }; + return { std::string(unit), precision }; +} + +std::string FormatFileSize(size_t size, const std::string& unit, int precision) +{ + static constexpr double K = 1024.0; + static constexpr std::array units = + { + "B", + "KB", + "MB", + "GB", + "TB", + "PB", + "EB", + "ZB", + "YB" + }; + + static constexpr std::array iec_units = + { + "B", + "KIB", + "MIB", + "GIB", + "TIB", + "PIB", + "EIB", + "ZIB", + "YIB" + }; + + std::string input_unit = unit; + std::transform(input_unit.begin(), input_unit.end(), input_unit.begin(), [] (unsigned char c) + { + return static_cast(std::toupper(c)); + }); + + double bytes = static_cast(size); + if ((input_unit == "BIT") || (input_unit == "BITS")) + bytes /= 8.0; + else + { + size_t unit_index = 0; + bool found = false; + for (size_t i = 0; i < units.size(); ++i) + { + if ((input_unit == units[i]) || (input_unit == iec_units[i])) + { + unit_index = i; + found = true; + break; + } + } + if (!found) + return std::format("{} {}", size, input_unit); + for (size_t i = 0; i < unit_index; ++i) + bytes *= K; + } + + size_t output_index = 0; + while ((bytes >= K) && (output_index < (units.size() - 1))) + { + bytes /= K; + ++output_index; + } + if (precision < 0) + precision = 0; + + if (std::fabs(bytes - std::round(bytes)) < std::numeric_limits::epsilon()) + return fmt::format("{} {}", static_cast(std::round(bytes)), units[output_index]); + + std::string value = fmt::format("{:.{}f}", bytes, precision); + return fmt::format("{} {}", value, units[output_index]); +} + std::string ServerLogger::GenerateLogHeader(uns::ServerLogLevel LogLevel) { std::string hstr; @@ -245,7 +384,7 @@ inline std::string StripAnsiCodes(const std::string& input) noexcept catch (...) { // 极罕见的内存耗尽情况,直接降级返回原串或空串,绝不崩溃 - return input; + return input; } bool in_escape = false; for (char c : input) @@ -411,6 +550,18 @@ void ServerLogger::RotateIfNeeded(std::time_t now, bool check_size_after_write) } } +size_t GetUnsignedInteger(const uns::LogVariant& value) +{ + return std::visit([] (const auto& v) -> size_t + { + using T = std::decay_t; + if constexpr (std::is_integral_v && !std::is_same_v && !std::is_same_v) + return static_cast(v); + else + return 0; + }, value); +} + inline std::string RewriteFormatString(const std::string& real_format, const uns::LogArg* args, size_t count, fmt::dynamic_format_arg_store& store) { std::string out; @@ -463,6 +614,11 @@ inline std::string RewriteFormatString(const std::string& real_format, const uns else store.push_back(args[arg_index]); } + else if (StartsWith(inside, "siz")) + { + auto [u, p] = ParseSizeFormat(inside); + store.push_back(FormatFileSize(GetUnsignedInteger(arg.value), u, p)); + } else store.push_back(args[arg_index]); } diff --git a/ServerProcessor.cpp b/ServerProcessor.cpp index 18e8b94..77a227b 100644 --- a/ServerProcessor.cpp +++ b/ServerProcessor.cpp @@ -91,7 +91,7 @@ void ServerProcessor::AppenedBlockedIP(DateTime::Span block_time, std::string ip IPList li{ ip }; pimpl->BlockedIPs->Appened(expr_time, li); pimpl->BlockedIPs->Update(); - SCLOG_INFO("IP: [%s] has been blocked untill {%s}", ip.c_str(), std::string(expr_time).c_str()); + SCLOGF_INFO("IP: [{}] has been blocked untill {{{}}}", ip, std::string(expr_time)); return; } @@ -136,13 +136,18 @@ bool ServerProcessor::IsPathSafe(const std::string& raw_path) return false; } +bool ServerProcessor::IsHeaderValid(uns::RequestPtr request) +{ + return true; +} + uns::ResponsePtr ServerProcessor::Handle(uns::RequestPtr request) { std::string x_real_ip; if(request->GetImpl()->webcc_req->HasHeader("X-Real-IP")) x_real_ip = request->GetImpl()->webcc_req->GetHeader("X-Real-IP"); std::string req_ip = (x_real_ip.empty() ? request->GetImpl()->webcc_req->address() : x_real_ip); - SCLOGF_INFO("Request recived by {{{0}}}, ip: [{}], method: {}, URL: {}", RTTISubClassName(typeid(*this)), req_ip, request->GetImpl()->webcc_req->method(), request->GetImpl()->webcc_req->url().path()); + SCLOGF_INFO("Request recived by {{{}}}, ip: [{}], method: {}, URL: {}", RTTISubClassName(typeid(*this)), req_ip, request->GetImpl()->webcc_req->method(), request->GetImpl()->webcc_req->url().path()); if (pimpl->IPCheck && (pimpl->BlockedIPs != nullptr)) { pimpl->BlockedIPs->Update(); diff --git a/ServerProcessor.h b/ServerProcessor.h index d9d8b70..04fca13 100644 --- a/ServerProcessor.h +++ b/ServerProcessor.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "Global.h" #include "Export.h" #include "IPTable.h" @@ -23,9 +23,14 @@ public: void AddStreamSettings(std::string method, bool stream); public: + // 主接口,重载以实现对请求的处理 virtual uns::ResponsePtr Processor(uns::RequestPtr request) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); public: uns::ResponsePtr Handle(uns::RequestPtr request); diff --git a/SyncFileReceiver.cpp b/SyncFileReceiver.cpp index 5a64e8d..0c44b34 100644 --- a/SyncFileReceiver.cpp +++ b/SyncFileReceiver.cpp @@ -13,7 +13,8 @@ public: bool HTMLResponse = false; std::string TempRoot; IPTablePtr BlockedIPs = nullptr; - WebFileInfoVec FileInfo; + TempFileManager FileManager; + std::chrono::seconds FileTimeout = 300s, FileMaxProcTimeout = 600s; }; SyncFileReceiver::SyncFileReceiver() : pimpl(std::make_unique()) @@ -23,31 +24,34 @@ SyncFileReceiver::SyncFileReceiver() : pimpl(std::make_unique()) SyncFileReceiver::~SyncFileReceiver() = default; // 【修改】虚函数的默认实现:如果子类不重写,则默认返回原先的成功状态(201 Created) -uns::ResponsePtr SyncFileReceiver::ProcessFiles(const WebFileInfoVec& file_info, const std::string& tmp_root, uns::RequestPtr request) +uns::ResponsePtr SyncFileReceiver::ProcessFiles(TempFileManager& file_info, SFR_FileMap file_map, const std::string& tmp_root, uns::RequestPtr request) { - SCLOGF_ERROR("SyncFileReceiver::ProcessFiles default handler triggered. Files count: {}", file_info.size()); - + SCLOGF_ERROR("SyncFileReceiver::ProcessFiles default handler triggered. Files count: {}", file_map.size()); + std::string resp_body = (pimpl->HTMLResponse ? EncodeUploadResultHTML() : EncodeUploadResult()); - + return (pimpl->EnableCORS ? uns::ResponseBuilder().Created().Body(resp_body).AutoCORS(request)() : uns::ResponseBuilder().Created().Body(resp_body)()); } void SyncFileReceiver::SetResponseMode(bool html) { pimpl->HTMLResponse = html; - SCLOG_DEBUG("SyncFileReceiver init mode: %s", (html ? "html" : "json")); + SCLOGF_DEBUG("SyncFileReceiver init mode: {}", (html ? "html" : "json")); } void SyncFileReceiver::SetCORSEnable(bool enable) { pimpl->EnableCORS = enable; - SCLOG_DEBUG("SyncFileReceiver CORS mode: %s", (enable ? "enabled" : "disabled")); + SCLOGF_DEBUG("SyncFileReceiver CORS mode: {}", (enable ? "enabled" : "disabled")); } void SyncFileReceiver::SetTempRoot(std::string temp_root) { pimpl->TempRoot = temp_root; - SCLOG_TRACE("SFR-TempRoot: %s", pimpl->TempRoot.c_str()); + if (pimpl->FileManager.SetBaseDirectory(temp_root)) + SCLOGF_TRACE("SFR-TempRoot: {}", pimpl->TempRoot); + else + SCLOGF_WARNING("SFR: Failed to Set Temp Root ({})", temp_root); return; } @@ -63,7 +67,7 @@ void SyncFileReceiver::AppenedBlockedIP(DateTime::Span block_time, std::string i IPList li{ ip }; pimpl->BlockedIPs->Appened(expr_time, li); pimpl->BlockedIPs->Update(); - SCLOG_INFO("IP: [%s] has been blocked untill {%s}", ip.c_str(), std::string(expr_time).c_str()); + SCLOGF_INFO("IP: [{}] has been blocked untill {{{}}}", ip, std::string(expr_time)); return; } @@ -97,13 +101,24 @@ bool SyncFileReceiver::WriteFile(const std::string& path, const std::string& byt std::ofstream stream{ path, std::ios::binary }; if (stream.fail()) { - SCLOG_WARNING("Failed to write file [%s]: can't open stream", path.c_str()); + SCLOGF_WARNING("Failed to write file [{}]: can't open stream", path); return false; } stream.write(bytes.data(), bytes.size()); - if (stream.fail()) - SCLOG_WARNING("Failed to write file [%s]: can't write to stream", path.c_str()); - return !stream.fail(); + bool fail = stream.fail(); + if (fail) + SCLOGF_WARNING("Failed to write file [{}]: can't write to stream", path); + else + SCLOGF_TRACE("Wrote {siz-b} to file [{}]", bytes.size(), path); + return !fail; +} + +void SyncFileReceiver::SetFileTimeout(std::chrono::seconds timeout, std::chrono::seconds max_proc_timeout) noexcept +{ + if (timeout.count() > 0) + pimpl->FileTimeout = timeout; + if (max_proc_timeout.count() > 0) + pimpl->FileMaxProcTimeout = max_proc_timeout; } uns::PathTraversalDefenceLevel SyncFileReceiver::PTDefence() @@ -111,25 +126,41 @@ uns::PathTraversalDefenceLevel SyncFileReceiver::PTDefence() return uns::PathTraversalDefenceLevel::DenyAll; } -bool SyncFileReceiver::IsPathSafe(const std::string & raw_path) +bool SyncFileReceiver::IsPathSafe(const std::string& raw_path) { return false; } +bool SyncFileReceiver::IsHeaderValid(uns::RequestPtr request) +{ + return true; +} + std::string SyncFileReceiver::EncodeUploadResult() { - Json::Value root; - Json::FastWriter writer; - root["AcceptedCount"] = pimpl->FileInfo.size(); - root["AcceptedFiles"] = Json::Value(Json::arrayValue); - for (auto& ele : pimpl->FileInfo) + try { - Json::Value sub; - sub["FileName"] = ele.GetStorageFileName(); - sub["UploadTime"] = ele.GetUploadTime().GetTimeStamp(); - root["AcceptedFiles"].append(sub); + Json::Value root; + Json::FastWriter writer; + // 1. 从管理器安全获取当前所有文件的快照 + auto file_infos = pimpl->FileManager.GetAllFileInfos(); + // 2. 组装 JSON 数据 + root["AcceptedCount"] = static_cast(file_infos.size()); + root["AcceptedFiles"] = Json::Value(Json::arrayValue); + for (const auto& ele : file_infos) + { + Json::Value sub; + sub["FileName"] = ele.GetStorageFileName(); + sub["UploadTime"] = ele.GetUploadTime().GetTimeStamp(); + root["AcceptedFiles"].append(sub); + } + return writer.write(root); + } + catch (...) + { + // 极致异常安全兜底:如果 Json 报错或内存写满,返回一个合法的空 JSON 字符串 + return "{\"AcceptedCount\":0,\"AcceptedFiles\":[]}"; } - return writer.write(root); } std::string SyncFileReceiver::EncodeUploadResultHTML() @@ -150,44 +181,60 @@ std::string SyncFileReceiver::EncodeUploadResultHTML() )"; - std::string tmp; - for (auto& ele : pimpl->FileInfo) - tmp += "[" + ele.GetStorageFileName() + "] - {" + ele.GetUploadTime().Format("%Y-%m-%d %H:%M:%S") + "}
"; - size_t html_size = strlen(html) + tmp.size() + 10; - char* result = new char[html_size]; - memset(result, 0, sizeof(result)); - sprintf(result, html, pimpl->FileInfo.size(), tmp.c_str()); - tmp = std::string(result); - delete[] result; - return tmp; + try + { + // 1. 获取文件快照 + auto file_infos = pimpl->FileManager.GetAllFileInfos(); + // 2. 拼接文件列表 HTML + std::string tmp; + for (const auto& ele : file_infos) + tmp += "[" + ele.GetStorageFileName() + "] - {" + ele.GetUploadTime().Format("%Y-%m-%d %H:%M:%S") + "}
"; + // 3. 动态安全计算所需缓冲区大小(32字节用于容纳 %lld 的数字展开) + size_t html_size = strlen(html) + tmp.size() + 32; + // 利用 std::string 管理缓冲区内存(RAII 机制,无论发生什么都会自动释放,绝不泄漏) + std::string result_str(html_size, '\0'); + // 使用安全的 snprintf 写入 string 内部缓冲区 + int written = snprintf(result_str.data(), result_str.size(), html, static_cast(file_infos.size()), tmp.c_str()); + if (written > 0) + { + result_str.resize(written); // 裁剪掉尾部多余的 \0 + return result_str; + } + return "HTML generation failed"; + } + catch (...) + { + // 异常安全兜底 + return "

Upload Result Error

"; + } } uns::ResponsePtr SyncFileReceiver::Execute(uns::RequestPtr request) { uns::HTTPMethod method = GetMethod(request); std::string x_real_ip; - if(request->GetImpl()->webcc_req->HasHeader("X-Real-IP")) + if (request->GetImpl()->webcc_req->HasHeader("X-Real-IP")) x_real_ip = request->GetImpl()->webcc_req->GetHeader("X-Real-IP"); std::string req_ip = (x_real_ip.empty() ? request->GetImpl()->webcc_req->address() : x_real_ip); - SCLOG_DEBUG("Request recived, ip: [%s], method: %s", req_ip.c_str(), request->GetImpl()->webcc_req->method().c_str()); + SCLOGF_DEBUG("Request recived, ip: [{}], method: {}", req_ip, request->GetImpl()->webcc_req->method()); // path test std::string path = request->GetImpl()->webcc_req->url().path(); auto status = PathTraversal::AnalyzeUrlTraversal(path); - if(status != PathTraversal::UrlSafetyStatus::Safe) + if (status != PathTraversal::UrlSafetyStatus::Safe) SCLOGF_WARNING("PathTraversal Detected: {}, Level: {}", path, PathTraversal::ToString(status)); - switch(PTDefence()) + switch (PTDefence()) { case uns::PathTraversalDefenceLevel::DenyAll: - if(status != PathTraversal::UrlSafetyStatus::Safe) + if (status != PathTraversal::UrlSafetyStatus::Safe) return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); break; case uns::PathTraversalDefenceLevel::AutoNormalize: { - if(status == PathTraversal::UrlSafetyStatus::EvasiveTraversal) + if (status == PathTraversal::UrlSafetyStatus::EvasiveTraversal) return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); auto decoded_path = PathTraversal::UrlDecode(path); - if(!IsPathSafe(decoded_path)) - return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); + if (!IsPathSafe(decoded_path)) + return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); auto url = request->GetImpl()->webcc_req->url(); url.ForceSet_Path(PathTraversal::NormalizeUrlPath(decoded_path)); request->GetImpl()->webcc_req->set_url(std::move(url)); @@ -195,11 +242,11 @@ uns::ResponsePtr SyncFileReceiver::Execute(uns::RequestPtr request) } case uns::PathTraversalDefenceLevel::AllowNormal: { - if(status == PathTraversal::UrlSafetyStatus::EvasiveTraversal) + if (status == PathTraversal::UrlSafetyStatus::EvasiveTraversal) return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); auto decoded_path = PathTraversal::UrlDecode(path); - if(!IsPathSafe(decoded_path)) - return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); + if (!IsPathSafe(decoded_path)) + return (pimpl->EnableCORS ? uns::ResponseBuilder().Forbidden().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Forbidden().EmptyBody()()); auto url = request->GetImpl()->webcc_req->url(); url.ForceSet_Path(decoded_path); request->GetImpl()->webcc_req->set_url(std::move(url)); @@ -217,13 +264,14 @@ uns::ResponsePtr SyncFileReceiver::Execute(uns::RequestPtr request) if (pimpl->BlockedIPs->IPExist(req_ip)) return (pimpl->EnableCORS ? uns::ResponseBuilder().IPBlocked().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().IPBlocked().EmptyBody()()); } - webcc::Status tmpStatus = uns::ConvertStatus(PreCheckRequest(request)); - if (tmpStatus != webcc::kOK) - return (pimpl->EnableCORS ? uns::ResponseBuilder().Code(tmpStatus).EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Code(tmpStatus).EmptyBody()()); + webcc::Status tmp_status = uns::ConvertStatus(PreCheckRequest(request)); + if (tmp_status != webcc::kOK) + return (pimpl->EnableCORS ? uns::ResponseBuilder().Code(tmp_status).EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().Code(tmp_status).EmptyBody()()); else if (!request->IsForm()) return (pimpl->EnableCORS ? uns::ResponseBuilder().RequestFormatError().EmptyBody().AutoCORS(request)() : uns::ResponseBuilder().RequestFormatError().EmptyBody()()); else { + SFR_FileMap fmap; for (auto& form : request->GetFormParts()) { if (form->GetFileName().empty()) @@ -236,17 +284,13 @@ uns::ResponsePtr SyncFileReceiver::Execute(uns::RequestPtr request) SCLOGF_DEBUG("File recived: [{}], {} bytes", form->GetFileName(), form->GetDataSize()); WebFileInfo info(form->GetFileNameS(), form->GetDataSize()); WriteFile(info.MakePath(pimpl->TempRoot), form->GetData()); - pimpl->FileInfo.push_back(info); + fmap.insert({ form->GetFileNameS(), info.GetStorageFileName() }); + //pimpl->FileInfo.push_back(info); + if (!pimpl->FileManager.RegisterFile(info, pimpl->FileTimeout, pimpl->FileMaxProcTimeout)) + SCLOGF_WARNING("FileManager.RegisterFile Error, File: {}, TempRoot: {}", form->GetFileName(), pimpl->TempRoot); } - - // 【修改的关键步骤】 - // 1. 同步调用虚函数,获取具体的业务处理结果(及构筑好的自定义 HTTP Response) - uns::ResponsePtr response = ProcessFiles(pimpl->FileInfo, pimpl->TempRoot, request); - - // 2. 清理当前类中的文件缓存(防止污染下一次 HTTP 请求) - pimpl->FileInfo.clear(); - - // 3. 作为最后一步直接返回 + // 同步调用虚函数,获取具体的业务处理结果(及构筑好的自定义 HTTP Response) + uns::ResponsePtr response = ProcessFiles(pimpl->FileManager, fmap, pimpl->TempRoot, request); return response; } } diff --git a/SyncFileReceiver.h b/SyncFileReceiver.h index 7302aab..0b25a40 100644 --- a/SyncFileReceiver.h +++ b/SyncFileReceiver.h @@ -1,9 +1,11 @@ -#pragma once +#pragma once #include "Export.h" #include "Global.h" #include "IPTable.h" -#include "WebFileInfo.h" #include "HTTPObjects.h" +#include "TempFileManager.h" + +using SFR_FileMap = std::map; class UNSWSC_DLL_EXPORT SyncFileReceiver { @@ -25,16 +27,22 @@ public: uns::HTTPMethod GetMethod(uns::RequestPtr request); void AppenedBlockedIP(DateTime::Span block_time, std::string ip); bool WriteFile(const std::string& path, const std::string& bytes); + void SetFileTimeout(std::chrono::seconds timeout = 0s, std::chrono::seconds max_proc_timeout = 0s) noexcept; public: + // 请求信息预检,重载以在保存文件之前检查请求体 virtual uns::Status PreCheckRequest(uns::RequestPtr request) = 0; + // 表单预检,重载以在处理表单前检查表单 virtual bool PreCheckForm(uns::FormPartPtr form) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); - // 【修改】由原先的 Callback 改为可供子类重写的虚函数 - // 返回值改为 webcc::ResponsePtr,并且引入 request 参数以便子类调用 AutoCORS 或解析请求头 - virtual uns::ResponsePtr ProcessFiles(const WebFileInfoVec& file_info, const std::string& tmp_root, uns::RequestPtr request); + // 主接口,重载以接收并处理文件 + virtual uns::ResponsePtr ProcessFiles(TempFileManager& file_info, SFR_FileMap file_map, const std::string& tmp_root, uns::RequestPtr request); public: uns::ResponsePtr Execute(uns::RequestPtr request); diff --git a/TempFileManager.cpp b/TempFileManager.cpp new file mode 100644 index 0000000..5d960a2 --- /dev/null +++ b/TempFileManager.cpp @@ -0,0 +1,397 @@ +#include "TempFileManager.h" +#include +#include +#include +#include +#include +#include "ServerLogger.h" + +class TempFileManager::Impl +{ +public: + struct FileControlBlock + { + WebFileInfo info; + std::chrono::steady_clock::time_point expire_time; + std::chrono::steady_clock::time_point active_start_time; + std::chrono::seconds remaining_timeout; + std::chrono::seconds max_processing_timeout; + bool is_active = false; + bool is_permanent = false; // 是否永久保留 + bool is_invalid = false; + }; + + std::string base_dir; + std::unordered_map file_map; + mutable std::shared_mutex rw_mutex; + + // C++20 jthread + std::jthread cleanup_thread; + +public: + Impl() noexcept + { + } + + ~Impl() noexcept + { + // 1. 必须第一步:发送停止信号并阻塞等待后台清理线程彻底退出 + // 这样能确保后面遍历 file_map 时,绝对没有第二个线程在并发访问它 + SCLOG_INFO("TempFileManager Destruction Begin"); + cleanup_thread.request_stop(); + if (cleanup_thread.joinable()) + cleanup_thread.join(); + // 2. 此时属于单线程环境,无需加锁。遍历并销毁所有非永久文件 + std::error_code ec; + for (const auto& [_, fcb] : file_map) + { + if (!fcb.is_permanent && !base_dir.empty()) + { + std::string path = fcb.info.MakePath(base_dir); + // 使用无异常重载版本,即使磁盘物理删除失败(如文件被外层强行独占锁死)也绝不抛出异常 + std::filesystem::remove(path, ec); + if (!ec) + SCLOGF_INFO("Temp File {} Deleted.", path); + else + SCLOGF_WARNING("Temp File {} Delete Failed: {}({})", path, ec.value(), ec.message()); + } + // 如果 is_permanent 为 true(永久化文件),则跳过不处理,物理文件将安全留在磁盘上 + } + // 3. 析构结束,file_map 内存控制块会自动退栈销毁 + SCLOG_INFO("TempFileManager Destruction Finished"); + } + +public: + void CleanupLoop(std::stop_token st) noexcept + { + while (!st.stop_requested()) + { + // 改进:引入分段休眠(10次*100ms),让析构函数调用 join() 时能在最大 100ms 内瞬间响应退出 + // 避免传统的 sleep_for(1s) 导致服务器内核关闭时卡顿 1 秒 + for (int i = 0; i < 10; i++) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (st.stop_requested()) + return; // 随时收到终止信号随时退出 + } + std::unique_lock lock(rw_mutex); + if (base_dir.empty()) + continue; + auto now = std::chrono::steady_clock::now(); + for (auto it = file_map.begin(); it != file_map.end(); ) + { + bool should_delete = false; + if (it->second.is_invalid) + should_delete = true; //手动设置的无条件立即删除 + if (!it->second.is_permanent) + { + if (it->second.is_active) + { + if ((it->second.max_processing_timeout > std::chrono::seconds(0)) && ((now - it->second.active_start_time) > it->second.max_processing_timeout)) + should_delete = true; + } + else + { + if (now > it->second.expire_time) + should_delete = true; + } + } + if (should_delete) + { + std::error_code ec; + std::string path = it->second.info.MakePath(base_dir); + std::filesystem::remove(path, ec); + if (!ec) + SCLOGF_INFO("Temp File {} {}, Deleted.", path, (it->second.is_invalid ? "Invalid" : "Expried")); + else + SCLOGF_WARNING("Temp File {} {}, Delete Failed: {}({})", path, (it->second.is_invalid ? "Invalid" : "Expried"), ec.value(), ec.message()); + it = file_map.erase(it); + } + else + ++it; + } + } + } +}; + +TempFileManager::TempFileManager() noexcept : pimpl(std::make_unique()) +{ +} + +TempFileManager::~TempFileManager() noexcept = default; + +// ================= 以下其余基础业务接口保持不变 ================= + +bool TempFileManager::SetBaseDirectory(std::string dir) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); // 加上写锁,防止与其他文件操作并发 + pimpl->base_dir = std::move(dir); + std::error_code ec; + // 物理创建目录(无异常版本) + std::filesystem::create_directories(pimpl->base_dir, ec); + if (ec) + SCLOGF_ERROR("TempFileManager: create_directories error: {}({})", ec.value(), ec.message()); + // 只有在线程未启动时才启动后台清理线程,确保整个生命周期只启动一次 + if (!pimpl->cleanup_thread.joinable() && !ec) + { + pimpl->cleanup_thread = std::jthread([this] (std::stop_token st) + { + this->pimpl->CleanupLoop(st); + }); + SCLOGF_INFO("TempFileManager: Thread Started."); + } + else + SCLOGF_ERROR("TempFileManager: Failed To Start Thread (Thread Joinable: {}, Error: {})", pimpl->cleanup_thread.joinable(), ec.message()); + return !ec; +} + +bool TempFileManager::RegisterFile(const WebFileInfo& info, std::chrono::seconds timeout, std::chrono::seconds max_proc_timeout) noexcept +{ + try + { + std::unique_lock lock(pimpl->rw_mutex); + if (pimpl->file_map.contains(info.GetStorageFileName())) + { + SCLOGF_WARNING("RegisterFile Failed: File {} Already Exists", info.GetStorageFileName()); + return false; + } + Impl::FileControlBlock fcb + { + .info = info, + .expire_time = std::chrono::steady_clock::now() + timeout, + .remaining_timeout = timeout, + .max_processing_timeout = max_proc_timeout + }; + pimpl->file_map[info.GetStorageFileName()] = std::move(fcb); + SCLOGF_INFO("File {}({}) Registered", info.GetOriginalFileName(), info.GetStorageFileName()); + return true; + } + catch (...) + { + SCLOG_WARNING("RegisterFile Failed: Exception"); + return false; + } +} + +bool TempFileManager::InvalidateFile(const WebFileInfo& info) +{ + std::unique_lock lock(pimpl->rw_mutex); + if (pimpl->file_map.contains(info.GetStorageFileName())) + { + pimpl->file_map[info.GetStorageFileName()].is_invalid = true; + SCLOGF_INFO("File [{}]({}) Marked AS Invalid", info.GetStorageFileName(), info.GetOriginalFileName()); + return true; + } + else + SCLOGF_WARNING("InvalidateFile({}/{}) Failed: Not Found", info.GetOriginalFileName(), info.GetStorageFileName()); + return false; +} + +bool TempFileManager::InvalidateFile(const std::map& info) +{ + size_t succ_cnt = 0; + std::unique_lock lock(pimpl->rw_mutex); + for (const auto& [on, sn] : info) + { + if (pimpl->file_map.contains(sn)) + { + pimpl->file_map[sn].is_invalid = true; + succ_cnt++; + SCLOGF_INFO("File [{}]({}) Marked AS Invalid", sn, on); + } + else + SCLOGF_WARNING("InvalidateFile({}/{}) Failed: Not Found", on, sn); + } + return (succ_cnt == info.size()); +} + +bool TempFileManager::CopyFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept +{ + std::shared_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + auto dest_file = std::filesystem::path(dest_absolute_path) / storage_name; + if (it == pimpl->file_map.end()) + { + SCLOGF_WARNING("CopyFileTo({}, {}) Failed: File Not Exists", storage_name, dest_file); + return false; + } + std::error_code ec; + std::filesystem::copy(it->second.info.MakePath(pimpl->base_dir), dest_file, std::filesystem::copy_options::overwrite_existing, ec); + if (ec) + SCLOGF_WARNING("CopyFileTo({}, {}) Failed: {}({})", storage_name, dest_file, ec.value(), ec.message()); + else + SCLOGF_INFO("CopyFileTo({}, {}) Success", storage_name, dest_file); + return !ec; +} + +bool TempFileManager::CutFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + auto dest_file = std::filesystem::path(dest_absolute_path) / storage_name; + if (it == pimpl->file_map.end()) + { + SCLOGF_WARNING("CutFileTo({}, {}) Failed: File Not Exists", storage_name, dest_file); + return false; + } + std::error_code ec; + std::filesystem::rename(it->second.info.MakePath(pimpl->base_dir), dest_file, ec); + if (ec) + SCLOGF_WARNING("CutFileTo({}, {}) Failed: {}({})", storage_name, dest_file, ec.value(), ec.message()); + else + SCLOGF_INFO("CutFileTo({}, {}) Success", storage_name, dest_file); + if (ec) + return false; + pimpl->file_map.erase(it); + return true; +} + +bool TempFileManager::RenameFile(const std::string& old_storage_name, const std::string& new_storage_name) noexcept +{ + try + { + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(old_storage_name); + if ((it == pimpl->file_map.end()) || pimpl->file_map.contains(new_storage_name)) + { + SCLOGF_WARNING("RenameFile({}, {}) Failed: File Not Exists", old_storage_name, new_storage_name); + return false; + } + std::error_code ec; + std::string old_path = it->second.info.MakePath(pimpl->base_dir); + Impl::FileControlBlock fcb = std::move(it->second); + fcb.info.SetStorageFileName(new_storage_name); + std::string new_path = fcb.info.MakePath(pimpl->base_dir); + std::filesystem::rename(old_path, new_path, ec); + if (ec) + SCLOGF_WARNING("RenameFile({}, {}) Failed: {}({})", old_storage_name, new_storage_name, ec.value(), ec.message()); + else + SCLOGF_INFO("RenameFile({}, {}) Success", old_storage_name, new_storage_name); + if (ec) + return false; + pimpl->file_map.erase(it); + pimpl->file_map[new_storage_name] = std::move(fcb); + return true; + } + catch (...) + { + SCLOG_WARNING("RenameFile Failed: Exception"); + return false; + } +} + +bool TempFileManager::DeleteFile(const std::string& storage_name) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + if (it == pimpl->file_map.end()) + { + SCLOGF_WARNING("DeleteFile({}) Failed: File Not Exists", storage_name); + return false; + } + std::error_code ec; + std::filesystem::remove(it->second.info.MakePath(pimpl->base_dir), ec); + if (ec) + SCLOGF_WARNING("DeleteFile({}) Failed: {}({})", storage_name, ec.value(), ec.message()); + else + SCLOGF_INFO("DeleteFile({}) Success", storage_name); + if (ec) + return false; + pimpl->file_map.erase(it); + return true; +} + +bool TempFileManager::ActiveFile(const std::string& storage_name) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + if ((it == pimpl->file_map.end()) || it->second.is_active) + { + SCLOGF_WARNING("ActiveFile({}) Failed: {}", storage_name, (it->second.is_active ? "Already Actived" : "File Not Exists")); + return false; + } + auto now = std::chrono::steady_clock::now(); + if (it->second.expire_time > now) + it->second.remaining_timeout = std::chrono::duration_cast(it->second.expire_time - now); + else + it->second.remaining_timeout = std::chrono::seconds(0); + it->second.is_active = true; + it->second.active_start_time = now; + SCLOGF_INFO("ActiveFile({}) Success", storage_name); + return true; +} + +bool TempFileManager::DeactiveFile(const std::string& storage_name) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + if ((it == pimpl->file_map.end()) || !it->second.is_active) + { + SCLOGF_WARNING("DeactiveFile({}) Failed: {}", storage_name, ((it != pimpl->file_map.end()) ? "Already Deactived" : "File Not Exists")); + return false; + } + it->second.is_active = false; + it->second.expire_time = std::chrono::steady_clock::now() + it->second.remaining_timeout; + SCLOGF_INFO("DeactiveFile({}) Success", storage_name); + return true; +} + +bool TempFileManager::SetPermanent(const std::string& storage_name, bool permanent) noexcept +{ + std::unique_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + if (it == pimpl->file_map.end()) + { + SCLOGF_WARNING("SetPermanent({}) Failed: File Not Exists", storage_name); + return false; + } + it->second.is_permanent = permanent; + SCLOGF_INFO("SetPermanent({}) Success", storage_name); + return true; +} + +bool TempFileManager::FileExists(const std::string& storage_name) const noexcept +{ + std::shared_lock lock(pimpl->rw_mutex); + return pimpl->file_map.contains(storage_name); +} + +bool TempFileManager::GetFileInfo(const std::string& storage_name, WebFileInfo& out_info) const noexcept +{ + try + { + std::shared_lock lock(pimpl->rw_mutex); + auto it = pimpl->file_map.find(storage_name); + if (it == pimpl->file_map.end()) + return false; + out_info = it->second.info; + return true; + } + catch (...) + { + SCLOGF_WARNING("GetFileInfo({}) Failed: Exception", storage_name); + return false; + } +} + +size_t TempFileManager::GetFileCount() const noexcept +{ + return pimpl->file_map.size(); +} + +std::vector TempFileManager::GetAllFileInfos() const noexcept +{ + std::vector list; + try + { + std::shared_lock lock(pimpl->rw_mutex); // 申请读锁,支持高并发并发读取 + list.reserve(pimpl->file_map.size()); // 提前预留空间,减少内存重分配次数 + for (const auto& [_, fcb] : pimpl->file_map) + list.push_back(fcb.info); // 拷贝文件元数据到外部 + } + catch (...) + { + list.clear(); // 极端内存崩溃(bad_alloc)时,清空并安全返回空数组 + } + return list; +} diff --git a/TempFileManager.h b/TempFileManager.h new file mode 100644 index 0000000..9597451 --- /dev/null +++ b/TempFileManager.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include +#include +#include "Export.h" +#include "WebFileInfo.h" + +using std::chrono::operator""s; +using std::chrono::operator""min; + +class UNSWSC_DLL_EXPORT TempFileManager +{ +private: + class Impl; + + std::unique_ptr pimpl; + +public: + TempFileManager() noexcept; + ~TempFileManager() noexcept; + + // 禁止拷贝与移动 + TempFileManager(const TempFileManager&) = delete; + TempFileManager& operator=(const TempFileManager&) = delete; + TempFileManager(TempFileManager&&) = delete; + TempFileManager& operator=(TempFileManager&&) = delete; + + // 基础业务接口(保持不变) + bool SetBaseDirectory(std::string dir) noexcept; + bool RegisterFile(const WebFileInfo& info, std::chrono::seconds timeout, std::chrono::seconds max_proc_timeout = std::chrono::seconds(0)) noexcept; + bool InvalidateFile(const WebFileInfo& info); + //For SFR_FileMap + bool InvalidateFile(const std::map& info); + bool CopyFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept; + bool CutFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept; + bool RenameFile(const std::string& old_storage_name, const std::string& new_storage_name) noexcept; + bool DeleteFile(const std::string& storage_name) noexcept; + bool ActiveFile(const std::string& storage_name) noexcept; + bool DeactiveFile(const std::string& storage_name) noexcept; + bool SetPermanent(const std::string& storage_name, bool permanent) noexcept; + bool FileExists(const std::string& storage_name) const noexcept; + bool GetFileInfo(const std::string& storage_name, WebFileInfo& out_info) const noexcept; + size_t GetFileCount() const noexcept; + // 获取当前所有管理中的文件信息快照(线程安全,绝不抛出异常) + std::vector GetAllFileInfos() const noexcept; +}; \ No newline at end of file diff --git a/UNSResponseBuilder.cpp b/UNSResponseBuilder.cpp index bb99949..33318a9 100644 --- a/UNSResponseBuilder.cpp +++ b/UNSResponseBuilder.cpp @@ -740,18 +740,18 @@ uns::ResponseBuilder& uns::ResponseBuilder::AutoCORS(uns::RequestPtr req) std::string host = req->GetImpl()->webcc_req->HasHeader("Host") ? req->GetImpl()->webcc_req->GetHeader("Host") : ""; if(host.empty() || GlobalCORSConfig.HostValidate(host)) { - SCLOG_INFO("Applied CORS headers for origin=%s cred=%d", origin.c_str(), GlobalCORSConfig.AllowCookie() ? 1 : 0); + SCLOGF_INFO("Applied CORS headers for origin={} cred={}", origin, GlobalCORSConfig.AllowCookie() ? 1 : 0); return CORS(origin); } else { - SCLOG_WARNING("Actual request: Host not allowed: %s", host.c_str()); + SCLOGF_WARNING("Actual request: Host not allowed: {}", host); return Forbidden().Body(std::string("CORS ERROR")); } } else { - SCLOG_WARNING("Actual request: Origin not allowed: %s", origin.c_str()); + SCLOGF_WARNING("Actual request: Origin not allowed: {}", origin); return Forbidden().Body(std::string("CORS ERROR")); } } diff --git a/WebFileInfo.cpp b/WebFileInfo.cpp index 2deeb3e..dd8e749 100644 --- a/WebFileInfo.cpp +++ b/WebFileInfo.cpp @@ -90,3 +90,13 @@ size_t WebFileInfo::GetFileSize() const { return FileSize; } + +void WebFileInfo::SetStorageFileName(const std::string& sfn) +{ + StorageFileName = sfn; +} + +void WebFileInfo::SetOriginalFileName(const std::string& ofn) +{ + OriginalFileName = ofn; +} diff --git a/WebFileInfo.h b/WebFileInfo.h index 7ad0af5..fe849fc 100644 --- a/WebFileInfo.h +++ b/WebFileInfo.h @@ -31,6 +31,10 @@ public: std::string GetExtensionName() const; DateTime GetUploadTime() const; size_t GetFileSize() const; + +public: + void SetStorageFileName(const std::string& sfn); + void SetOriginalFileName(const std::string& ofn); }; using WebFileInfoVec = std::vector; \ No newline at end of file diff --git a/build/CMakeFiles/Makefile2 b/build/CMakeFiles/Makefile2 index e16317d..7e6e3f9 100644 --- a/build/CMakeFiles/Makefile2 +++ b/build/CMakeFiles/Makefile2 @@ -86,12 +86,12 @@ clean: CMakeFiles/rebuild.dir/clean CMakeFiles/unswsc.dir/all: $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/depend $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/build - @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/unknownobject/UNSWebServerCore/build/CMakeFiles --progress-num=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 "Built target unswsc" + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/unknownobject/UNSWebServerCore/build/CMakeFiles --progress-num=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 "Built target unswsc" .PHONY : CMakeFiles/unswsc.dir/all # Build rule for subdir invocation for target. CMakeFiles/unswsc.dir/rule: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/unknownobject/UNSWebServerCore/build/CMakeFiles 20 + $(CMAKE_COMMAND) -E cmake_progress_start /home/unknownobject/UNSWebServerCore/build/CMakeFiles 21 $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/unswsc.dir/all $(CMAKE_COMMAND) -E cmake_progress_start /home/unknownobject/UNSWebServerCore/build/CMakeFiles 0 .PHONY : CMakeFiles/unswsc.dir/rule diff --git a/build/CMakeFiles/logger_test.dir/LogArg.cpp.o.d b/build/CMakeFiles/logger_test.dir/LogArg.cpp.o.d index 2bccca7..0638529 100644 --- a/build/CMakeFiles/logger_test.dir/LogArg.cpp.o.d +++ b/build/CMakeFiles/logger_test.dir/LogArg.cpp.o.d @@ -209,5 +209,8 @@ CMakeFiles/logger_test.dir/LogArg.cpp.o: \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ /usr/include/c++/13/bits/node_handle.h \ - /usr/include/c++/13/bits/erase_if.h \ + /usr/include/c++/13/bits/erase_if.h /usr/include/c++/13/filesystem \ + /usr/include/c++/13/bits/fs_fwd.h /usr/include/c++/13/bits/fs_path.h \ + /usr/include/c++/13/codecvt /usr/include/c++/13/bits/fs_dir.h \ + /usr/include/c++/13/bits/fs_ops.h \ /home/unknownobject/UNSWebServerCore/utextcodec/UTextCodec.h diff --git a/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o b/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o index a6110bc..98ddfbc 100644 Binary files a/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o and b/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o differ diff --git a/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o.d b/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o.d index 4635ff8..d99a4f1 100644 --- a/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o.d +++ b/build/CMakeFiles/logger_test.dir/ServerLogger.cpp.o.d @@ -251,8 +251,10 @@ CMakeFiles/logger_test.dir/ServerLogger.cpp.o: \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ /usr/include/c++/13/bits/node_handle.h \ - /usr/include/c++/13/bits/erase_if.h \ - /usr/include/c++/13/condition_variable \ + /usr/include/c++/13/bits/erase_if.h /usr/include/c++/13/filesystem \ + /usr/include/c++/13/bits/fs_fwd.h /usr/include/c++/13/bits/fs_path.h \ + /usr/include/c++/13/codecvt /usr/include/c++/13/bits/fs_dir.h \ + /usr/include/c++/13/bits/fs_ops.h /usr/include/c++/13/condition_variable \ /home/unknownobject/vcpkg/installed/x64-linux/include/fmt/format.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/fmt/base.h \ /usr/include/c++/13/cmath /usr/include/math.h \ diff --git a/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o b/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o index 00f446b..e066821 100644 Binary files a/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o and b/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o differ diff --git a/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o.d b/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o.d index 907063e..0051469 100644 --- a/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o.d +++ b/build/CMakeFiles/logger_test.dir/TestLogger.cpp.o.d @@ -251,4 +251,7 @@ CMakeFiles/logger_test.dir/TestLogger.cpp.o: \ /usr/include/c++/13/span /usr/include/c++/13/variant \ /usr/include/c++/13/bits/ranges_algobase.h \ /home/unknownobject/UNSWebServerCore/Export.h \ + /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ + /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ + /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ /usr/include/c++/13/condition_variable diff --git a/build/CMakeFiles/progress.marks b/build/CMakeFiles/progress.marks index 6f4247a..f64f5d8 100644 --- a/build/CMakeFiles/progress.marks +++ b/build/CMakeFiles/progress.marks @@ -1 +1 @@ -26 +27 diff --git a/build/CMakeFiles/unswsc.dir/CORSConfig.cpp.o.d b/build/CMakeFiles/unswsc.dir/CORSConfig.cpp.o.d index f76b0cf..6afd6e6 100644 --- a/build/CMakeFiles/unswsc.dir/CORSConfig.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/CORSConfig.cpp.o.d @@ -180,4 +180,6 @@ CMakeFiles/unswsc.dir/CORSConfig.cpp.o: \ /usr/include/c++/13/bits/istream.tcc \ /usr/include/c++/13/bits/sstream.tcc \ /home/unknownobject/UNSWebServerCore/Global.h \ + /usr/include/c++/13/optional \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/DateTime.h diff --git a/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o b/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o index cf65b9e..13c9bbd 100644 Binary files a/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o and b/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o.d b/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o.d index 47acbed..ef5356f 100644 --- a/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/CORSProcessor.cpp.o.d @@ -140,7 +140,11 @@ CMakeFiles/unswsc.dir/CORSProcessor.cpp.o: \ /usr/include/c++/13/bits/stl_uninitialized.h \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/Export.h \ /home/unknownobject/UNSWebServerCore/DateTime.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ @@ -159,11 +163,8 @@ CMakeFiles/unswsc.dir/CORSProcessor.cpp.o: \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/c++/13/bits/unique_ptr.h /usr/include/c++/13/ostream \ - /usr/include/c++/13/ios /usr/include/c++/13/exception \ - /usr/include/c++/13/bits/exception_ptr.h \ - /usr/include/c++/13/bits/cxxabi_init_exception.h \ - /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ - /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ios /usr/include/c++/13/bits/ios_base.h \ + /usr/include/c++/13/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ @@ -265,16 +266,14 @@ CMakeFiles/unswsc.dir/CORSProcessor.cpp.o: \ /usr/include/c++/13/bits/locale_conv.h \ /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ /usr/include/c++/13/array /usr/include/c++/13/charconv \ - /usr/include/c++/13/optional \ - /usr/include/c++/13/bits/enable_special_members.h \ /usr/include/c++/13/span /usr/include/c++/13/variant \ /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ - /usr/include/c++/13/condition_variable \ - /home/unknownobject/UNSWebServerCore/UNSResponseBuilder.h \ /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ - /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h + /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ + /usr/include/c++/13/condition_variable \ + /home/unknownobject/UNSWebServerCore/UNSResponseBuilder.h diff --git a/build/CMakeFiles/unswsc.dir/DataTransfer.cpp.o b/build/CMakeFiles/unswsc.dir/DataTransfer.cpp.o index 62b4a9a..f08444b 100644 Binary files a/build/CMakeFiles/unswsc.dir/DataTransfer.cpp.o and b/build/CMakeFiles/unswsc.dir/DataTransfer.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/DependInfo.cmake b/build/CMakeFiles/unswsc.dir/DependInfo.cmake index aecf9d6..64d1532 100644 --- a/build/CMakeFiles/unswsc.dir/DependInfo.cmake +++ b/build/CMakeFiles/unswsc.dir/DependInfo.cmake @@ -25,6 +25,7 @@ set(CMAKE_DEPENDS_DEPENDENCY_FILES "/home/unknownobject/UNSWebServerCore/ServerProcessor.cpp" "CMakeFiles/unswsc.dir/ServerProcessor.cpp.o" "gcc" "CMakeFiles/unswsc.dir/ServerProcessor.cpp.o.d" "/home/unknownobject/UNSWebServerCore/SessionManager.cpp" "CMakeFiles/unswsc.dir/SessionManager.cpp.o" "gcc" "CMakeFiles/unswsc.dir/SessionManager.cpp.o.d" "/home/unknownobject/UNSWebServerCore/SyncFileReceiver.cpp" "CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o" "gcc" "CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d" + "/home/unknownobject/UNSWebServerCore/TempFileManager.cpp" "CMakeFiles/unswsc.dir/TempFileManager.cpp.o" "gcc" "CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d" "/home/unknownobject/UNSWebServerCore/UNSResponseBuilder.cpp" "CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o" "gcc" "CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d" "/home/unknownobject/UNSWebServerCore/WebFileInfo.cpp" "CMakeFiles/unswsc.dir/WebFileInfo.cpp.o" "gcc" "CMakeFiles/unswsc.dir/WebFileInfo.cpp.o.d" ) diff --git a/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o b/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o index 9cf0ded..23acdd9 100644 Binary files a/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o and b/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o.d b/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o.d index 2c3a76f..6b47771 100644 --- a/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/FileReceiver.cpp.o.d @@ -139,7 +139,11 @@ CMakeFiles/unswsc.dir/FileReceiver.cpp.o: \ /usr/include/c++/13/bits/stl_uninitialized.h \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/Export.h \ /home/unknownobject/UNSWebServerCore/DateTime.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ @@ -151,17 +155,15 @@ CMakeFiles/unswsc.dir/FileReceiver.cpp.o: \ /usr/include/c++/13/bits/stl_multiset.h \ /home/unknownobject/UNSWebServerCore/IPList.h \ /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ - /usr/include/c++/13/typeinfo /usr/include/c++/13/unordered_map \ + /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ - /usr/include/c++/13/bits/hashtable_policy.h \ - /usr/include/c++/13/bits/enable_special_members.h \ - /usr/include/c++/13/array /usr/include/c++/13/bits/stl_algo.h \ + /usr/include/c++/13/bits/hashtable_policy.h /usr/include/c++/13/array \ + /usr/include/c++/13/bits/stl_algo.h \ /usr/include/c++/13/bits/algorithmfwd.h \ /usr/include/c++/13/bits/stl_heap.h \ /usr/include/c++/13/bits/uniform_int_dist.h \ /usr/include/c++/13/bits/stl_tempbuf.h \ - /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ /home/unknownobject/UNSWebServerCore/HTTPObjects.h \ /usr/include/c++/13/memory \ /usr/include/c++/13/bits/stl_raw_storage_iter.h \ @@ -170,11 +172,8 @@ CMakeFiles/unswsc.dir/FileReceiver.cpp.o: \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/c++/13/bits/unique_ptr.h /usr/include/c++/13/ostream \ - /usr/include/c++/13/ios /usr/include/c++/13/exception \ - /usr/include/c++/13/bits/exception_ptr.h \ - /usr/include/c++/13/bits/cxxabi_init_exception.h \ - /usr/include/c++/13/bits/nested_exception.h \ - /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ios /usr/include/c++/13/bits/ios_base.h \ + /usr/include/c++/13/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ @@ -237,14 +236,31 @@ CMakeFiles/unswsc.dir/FileReceiver.cpp.o: \ /usr/include/c++/13/bits/ranges_algobase.h \ /usr/include/c++/13/pstl/glue_memory_defs.h \ /usr/include/c++/13/pstl/execution_defs.h /usr/include/c++/13/utility \ - /usr/include/c++/13/bits/stl_relops.h /usr/include/c++/13/cstring \ - /usr/include/string.h /usr/include/strings.h \ + /usr/include/c++/13/bits/stl_relops.h \ + /home/unknownobject/UNSWebServerCore/TempFileManager.h \ + /usr/include/c++/13/chrono /usr/include/c++/13/bits/chrono.h \ + /usr/include/c++/13/ratio /usr/include/c++/13/limits \ + /usr/include/c++/13/ctime /usr/include/c++/13/bits/parse_numbers.h \ + /usr/include/c++/13/sstream /usr/include/c++/13/istream \ + /usr/include/c++/13/bits/istream.tcc \ + /usr/include/c++/13/bits/sstream.tcc \ + /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/iomanip \ + /usr/include/c++/13/locale \ + /usr/include/c++/13/bits/locale_facets_nonio.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ + /usr/include/libintl.h /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/bits/locale_facets_nonio.tcc \ + /usr/include/c++/13/bits/locale_conv.h \ + /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ + /usr/include/c++/13/charconv /usr/include/c++/13/span \ + /usr/include/c++/13/variant \ + /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ + /usr/include/c++/13/cstring /usr/include/string.h /usr/include/strings.h \ /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/json.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/config.h \ - /usr/include/c++/13/istream /usr/include/c++/13/bits/istream.tcc \ - /usr/include/c++/13/sstream /usr/include/c++/13/bits/sstream.tcc \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/allocator.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/version.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/json_features.h \ @@ -256,37 +272,24 @@ CMakeFiles/unswsc.dir/FileReceiver.cpp.o: \ /usr/include/c++/13/bits/stl_stack.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/writer.h \ /home/unknownobject/UNSWebServerCore/ServerLogger.h \ - /usr/include/c++/13/mutex /usr/include/c++/13/bits/chrono.h \ - /usr/include/c++/13/ratio /usr/include/c++/13/limits \ - /usr/include/c++/13/ctime /usr/include/c++/13/bits/parse_numbers.h \ - /usr/include/c++/13/bits/unique_lock.h /usr/include/c++/13/thread \ - /usr/include/c++/13/stop_token /usr/include/c++/13/atomic \ - /usr/include/c++/13/bits/std_thread.h /usr/include/c++/13/semaphore \ - /usr/include/c++/13/bits/semaphore_base.h \ + /usr/include/c++/13/mutex /usr/include/c++/13/bits/unique_lock.h \ + /usr/include/c++/13/thread /usr/include/c++/13/stop_token \ + /usr/include/c++/13/atomic /usr/include/c++/13/bits/std_thread.h \ + /usr/include/c++/13/semaphore /usr/include/c++/13/bits/semaphore_base.h \ /usr/include/c++/13/bits/atomic_timed_wait.h \ /usr/include/c++/13/bits/this_thread_sleep.h \ /usr/include/x86_64-linux-gnu/sys/time.h /usr/include/semaphore.h \ /usr/include/x86_64-linux-gnu/bits/semaphore.h \ - /usr/include/c++/13/fstream /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/fstream \ /usr/include/x86_64-linux-gnu/c++/13/bits/basic_file.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/c++io.h \ /usr/include/c++/13/bits/fstream.tcc \ - /home/unknownobject/UNSWebServerCore/LogArg.h /usr/include/c++/13/chrono \ - /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/iomanip \ - /usr/include/c++/13/locale \ - /usr/include/c++/13/bits/locale_facets_nonio.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ - /usr/include/libintl.h /usr/include/c++/13/bits/locale_facets_nonio.tcc \ - /usr/include/c++/13/bits/locale_conv.h \ - /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ - /usr/include/c++/13/charconv /usr/include/c++/13/optional \ - /usr/include/c++/13/span /usr/include/c++/13/variant \ - /usr/include/c++/13/condition_variable \ - /home/unknownobject/UNSWebServerCore/PathTraversal.h \ + /home/unknownobject/UNSWebServerCore/LogArg.h \ /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ + /usr/include/c++/13/condition_variable \ + /home/unknownobject/UNSWebServerCore/PathTraversal.h \ /home/unknownobject/UNSWebServerCore/HTTPObjectsBridge.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/request.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/message.h \ diff --git a/build/CMakeFiles/unswsc.dir/Global.cpp.o b/build/CMakeFiles/unswsc.dir/Global.cpp.o index d6d027c..b89036f 100644 Binary files a/build/CMakeFiles/unswsc.dir/Global.cpp.o and b/build/CMakeFiles/unswsc.dir/Global.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/Global.cpp.o.d b/build/CMakeFiles/unswsc.dir/Global.cpp.o.d index ca7a239..5fca8ec 100644 --- a/build/CMakeFiles/unswsc.dir/Global.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/Global.cpp.o.d @@ -137,7 +137,11 @@ CMakeFiles/unswsc.dir/Global.cpp.o: \ /usr/include/c++/13/bits/stl_uninitialized.h \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/Export.h \ /home/unknownobject/UNSWebServerCore/DateTime.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ @@ -151,11 +155,8 @@ CMakeFiles/unswsc.dir/Global.cpp.o: \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/c++/13/bits/unique_ptr.h /usr/include/c++/13/ostream \ - /usr/include/c++/13/ios /usr/include/c++/13/exception \ - /usr/include/c++/13/bits/exception_ptr.h \ - /usr/include/c++/13/bits/cxxabi_init_exception.h \ - /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ - /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ios /usr/include/c++/13/bits/ios_base.h \ + /usr/include/c++/13/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ @@ -225,13 +226,11 @@ CMakeFiles/unswsc.dir/Global.cpp.o: \ /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ /usr/include/libintl.h /usr/include/c++/13/bits/codecvt.h \ /usr/include/c++/13/bits/locale_facets_nonio.tcc \ - /usr/include/c++/13/bits/locale_conv.h /usr/include/c++/13/optional \ - /usr/include/c++/13/bits/enable_special_members.h \ - /usr/include/c++/13/span /usr/include/c++/13/variant \ - /usr/include/c++/13/bits/parse_numbers.h /usr/include/c++/13/chrono \ - /usr/include/c++/13/bits/chrono.h /usr/include/c++/13/ratio \ - /usr/include/c++/13/sstream /usr/include/c++/13/istream \ - /usr/include/c++/13/bits/istream.tcc \ + /usr/include/c++/13/bits/locale_conv.h /usr/include/c++/13/span \ + /usr/include/c++/13/variant /usr/include/c++/13/bits/parse_numbers.h \ + /usr/include/c++/13/chrono /usr/include/c++/13/bits/chrono.h \ + /usr/include/c++/13/ratio /usr/include/c++/13/sstream \ + /usr/include/c++/13/istream /usr/include/c++/13/bits/istream.tcc \ /usr/include/c++/13/bits/sstream.tcc /usr/include/c++/13/bits/stl_algo.h \ /usr/include/c++/13/bits/algorithmfwd.h \ /usr/include/c++/13/bits/stl_heap.h \ diff --git a/build/CMakeFiles/unswsc.dir/HTTPObjects.cpp.o b/build/CMakeFiles/unswsc.dir/HTTPObjects.cpp.o index 76686ff..3f9672b 100644 Binary files a/build/CMakeFiles/unswsc.dir/HTTPObjects.cpp.o and b/build/CMakeFiles/unswsc.dir/HTTPObjects.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/LogArg.cpp.o.d b/build/CMakeFiles/unswsc.dir/LogArg.cpp.o.d index 02a8b7c..5143bb7 100644 --- a/build/CMakeFiles/unswsc.dir/LogArg.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/LogArg.cpp.o.d @@ -209,5 +209,8 @@ CMakeFiles/unswsc.dir/LogArg.cpp.o: \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ /usr/include/c++/13/bits/node_handle.h \ - /usr/include/c++/13/bits/erase_if.h \ + /usr/include/c++/13/bits/erase_if.h /usr/include/c++/13/filesystem \ + /usr/include/c++/13/bits/fs_fwd.h /usr/include/c++/13/bits/fs_path.h \ + /usr/include/c++/13/codecvt /usr/include/c++/13/bits/fs_dir.h \ + /usr/include/c++/13/bits/fs_ops.h \ /home/unknownobject/UNSWebServerCore/utextcodec/UTextCodec.h diff --git a/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o b/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o index d167ab1..2889f08 100644 Binary files a/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o and b/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o.d b/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o.d index 93bf5bf..5cd2dc5 100644 --- a/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/ServerCore.cpp.o.d @@ -225,7 +225,8 @@ CMakeFiles/unswsc.dir/ServerCore.cpp.o: \ /usr/include/c++/13/bits/erase_if.h /usr/include/c++/13/vector \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/Export.h \ /home/unknownobject/UNSWebServerCore/DateTime.h \ /home/unknownobject/UNSWebServerCore/FileReceiver.h \ @@ -237,15 +238,29 @@ CMakeFiles/unswsc.dir/ServerCore.cpp.o: \ /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ - /usr/include/c++/13/bits/hashtable_policy.h \ - /usr/include/c++/13/bits/enable_special_members.h \ - /usr/include/c++/13/array /usr/include/c++/13/bits/stl_algo.h \ + /usr/include/c++/13/bits/hashtable_policy.h /usr/include/c++/13/array \ + /usr/include/c++/13/bits/stl_algo.h \ /usr/include/c++/13/bits/algorithmfwd.h \ /usr/include/c++/13/bits/stl_heap.h \ /usr/include/c++/13/bits/uniform_int_dist.h \ - /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ /home/unknownobject/UNSWebServerCore/HTTPObjects.h \ /usr/include/c++/13/utility /usr/include/c++/13/bits/stl_relops.h \ + /home/unknownobject/UNSWebServerCore/TempFileManager.h \ + /usr/include/c++/13/chrono /usr/include/c++/13/sstream \ + /usr/include/c++/13/istream /usr/include/c++/13/bits/istream.tcc \ + /usr/include/c++/13/bits/sstream.tcc \ + /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/iomanip \ + /usr/include/c++/13/locale \ + /usr/include/c++/13/bits/locale_facets_nonio.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ + /usr/include/libintl.h /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/bits/locale_facets_nonio.tcc \ + /usr/include/c++/13/bits/locale_conv.h \ + /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ + /usr/include/c++/13/charconv /usr/include/c++/13/span \ + /usr/include/c++/13/variant \ + /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ /home/unknownobject/UNSWebServerCore/ServerProcessor.h \ /home/unknownobject/UNSWebServerCore/SyncFileReceiver.h \ /home/unknownobject/UNSWebServerCore/ServerLogger.h \ @@ -255,31 +270,19 @@ CMakeFiles/unswsc.dir/ServerCore.cpp.o: \ /usr/include/string.h /usr/include/strings.h \ /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ - /usr/include/c++/13/fstream /usr/include/c++/13/istream \ - /usr/include/c++/13/bits/istream.tcc /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/fstream \ /usr/include/x86_64-linux-gnu/c++/13/bits/basic_file.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/c++io.h \ /usr/include/c++/13/bits/fstream.tcc \ - /home/unknownobject/UNSWebServerCore/LogArg.h /usr/include/c++/13/chrono \ - /usr/include/c++/13/sstream /usr/include/c++/13/bits/sstream.tcc \ - /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/iomanip \ - /usr/include/c++/13/locale \ - /usr/include/c++/13/bits/locale_facets_nonio.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ - /usr/include/libintl.h /usr/include/c++/13/bits/locale_facets_nonio.tcc \ - /usr/include/c++/13/bits/locale_conv.h \ - /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ - /usr/include/c++/13/charconv /usr/include/c++/13/optional \ - /usr/include/c++/13/span /usr/include/c++/13/variant \ + /home/unknownobject/UNSWebServerCore/LogArg.h \ + /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ + /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ + /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ /usr/include/c++/13/condition_variable \ /home/unknownobject/UNSWebServerCore/CORSProcessor.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/logger.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/config.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/fs.h \ - /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ - /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ - /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/server.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/boost/asio/io_context.hpp \ /home/unknownobject/vcpkg/installed/x64-linux/include/boost/asio/detail/config.hpp \ @@ -972,10 +975,10 @@ CMakeFiles/unswsc.dir/ServerCore.cpp.o: \ /usr/include/c++/13/bits/regex_executor.tcc \ /home/unknownobject/UNSWebServerCore/webcc/webcc/request_parser.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/parser.h \ + /home/unknownobject/UNSWebServerCore/webcc/webcc/view.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/response.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/connection_pool.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/router.h \ - /home/unknownobject/UNSWebServerCore/webcc/webcc/view.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/utility.h \ /home/unknownobject/UNSWebServerCore/ProcessorAdapter.h \ /home/unknownobject/UNSWebServerCore/HTTPObjectsBridge.h \ diff --git a/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o b/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o index c993cc4..353e62a 100644 Binary files a/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o and b/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o.d b/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o.d index ad0a5a8..c900634 100644 --- a/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/ServerLogger.cpp.o.d @@ -251,8 +251,10 @@ CMakeFiles/unswsc.dir/ServerLogger.cpp.o: \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ /usr/include/c++/13/bits/node_handle.h \ - /usr/include/c++/13/bits/erase_if.h \ - /usr/include/c++/13/condition_variable \ + /usr/include/c++/13/bits/erase_if.h /usr/include/c++/13/filesystem \ + /usr/include/c++/13/bits/fs_fwd.h /usr/include/c++/13/bits/fs_path.h \ + /usr/include/c++/13/codecvt /usr/include/c++/13/bits/fs_dir.h \ + /usr/include/c++/13/bits/fs_ops.h /usr/include/c++/13/condition_variable \ /home/unknownobject/vcpkg/installed/x64-linux/include/fmt/format.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/fmt/base.h \ /usr/include/c++/13/cmath /usr/include/math.h \ diff --git a/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o b/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o index 9f4cf22..a0d0f76 100644 Binary files a/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o and b/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o.d b/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o.d index a80846a..6958f4e 100644 --- a/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/ServerProcessor.cpp.o.d @@ -139,7 +139,11 @@ CMakeFiles/unswsc.dir/ServerProcessor.cpp.o: \ /usr/include/c++/13/bits/stl_uninitialized.h \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/Export.h \ /home/unknownobject/UNSWebServerCore/DateTime.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ @@ -158,11 +162,8 @@ CMakeFiles/unswsc.dir/ServerProcessor.cpp.o: \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/c++/13/bits/unique_ptr.h /usr/include/c++/13/ostream \ - /usr/include/c++/13/ios /usr/include/c++/13/exception \ - /usr/include/c++/13/bits/exception_ptr.h \ - /usr/include/c++/13/bits/cxxabi_init_exception.h \ - /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ - /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ios /usr/include/c++/13/bits/ios_base.h \ + /usr/include/c++/13/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ @@ -263,19 +264,17 @@ CMakeFiles/unswsc.dir/ServerProcessor.cpp.o: \ /usr/include/c++/13/bits/locale_conv.h \ /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ /usr/include/c++/13/array /usr/include/c++/13/charconv \ - /usr/include/c++/13/optional \ - /usr/include/c++/13/bits/enable_special_members.h \ /usr/include/c++/13/span /usr/include/c++/13/variant \ /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ - /usr/include/c++/13/condition_variable \ - /home/unknownobject/UNSWebServerCore/PathTraversal.h \ /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ + /usr/include/c++/13/condition_variable \ + /home/unknownobject/UNSWebServerCore/PathTraversal.h \ /home/unknownobject/UNSWebServerCore/HTTPObjectsBridge.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/request.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/message.h \ diff --git a/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o b/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o index 955ae21..c2af248 100644 Binary files a/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o and b/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d b/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d index 7fbb3c3..adcd5bb 100644 --- a/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d @@ -140,7 +140,11 @@ CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o: \ /usr/include/c++/13/bits/stl_uninitialized.h \ /usr/include/c++/13/bits/stl_vector.h \ /usr/include/c++/13/bits/stl_bvector.h \ - /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/optional \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/DateTime.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ @@ -150,7 +154,6 @@ CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o: \ /usr/include/c++/13/bits/stl_set.h \ /usr/include/c++/13/bits/stl_multiset.h \ /home/unknownobject/UNSWebServerCore/IPList.h \ - /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ /home/unknownobject/UNSWebServerCore/HTTPObjects.h \ /usr/include/c++/13/memory /usr/include/c++/13/bits/stl_tempbuf.h \ /usr/include/c++/13/bits/stl_raw_storage_iter.h \ @@ -159,11 +162,8 @@ CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o: \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/c++/13/bits/unique_ptr.h /usr/include/c++/13/ostream \ - /usr/include/c++/13/ios /usr/include/c++/13/exception \ - /usr/include/c++/13/bits/exception_ptr.h \ - /usr/include/c++/13/bits/cxxabi_init_exception.h \ - /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ - /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ios /usr/include/c++/13/bits/ios_base.h \ + /usr/include/c++/13/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ @@ -226,42 +226,14 @@ CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o: \ /usr/include/c++/13/bits/ranges_algobase.h \ /usr/include/c++/13/pstl/glue_memory_defs.h \ /usr/include/c++/13/pstl/execution_defs.h /usr/include/c++/13/utility \ - /usr/include/c++/13/bits/stl_relops.h /usr/include/c++/13/cstring \ - /usr/include/string.h /usr/include/strings.h \ - /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ - /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/json.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/config.h \ - /usr/include/c++/13/istream /usr/include/c++/13/bits/istream.tcc \ - /usr/include/c++/13/sstream /usr/include/c++/13/bits/sstream.tcc \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/allocator.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/version.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/json_features.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/forwards.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/reader.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/value.h \ - /usr/include/c++/13/array /usr/include/c++/13/deque \ - /usr/include/c++/13/bits/stl_deque.h /usr/include/c++/13/bits/deque.tcc \ - /usr/include/c++/13/stack /usr/include/c++/13/bits/stl_stack.h \ - /home/unknownobject/vcpkg/installed/x64-linux/include/json/writer.h \ - /home/unknownobject/UNSWebServerCore/ServerLogger.h \ - /usr/include/c++/13/mutex /usr/include/c++/13/bits/chrono.h \ + /usr/include/c++/13/bits/stl_relops.h \ + /home/unknownobject/UNSWebServerCore/TempFileManager.h \ + /usr/include/c++/13/chrono /usr/include/c++/13/bits/chrono.h \ /usr/include/c++/13/ratio /usr/include/c++/13/limits \ /usr/include/c++/13/ctime /usr/include/c++/13/bits/parse_numbers.h \ - /usr/include/c++/13/bits/unique_lock.h /usr/include/c++/13/thread \ - /usr/include/c++/13/stop_token /usr/include/c++/13/atomic \ - /usr/include/c++/13/bits/std_thread.h /usr/include/c++/13/semaphore \ - /usr/include/c++/13/bits/semaphore_base.h \ - /usr/include/c++/13/bits/atomic_timed_wait.h \ - /usr/include/c++/13/bits/this_thread_sleep.h \ - /usr/include/x86_64-linux-gnu/sys/time.h /usr/include/semaphore.h \ - /usr/include/x86_64-linux-gnu/bits/semaphore.h \ - /usr/include/c++/13/fstream /usr/include/c++/13/bits/codecvt.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/basic_file.h \ - /usr/include/x86_64-linux-gnu/c++/13/bits/c++io.h \ - /usr/include/c++/13/bits/fstream.tcc \ - /home/unknownobject/UNSWebServerCore/LogArg.h /usr/include/c++/13/chrono \ - /usr/include/c++/13/bits/stl_algo.h \ + /usr/include/c++/13/sstream /usr/include/c++/13/istream \ + /usr/include/c++/13/bits/istream.tcc \ + /usr/include/c++/13/bits/sstream.tcc /usr/include/c++/13/bits/stl_algo.h \ /usr/include/c++/13/bits/algorithmfwd.h \ /usr/include/c++/13/bits/stl_heap.h \ /usr/include/c++/13/bits/uniform_int_dist.h \ @@ -270,22 +242,52 @@ CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o: \ /usr/include/c++/13/bits/locale_facets_nonio.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ - /usr/include/libintl.h /usr/include/c++/13/bits/locale_facets_nonio.tcc \ + /usr/include/libintl.h /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/bits/locale_facets_nonio.tcc \ /usr/include/c++/13/bits/locale_conv.h \ /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ - /usr/include/c++/13/charconv /usr/include/c++/13/optional \ - /usr/include/c++/13/bits/enable_special_members.h \ + /usr/include/c++/13/array /usr/include/c++/13/charconv \ /usr/include/c++/13/span /usr/include/c++/13/variant \ + /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ + /usr/include/c++/13/cstring /usr/include/string.h /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/json.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/config.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/allocator.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/version.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/json_features.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/forwards.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/reader.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/value.h \ + /usr/include/c++/13/deque /usr/include/c++/13/bits/stl_deque.h \ + /usr/include/c++/13/bits/deque.tcc /usr/include/c++/13/stack \ + /usr/include/c++/13/bits/stl_stack.h \ + /home/unknownobject/vcpkg/installed/x64-linux/include/json/writer.h \ + /home/unknownobject/UNSWebServerCore/ServerLogger.h \ + /usr/include/c++/13/mutex /usr/include/c++/13/bits/unique_lock.h \ + /usr/include/c++/13/thread /usr/include/c++/13/stop_token \ + /usr/include/c++/13/atomic /usr/include/c++/13/bits/std_thread.h \ + /usr/include/c++/13/semaphore /usr/include/c++/13/bits/semaphore_base.h \ + /usr/include/c++/13/bits/atomic_timed_wait.h \ + /usr/include/c++/13/bits/this_thread_sleep.h \ + /usr/include/x86_64-linux-gnu/sys/time.h /usr/include/semaphore.h \ + /usr/include/x86_64-linux-gnu/bits/semaphore.h \ + /usr/include/c++/13/fstream \ + /usr/include/x86_64-linux-gnu/c++/13/bits/basic_file.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++io.h \ + /usr/include/c++/13/bits/fstream.tcc \ + /home/unknownobject/UNSWebServerCore/LogArg.h \ /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ /usr/include/c++/13/bits/hashtable_policy.h \ - /usr/include/c++/13/condition_variable \ - /home/unknownobject/UNSWebServerCore/PathTraversal.h \ /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ + /usr/include/c++/13/condition_variable \ + /home/unknownobject/UNSWebServerCore/PathTraversal.h \ /home/unknownobject/UNSWebServerCore/HTTPObjectsBridge.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/request.h \ /home/unknownobject/UNSWebServerCore/webcc/webcc/message.h \ diff --git a/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o b/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o new file mode 100644 index 0000000..aa0eb32 Binary files /dev/null and b/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d b/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d new file mode 100644 index 0000000..0cb7ddf --- /dev/null +++ b/build/CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d @@ -0,0 +1,270 @@ +CMakeFiles/unswsc.dir/TempFileManager.cpp.o: \ + /home/unknownobject/UNSWebServerCore/TempFileManager.cpp \ + /usr/include/stdc-predef.h \ + /home/unknownobject/UNSWebServerCore/TempFileManager.h \ + /usr/include/c++/13/map /usr/include/c++/13/bits/requires_hosted.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/os_defines.h \ + /usr/include/features.h /usr/include/features-time64.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/cpu_defines.h \ + /usr/include/c++/13/pstl/pstl_config.h \ + /usr/include/c++/13/bits/stl_tree.h \ + /usr/include/c++/13/bits/stl_algobase.h \ + /usr/include/c++/13/bits/functexcept.h \ + /usr/include/c++/13/bits/exception_defines.h \ + /usr/include/c++/13/bits/cpp_type_traits.h \ + /usr/include/c++/13/ext/type_traits.h \ + /usr/include/c++/13/ext/numeric_traits.h \ + /usr/include/c++/13/bits/stl_pair.h /usr/include/c++/13/type_traits \ + /usr/include/c++/13/bits/move.h /usr/include/c++/13/bits/utility.h \ + /usr/include/c++/13/compare /usr/include/c++/13/concepts \ + /usr/include/c++/13/bits/stl_iterator_base_types.h \ + /usr/include/c++/13/bits/iterator_concepts.h \ + /usr/include/c++/13/bits/ptr_traits.h \ + /usr/include/c++/13/bits/ranges_cmp.h \ + /usr/include/c++/13/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/13/bits/concept_check.h \ + /usr/include/c++/13/debug/assertions.h \ + /usr/include/c++/13/bits/stl_iterator.h /usr/include/c++/13/new \ + /usr/include/c++/13/bits/exception.h \ + /usr/include/c++/13/bits/stl_construct.h \ + /usr/include/c++/13/debug/debug.h \ + /usr/include/c++/13/bits/predefined_ops.h /usr/include/c++/13/bit \ + /usr/include/c++/13/bits/allocator.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++allocator.h \ + /usr/include/c++/13/bits/new_allocator.h \ + /usr/include/c++/13/bits/memoryfwd.h \ + /usr/include/c++/13/bits/stl_function.h \ + /usr/include/c++/13/backward/binders.h \ + /usr/include/c++/13/ext/alloc_traits.h \ + /usr/include/c++/13/bits/alloc_traits.h \ + /usr/include/c++/13/ext/aligned_buffer.h \ + /usr/include/c++/13/bits/node_handle.h \ + /usr/include/c++/13/bits/stl_map.h /usr/include/c++/13/initializer_list \ + /usr/include/c++/13/tuple /usr/include/c++/13/bits/uses_allocator.h \ + /usr/include/c++/13/bits/invoke.h /usr/include/c++/13/bits/ranges_util.h \ + /usr/include/c++/13/bits/ranges_base.h \ + /usr/include/c++/13/bits/max_size_type.h /usr/include/c++/13/numbers \ + /usr/include/c++/13/bits/stl_multimap.h \ + /usr/include/c++/13/bits/range_access.h \ + /usr/include/c++/13/bits/erase_if.h \ + /usr/include/c++/13/bits/memory_resource.h /usr/include/c++/13/cstddef \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stddef.h \ + /usr/include/c++/13/bits/uses_allocator_args.h \ + /usr/include/c++/13/string /usr/include/c++/13/bits/stringfwd.h \ + /usr/include/c++/13/bits/char_traits.h \ + /usr/include/c++/13/bits/postypes.h /usr/include/c++/13/cwchar \ + /usr/include/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h \ + /usr/include/c++/13/bits/localefwd.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++locale.h \ + /usr/include/c++/13/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/13/iosfwd \ + /usr/include/c++/13/cctype /usr/include/ctype.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/c++/13/bits/ostream_insert.h \ + /usr/include/c++/13/bits/cxxabi_forced.h \ + /usr/include/c++/13/bits/refwrap.h \ + /usr/include/c++/13/bits/basic_string.h /usr/include/c++/13/string_view \ + /usr/include/c++/13/bits/functional_hash.h \ + /usr/include/c++/13/bits/hash_bytes.h \ + /usr/include/c++/13/bits/string_view.tcc \ + /usr/include/c++/13/ext/string_conversions.h /usr/include/c++/13/cstdlib \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/select-decl.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/c++/13/bits/std_abs.h /usr/include/c++/13/cstdio \ + /usr/include/stdio.h /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/c++/13/cerrno \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/c++/13/bits/charconv.h \ + /usr/include/c++/13/bits/basic_string.tcc /usr/include/c++/13/chrono \ + /usr/include/c++/13/bits/chrono.h /usr/include/c++/13/ratio \ + /usr/include/c++/13/cstdint \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/c++/13/limits /usr/include/c++/13/ctime /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/c++/13/bits/parse_numbers.h /usr/include/c++/13/sstream \ + /usr/include/c++/13/istream /usr/include/c++/13/ios \ + /usr/include/c++/13/exception /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/typeinfo /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/ios_base.h /usr/include/c++/13/ext/atomicity.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/c++/13/bits/locale_classes.h \ + /usr/include/c++/13/bits/locale_classes.tcc \ + /usr/include/c++/13/system_error \ + /usr/include/x86_64-linux-gnu/c++/13/bits/error_constants.h \ + /usr/include/c++/13/stdexcept /usr/include/c++/13/streambuf \ + /usr/include/c++/13/bits/streambuf.tcc \ + /usr/include/c++/13/bits/basic_ios.h \ + /usr/include/c++/13/bits/locale_facets.h /usr/include/c++/13/cwctype \ + /usr/include/wctype.h /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/ctype_base.h \ + /usr/include/c++/13/bits/streambuf_iterator.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/ctype_inline.h \ + /usr/include/c++/13/bits/locale_facets.tcc \ + /usr/include/c++/13/bits/basic_ios.tcc /usr/include/c++/13/ostream \ + /usr/include/c++/13/bits/ostream.tcc \ + /usr/include/c++/13/bits/istream.tcc \ + /usr/include/c++/13/bits/sstream.tcc /usr/include/c++/13/vector \ + /usr/include/c++/13/bits/stl_uninitialized.h \ + /usr/include/c++/13/bits/stl_vector.h \ + /usr/include/c++/13/bits/stl_bvector.h \ + /usr/include/c++/13/bits/vector.tcc /usr/include/c++/13/bits/stl_algo.h \ + /usr/include/c++/13/bits/algorithmfwd.h \ + /usr/include/c++/13/bits/stl_heap.h \ + /usr/include/c++/13/bits/uniform_int_dist.h \ + /usr/include/c++/13/bits/stl_tempbuf.h \ + /usr/include/c++/13/bits/shared_ptr.h \ + /usr/include/c++/13/bits/shared_ptr_base.h \ + /usr/include/c++/13/bits/allocated_ptr.h \ + /usr/include/c++/13/bits/unique_ptr.h \ + /usr/include/c++/13/ext/concurrence.h /usr/include/c++/13/bits/align.h \ + /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/iomanip \ + /usr/include/c++/13/locale \ + /usr/include/c++/13/bits/locale_facets_nonio.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/messages_members.h \ + /usr/include/libintl.h /usr/include/c++/13/bits/codecvt.h \ + /usr/include/c++/13/bits/locale_facets_nonio.tcc \ + /usr/include/c++/13/bits/locale_conv.h \ + /usr/include/c++/13/bits/quoted_string.h /usr/include/c++/13/format \ + /usr/include/c++/13/array /usr/include/c++/13/charconv \ + /usr/include/c++/13/optional \ + /usr/include/c++/13/bits/enable_special_members.h \ + /usr/include/c++/13/span /usr/include/c++/13/variant \ + /usr/include/c++/13/bits/ranges_algobase.h /usr/include/c++/13/memory \ + /usr/include/c++/13/bits/stl_raw_storage_iter.h \ + /usr/include/c++/13/bits/shared_ptr_atomic.h \ + /usr/include/c++/13/bits/atomic_base.h \ + /usr/include/c++/13/bits/atomic_lockfree_defines.h \ + /usr/include/c++/13/bits/atomic_wait.h /usr/include/c++/13/climits \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/linux/close_range.h /usr/include/syscall.h \ + /usr/include/x86_64-linux-gnu/sys/syscall.h \ + /usr/include/x86_64-linux-gnu/asm/unistd.h \ + /usr/include/x86_64-linux-gnu/asm/unistd_64.h \ + /usr/include/x86_64-linux-gnu/bits/syscall.h \ + /usr/include/c++/13/bits/std_mutex.h \ + /usr/include/c++/13/backward/auto_ptr.h \ + /usr/include/c++/13/bits/ranges_uninitialized.h \ + /usr/include/c++/13/pstl/glue_memory_defs.h \ + /usr/include/c++/13/pstl/execution_defs.h \ + /home/unknownobject/UNSWebServerCore/Export.h \ + /home/unknownobject/UNSWebServerCore/WebFileInfo.h \ + /home/unknownobject/UNSWebServerCore/DateTime.h \ + /usr/include/c++/13/thread /usr/include/c++/13/stop_token \ + /usr/include/c++/13/atomic /usr/include/c++/13/bits/std_thread.h \ + /usr/include/c++/13/semaphore /usr/include/c++/13/bits/semaphore_base.h \ + /usr/include/c++/13/bits/atomic_timed_wait.h \ + /usr/include/c++/13/bits/this_thread_sleep.h \ + /usr/include/x86_64-linux-gnu/sys/time.h /usr/include/semaphore.h \ + /usr/include/x86_64-linux-gnu/bits/semaphore.h \ + /usr/include/c++/13/filesystem /usr/include/c++/13/bits/fs_fwd.h \ + /usr/include/c++/13/bits/fs_path.h /usr/include/c++/13/codecvt \ + /usr/include/c++/13/bits/fs_dir.h /usr/include/c++/13/bits/fs_ops.h \ + /usr/include/c++/13/shared_mutex /usr/include/c++/13/unordered_map \ + /usr/include/c++/13/bits/unordered_map.h \ + /usr/include/c++/13/bits/hashtable.h \ + /usr/include/c++/13/bits/hashtable_policy.h \ + /home/unknownobject/UNSWebServerCore/ServerLogger.h \ + /usr/include/c++/13/deque /usr/include/c++/13/bits/stl_deque.h \ + /usr/include/c++/13/bits/deque.tcc /usr/include/c++/13/mutex \ + /usr/include/c++/13/bits/unique_lock.h /usr/include/c++/13/cstring \ + /usr/include/string.h /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/c++/13/fstream \ + /usr/include/x86_64-linux-gnu/c++/13/bits/basic_file.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++io.h \ + /usr/include/c++/13/bits/fstream.tcc \ + /home/unknownobject/UNSWebServerCore/LogArg.h \ + /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ + /usr/include/c++/13/condition_variable diff --git a/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o b/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o index d67ef33..76543e9 100644 Binary files a/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o and b/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d b/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d index 10ebd1c..93f126b 100644 --- a/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d +++ b/build/CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d @@ -235,7 +235,8 @@ CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o: \ /usr/include/c++/13/bits/stl_relops.h \ /home/unknownobject/UNSWebServerCore/Global.h /usr/include/c++/13/map \ /usr/include/c++/13/bits/stl_map.h \ - /usr/include/c++/13/bits/stl_multimap.h \ + /usr/include/c++/13/bits/stl_multimap.h /usr/include/c++/13/optional \ + /usr/include/c++/13/bits/enable_special_members.h \ /home/unknownobject/UNSWebServerCore/DateTime.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/json.h \ /home/unknownobject/vcpkg/installed/x64-linux/include/json/config.h \ @@ -272,10 +273,9 @@ CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o: \ /usr/include/c++/13/bits/stl_heap.h \ /usr/include/c++/13/bits/uniform_int_dist.h \ /usr/include/c++/13/bits/chrono_io.h /usr/include/c++/13/format \ - /usr/include/c++/13/charconv /usr/include/c++/13/optional \ - /usr/include/c++/13/bits/enable_special_members.h \ - /usr/include/c++/13/span /usr/include/c++/13/variant \ - /usr/include/c++/13/functional /usr/include/c++/13/bits/std_function.h \ + /usr/include/c++/13/charconv /usr/include/c++/13/span \ + /usr/include/c++/13/variant /usr/include/c++/13/functional \ + /usr/include/c++/13/bits/std_function.h \ /usr/include/c++/13/unordered_map \ /usr/include/c++/13/bits/unordered_map.h \ /usr/include/c++/13/bits/hashtable.h \ diff --git a/build/CMakeFiles/unswsc.dir/WebFileInfo.cpp.o b/build/CMakeFiles/unswsc.dir/WebFileInfo.cpp.o index 153ebd7..b9d0687 100644 Binary files a/build/CMakeFiles/unswsc.dir/WebFileInfo.cpp.o and b/build/CMakeFiles/unswsc.dir/WebFileInfo.cpp.o differ diff --git a/build/CMakeFiles/unswsc.dir/build.make b/build/CMakeFiles/unswsc.dir/build.make index 3378176..fd03757 100644 --- a/build/CMakeFiles/unswsc.dir/build.make +++ b/build/CMakeFiles/unswsc.dir/build.make @@ -335,6 +335,20 @@ CMakeFiles/unswsc.dir/PathTraversal.cpp.s: cmake_force @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/unswsc.dir/PathTraversal.cpp.s" /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/unknownobject/UNSWebServerCore/PathTraversal.cpp -o CMakeFiles/unswsc.dir/PathTraversal.cpp.s +CMakeFiles/unswsc.dir/TempFileManager.cpp.o: CMakeFiles/unswsc.dir/flags.make +CMakeFiles/unswsc.dir/TempFileManager.cpp.o: /home/unknownobject/UNSWebServerCore/TempFileManager.cpp +CMakeFiles/unswsc.dir/TempFileManager.cpp.o: CMakeFiles/unswsc.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/unknownobject/UNSWebServerCore/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_20) "Building CXX object CMakeFiles/unswsc.dir/TempFileManager.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/unswsc.dir/TempFileManager.cpp.o -MF CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d -o CMakeFiles/unswsc.dir/TempFileManager.cpp.o -c /home/unknownobject/UNSWebServerCore/TempFileManager.cpp + +CMakeFiles/unswsc.dir/TempFileManager.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/unswsc.dir/TempFileManager.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/unknownobject/UNSWebServerCore/TempFileManager.cpp > CMakeFiles/unswsc.dir/TempFileManager.cpp.i + +CMakeFiles/unswsc.dir/TempFileManager.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/unswsc.dir/TempFileManager.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/unknownobject/UNSWebServerCore/TempFileManager.cpp -o CMakeFiles/unswsc.dir/TempFileManager.cpp.s + # Object files for target unswsc unswsc_OBJECTS = \ "CMakeFiles/unswsc.dir/CORSConfig.cpp.o" \ @@ -355,7 +369,8 @@ unswsc_OBJECTS = \ "CMakeFiles/unswsc.dir/ServerCore.cpp.o" \ "CMakeFiles/unswsc.dir/SafeRNG.cpp.o" \ "CMakeFiles/unswsc.dir/HTTPObjects.cpp.o" \ -"CMakeFiles/unswsc.dir/PathTraversal.cpp.o" +"CMakeFiles/unswsc.dir/PathTraversal.cpp.o" \ +"CMakeFiles/unswsc.dir/TempFileManager.cpp.o" # External object files for target unswsc unswsc_EXTERNAL_OBJECTS = @@ -379,6 +394,7 @@ libunswsc.so: CMakeFiles/unswsc.dir/ServerCore.cpp.o libunswsc.so: CMakeFiles/unswsc.dir/SafeRNG.cpp.o libunswsc.so: CMakeFiles/unswsc.dir/HTTPObjects.cpp.o libunswsc.so: CMakeFiles/unswsc.dir/PathTraversal.cpp.o +libunswsc.so: CMakeFiles/unswsc.dir/TempFileManager.cpp.o libunswsc.so: CMakeFiles/unswsc.dir/build.make libunswsc.so: /home/unknownobject/UNSWebServerCore/lib/libwebcc.a libunswsc.so: /home/unknownobject/UNSWebServerCore/so/libuohash.so @@ -388,7 +404,7 @@ libunswsc.so: /home/unknownobject/vcpkg/installed/x64-linux/debug/lib/libcrypto. libunswsc.so: /home/unknownobject/vcpkg/installed/x64-linux/lib/libsodium.a libunswsc.so: /home/unknownobject/vcpkg/installed/x64-linux/lib/libjsoncpp.a libunswsc.so: CMakeFiles/unswsc.dir/link.txt - @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/unknownobject/UNSWebServerCore/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_20) "Linking CXX shared library libunswsc.so" + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/unknownobject/UNSWebServerCore/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_21) "Linking CXX shared library libunswsc.so" $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/unswsc.dir/link.txt --verbose=$(VERBOSE) # Rule to build all files generated by this target. diff --git a/build/CMakeFiles/unswsc.dir/cmake_clean.cmake b/build/CMakeFiles/unswsc.dir/cmake_clean.cmake index fdb881d..053aee2 100644 --- a/build/CMakeFiles/unswsc.dir/cmake_clean.cmake +++ b/build/CMakeFiles/unswsc.dir/cmake_clean.cmake @@ -33,6 +33,8 @@ file(REMOVE_RECURSE "CMakeFiles/unswsc.dir/SessionManager.cpp.o.d" "CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o" "CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o.d" + "CMakeFiles/unswsc.dir/TempFileManager.cpp.o" + "CMakeFiles/unswsc.dir/TempFileManager.cpp.o.d" "CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o" "CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o.d" "CMakeFiles/unswsc.dir/WebFileInfo.cpp.o" diff --git a/build/CMakeFiles/unswsc.dir/link.txt b/build/CMakeFiles/unswsc.dir/link.txt index 7b0bf2a..6c415dc 100644 --- a/build/CMakeFiles/unswsc.dir/link.txt +++ b/build/CMakeFiles/unswsc.dir/link.txt @@ -1 +1 @@ -/usr/bin/c++ -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libunswsc.so -o libunswsc.so CMakeFiles/unswsc.dir/CORSConfig.cpp.o CMakeFiles/unswsc.dir/SessionManager.cpp.o CMakeFiles/unswsc.dir/WebFileInfo.cpp.o CMakeFiles/unswsc.dir/ServerProcessor.cpp.o CMakeFiles/unswsc.dir/CORSProcessor.cpp.o CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o CMakeFiles/unswsc.dir/DateTime.cpp.o CMakeFiles/unswsc.dir/IPTable.cpp.o CMakeFiles/unswsc.dir/IPList.cpp.o CMakeFiles/unswsc.dir/Global.cpp.o CMakeFiles/unswsc.dir/FileReceiver.cpp.o CMakeFiles/unswsc.dir/DataTransfer.cpp.o CMakeFiles/unswsc.dir/ServerLogger.cpp.o CMakeFiles/unswsc.dir/LogArg.cpp.o CMakeFiles/unswsc.dir/ServerCore.cpp.o CMakeFiles/unswsc.dir/SafeRNG.cpp.o CMakeFiles/unswsc.dir/HTTPObjects.cpp.o CMakeFiles/unswsc.dir/PathTraversal.cpp.o -Wl,-rpath,/home/unknownobject/UNSWebServerCore/so /home/unknownobject/UNSWebServerCore/lib/libwebcc.a /home/unknownobject/UNSWebServerCore/so/libuohash.so /home/unknownobject/UNSWebServerCore/so/libutextcodec.so /home/unknownobject/vcpkg/installed/x64-linux/lib/libfmt.a /home/unknownobject/vcpkg/installed/x64-linux/debug/lib/libcrypto.a /home/unknownobject/vcpkg/installed/x64-linux/lib/libsodium.a -ldl /home/unknownobject/vcpkg/installed/x64-linux/lib/libjsoncpp.a +/usr/bin/c++ -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libunswsc.so -o libunswsc.so CMakeFiles/unswsc.dir/CORSConfig.cpp.o CMakeFiles/unswsc.dir/SessionManager.cpp.o CMakeFiles/unswsc.dir/WebFileInfo.cpp.o CMakeFiles/unswsc.dir/ServerProcessor.cpp.o CMakeFiles/unswsc.dir/CORSProcessor.cpp.o CMakeFiles/unswsc.dir/UNSResponseBuilder.cpp.o CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.o CMakeFiles/unswsc.dir/DateTime.cpp.o CMakeFiles/unswsc.dir/IPTable.cpp.o CMakeFiles/unswsc.dir/IPList.cpp.o CMakeFiles/unswsc.dir/Global.cpp.o CMakeFiles/unswsc.dir/FileReceiver.cpp.o CMakeFiles/unswsc.dir/DataTransfer.cpp.o CMakeFiles/unswsc.dir/ServerLogger.cpp.o CMakeFiles/unswsc.dir/LogArg.cpp.o CMakeFiles/unswsc.dir/ServerCore.cpp.o CMakeFiles/unswsc.dir/SafeRNG.cpp.o CMakeFiles/unswsc.dir/HTTPObjects.cpp.o CMakeFiles/unswsc.dir/PathTraversal.cpp.o CMakeFiles/unswsc.dir/TempFileManager.cpp.o -Wl,-rpath,/home/unknownobject/UNSWebServerCore/so /home/unknownobject/UNSWebServerCore/lib/libwebcc.a /home/unknownobject/UNSWebServerCore/so/libuohash.so /home/unknownobject/UNSWebServerCore/so/libutextcodec.so /home/unknownobject/vcpkg/installed/x64-linux/lib/libfmt.a /home/unknownobject/vcpkg/installed/x64-linux/debug/lib/libcrypto.a /home/unknownobject/vcpkg/installed/x64-linux/lib/libsodium.a -ldl /home/unknownobject/vcpkg/installed/x64-linux/lib/libjsoncpp.a diff --git a/build/CMakeFiles/unswsc.dir/progress.make b/build/CMakeFiles/unswsc.dir/progress.make index 5a01af2..0259f92 100644 --- a/build/CMakeFiles/unswsc.dir/progress.make +++ b/build/CMakeFiles/unswsc.dir/progress.make @@ -18,4 +18,5 @@ CMAKE_PROGRESS_17 = 24 CMAKE_PROGRESS_18 = 25 CMAKE_PROGRESS_19 = 26 CMAKE_PROGRESS_20 = 27 +CMAKE_PROGRESS_21 = 28 diff --git a/build/Makefile b/build/Makefile index fb09b24..384bb3a 100644 --- a/build/Makefile +++ b/build/Makefile @@ -606,6 +606,30 @@ SyncFileReceiver.cpp.s: $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/SyncFileReceiver.cpp.s .PHONY : SyncFileReceiver.cpp.s +TempFileManager.o: TempFileManager.cpp.o +.PHONY : TempFileManager.o + +# target to build an object file +TempFileManager.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/TempFileManager.cpp.o +.PHONY : TempFileManager.cpp.o + +TempFileManager.i: TempFileManager.cpp.i +.PHONY : TempFileManager.i + +# target to preprocess a source file +TempFileManager.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/TempFileManager.cpp.i +.PHONY : TempFileManager.cpp.i + +TempFileManager.s: TempFileManager.cpp.s +.PHONY : TempFileManager.s + +# target to generate assembly for a file +TempFileManager.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/unswsc.dir/build.make CMakeFiles/unswsc.dir/TempFileManager.cpp.s +.PHONY : TempFileManager.cpp.s + TestLogger.o: TestLogger.cpp.o .PHONY : TestLogger.o @@ -744,6 +768,9 @@ help: @echo "... SyncFileReceiver.o" @echo "... SyncFileReceiver.i" @echo "... SyncFileReceiver.s" + @echo "... TempFileManager.o" + @echo "... TempFileManager.i" + @echo "... TempFileManager.s" @echo "... TestLogger.o" @echo "... TestLogger.i" @echo "... TestLogger.s" diff --git a/build/libunswsc.so b/build/libunswsc.so index 7b3dbef..71bf2c4 100755 Binary files a/build/libunswsc.so and b/build/libunswsc.so differ diff --git a/build/logger_test b/build/logger_test index 51641b7..e6dcad1 100755 Binary files a/build/logger_test and b/build/logger_test differ diff --git a/build/so/libunswsc.so b/build/so/libunswsc.so index 7b3dbef..71bf2c4 100755 Binary files a/build/so/libunswsc.so and b/build/so/libunswsc.so differ diff --git a/build/unswsc/FileReceiver.h b/build/unswsc/FileReceiver.h index e1b782a..6d95641 100644 --- a/build/unswsc/FileReceiver.h +++ b/build/unswsc/FileReceiver.h @@ -2,10 +2,10 @@ #include "Global.h" #include "IPTable.h" #include -#include "WebFileInfo.h" #include "HTTPObjects.h" +#include "TempFileManager.h" -using FileProcessorCallback = std::function; +using FileProcessorCallback = std::function; class UNSWSC_DLL_EXPORT FileReceiver { @@ -29,12 +29,19 @@ public: uns::HTTPMethod GetMethod(uns::RequestPtr request); void AppenedBlockedIP(DateTime::Span block_time, std::string ip); bool WriteFile(const std::string& path, const std::string& bytes); + void SetFileTimeout(std::chrono::seconds timeout = 0s, std::chrono::seconds max_proc_timeout = 0s) noexcept; public: + // 请求信息预检,重载以在保存文件之前检查请求体 virtual uns::Status PreCheckRequest(uns::RequestPtr request) = 0; + // 表单预检,重载以在处理表单前检查表单 virtual bool PreCheckForm(uns::FormPartPtr form) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); public: // 核心驱动入口:供内部适配器调用的实际执行流 diff --git a/build/unswsc/Global.h b/build/unswsc/Global.h index 21cb029..f8c32c1 100644 --- a/build/unswsc/Global.h +++ b/build/unswsc/Global.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "Export.h" #include "DateTime.h" @@ -35,6 +36,11 @@ constexpr auto G_ERROR_PAGE = R"( // inline constexpr std::string_view G_HTTP_STD_WEEK[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +namespace Json +{ + class Value; +} + namespace uns { enum HTTPMethod @@ -65,6 +71,8 @@ namespace uns inline constexpr std::string_view resh_acma = "Access-Control-Max-Age"; }; + inline constexpr auto url_all = R"(/[\s\S]*)"; + using POSTArgs = std::map; std::string UNSWSC_DLL_EXPORT EncodeErrorPage(int code); @@ -93,6 +101,23 @@ namespace uns std::string UNSWSC_DLL_EXPORT ToLower(const std::string& s); std::string UNSWSC_DLL_EXPORT CalculateFileHashSHA256(const std::string& file); + + Json::Value UNSWSC_DLL_EXPORT SafeJsonDecode(const std::string& str); + + template + std::optional UNSWSC_DLL_EXPORT SafeStoX(const std::basic_string& str, std::size_t* pos = nullptr, int base = 10); + template + std::optional UNSWSC_DLL_EXPORT SafeStoX(std::basic_string_view str, std::size_t* pos = nullptr, int base = 10); + template + inline std::optional SafeStoX(const CharT* str, std::size_t* pos = nullptr, int base = 10) + { +#if defined(__cpp_char8_t) + if constexpr (std::is_same_v) + return SafeStoX(std::basic_string(reinterpret_cast(str)), pos, base); // 只有 u8"..." (char8_t) 强制转为 char 版本的 SafeStoX 处理 + else +#endif + return SafeStoX(std::basic_string(str), pos, base); // 普通 "..." (char) 和 L"..." (wchar_t) 保持各自类型,构造对应的 basic_string + } } namespace secure @@ -103,7 +128,7 @@ namespace uns * @param requested_path 客户端传入的、解码后的目标子路径 * @return true 安全(在沙盒内);false 不安全(企图穿越或路径非法) */ - bool IsSafePath(const std::string& safe_path, const std::string& requested_path); + bool IsSafePath(const std::string& safe_path, const std::string& requested_path); } }; diff --git a/build/unswsc/LogArg.h b/build/unswsc/LogArg.h index 53f7af5..11b0e43 100644 --- a/build/unswsc/LogArg.h +++ b/build/unswsc/LogArg.h @@ -6,6 +6,7 @@ #include #include "Export.h" #include +#include #include #include @@ -217,6 +218,8 @@ namespace uns else if constexpr (std::is_pointer_v) value = static_cast(val); // 7. 标准库容器(关键点:利用 Lambda 闭包在不引入 fmt 的情况下擦除容器类型!) + else if constexpr (std::is_same::value) + value = ConvertWStringToUtf8(val.generic_wstring()); else if constexpr (is_container::value) { value = RangeCapturer{ &val, [] (const void* p, std::vector& out) diff --git a/build/unswsc/ServerCore.h b/build/unswsc/ServerCore.h index 61e4685..bce4d40 100644 --- a/build/unswsc/ServerCore.h +++ b/build/unswsc/ServerCore.h @@ -1,4 +1,4 @@ -/* +/* * Unknown Network Service Web Server Core * Version 1.2.2 * diff --git a/build/unswsc/ServerProcessor.h b/build/unswsc/ServerProcessor.h index d9d8b70..04fca13 100644 --- a/build/unswsc/ServerProcessor.h +++ b/build/unswsc/ServerProcessor.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "Global.h" #include "Export.h" #include "IPTable.h" @@ -23,9 +23,14 @@ public: void AddStreamSettings(std::string method, bool stream); public: + // 主接口,重载以实现对请求的处理 virtual uns::ResponsePtr Processor(uns::RequestPtr request) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); public: uns::ResponsePtr Handle(uns::RequestPtr request); diff --git a/build/unswsc/SyncFileReceiver.h b/build/unswsc/SyncFileReceiver.h index 7302aab..0b25a40 100644 --- a/build/unswsc/SyncFileReceiver.h +++ b/build/unswsc/SyncFileReceiver.h @@ -1,9 +1,11 @@ -#pragma once +#pragma once #include "Export.h" #include "Global.h" #include "IPTable.h" -#include "WebFileInfo.h" #include "HTTPObjects.h" +#include "TempFileManager.h" + +using SFR_FileMap = std::map; class UNSWSC_DLL_EXPORT SyncFileReceiver { @@ -25,16 +27,22 @@ public: uns::HTTPMethod GetMethod(uns::RequestPtr request); void AppenedBlockedIP(DateTime::Span block_time, std::string ip); bool WriteFile(const std::string& path, const std::string& bytes); + void SetFileTimeout(std::chrono::seconds timeout = 0s, std::chrono::seconds max_proc_timeout = 0s) noexcept; public: + // 请求信息预检,重载以在保存文件之前检查请求体 virtual uns::Status PreCheckRequest(uns::RequestPtr request) = 0; + // 表单预检,重载以在处理表单前检查表单 virtual bool PreCheckForm(uns::FormPartPtr form) = 0; + // 路径穿越配置,重载以配置允许的路径穿越类型 virtual uns::PathTraversalDefenceLevel PTDefence(); + // 路径穿越防护,重载以实现路径穿越检查,配置为AutoNormalize或AllowNormal时必须,否则自动退化为DenyAll virtual bool IsPathSafe(const std::string& raw_path); + // 请求头预检,重载以实现在接收请求体之前检查请求头,返回false则服务器将强制关闭连接 + virtual bool IsHeaderValid(uns::RequestPtr request); - // 【修改】由原先的 Callback 改为可供子类重写的虚函数 - // 返回值改为 webcc::ResponsePtr,并且引入 request 参数以便子类调用 AutoCORS 或解析请求头 - virtual uns::ResponsePtr ProcessFiles(const WebFileInfoVec& file_info, const std::string& tmp_root, uns::RequestPtr request); + // 主接口,重载以接收并处理文件 + virtual uns::ResponsePtr ProcessFiles(TempFileManager& file_info, SFR_FileMap file_map, const std::string& tmp_root, uns::RequestPtr request); public: uns::ResponsePtr Execute(uns::RequestPtr request); diff --git a/build/unswsc/TempFileManager.h b/build/unswsc/TempFileManager.h new file mode 100644 index 0000000..9597451 --- /dev/null +++ b/build/unswsc/TempFileManager.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include +#include +#include "Export.h" +#include "WebFileInfo.h" + +using std::chrono::operator""s; +using std::chrono::operator""min; + +class UNSWSC_DLL_EXPORT TempFileManager +{ +private: + class Impl; + + std::unique_ptr pimpl; + +public: + TempFileManager() noexcept; + ~TempFileManager() noexcept; + + // 禁止拷贝与移动 + TempFileManager(const TempFileManager&) = delete; + TempFileManager& operator=(const TempFileManager&) = delete; + TempFileManager(TempFileManager&&) = delete; + TempFileManager& operator=(TempFileManager&&) = delete; + + // 基础业务接口(保持不变) + bool SetBaseDirectory(std::string dir) noexcept; + bool RegisterFile(const WebFileInfo& info, std::chrono::seconds timeout, std::chrono::seconds max_proc_timeout = std::chrono::seconds(0)) noexcept; + bool InvalidateFile(const WebFileInfo& info); + //For SFR_FileMap + bool InvalidateFile(const std::map& info); + bool CopyFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept; + bool CutFileTo(const std::string& storage_name, const std::string& dest_absolute_path) noexcept; + bool RenameFile(const std::string& old_storage_name, const std::string& new_storage_name) noexcept; + bool DeleteFile(const std::string& storage_name) noexcept; + bool ActiveFile(const std::string& storage_name) noexcept; + bool DeactiveFile(const std::string& storage_name) noexcept; + bool SetPermanent(const std::string& storage_name, bool permanent) noexcept; + bool FileExists(const std::string& storage_name) const noexcept; + bool GetFileInfo(const std::string& storage_name, WebFileInfo& out_info) const noexcept; + size_t GetFileCount() const noexcept; + // 获取当前所有管理中的文件信息快照(线程安全,绝不抛出异常) + std::vector GetAllFileInfos() const noexcept; +}; \ No newline at end of file diff --git a/build/unswsc/WebFileInfo.h b/build/unswsc/WebFileInfo.h index 7ad0af5..fe849fc 100644 --- a/build/unswsc/WebFileInfo.h +++ b/build/unswsc/WebFileInfo.h @@ -31,6 +31,10 @@ public: std::string GetExtensionName() const; DateTime GetUploadTime() const; size_t GetFileSize() const; + +public: + void SetStorageFileName(const std::string& sfn); + void SetOriginalFileName(const std::string& ofn); }; using WebFileInfoVec = std::vector; \ No newline at end of file diff --git a/lib/libwebcc.a b/lib/libwebcc.a index af3f1a7..1b2999a 100644 Binary files a/lib/libwebcc.a and b/lib/libwebcc.a differ diff --git a/webcc/webcc/common.h b/webcc/webcc/common.h index 40d6fe5..e835f4d 100644 --- a/webcc/webcc/common.h +++ b/webcc/webcc/common.h @@ -9,241 +9,277 @@ #include "webcc/fs.h" #include "webcc/globals.h" -namespace webcc { +namespace webcc +{ // ----------------------------------------------------------------------------- -using Header = std::pair; + using Header = std::pair; -class Headers { -public: - std::size_t size() const { - return headers_.size(); - } + class Headers + { +//fix core dumped + public: + Headers() : headers_() + { - bool empty() const { - return headers_.empty(); - } + } + public: + std::size_t size() const + { + return headers_.size(); + } - const std::vector
& data() const { - return headers_; - } + bool empty() const + { + return headers_.empty(); + } - bool Set(string_view key, string_view value); + const std::vector
& data() const + { + return headers_; + } - bool Has(string_view key) const; + bool Set(string_view key, string_view value); - // Get header by index. - const Header& Get(std::size_t index) const { - assert(index < size()); - return headers_[index]; - } + bool Has(string_view key) const; - // Get header value by key. - // If there's no such header with the given key, besides return empty, the - // optional |existed| parameter will be set to false. - const std::string& Get(string_view key, bool* existed = nullptr) const; + // Get header by index. + const Header& Get(std::size_t index) const + { + assert(index < size()); + return headers_[index]; + } - void Clear() { - headers_.clear(); - } + // Get header value by key. + // If there's no such header with the given key, besides return empty, the + // optional |existed| parameter will be set to false. + const std::string& Get(string_view key, bool* existed = nullptr) const; -private: - std::vector
::iterator Find(string_view key); + void Clear() + { + headers_.clear(); + } - std::vector
headers_; -}; + private: + std::vector
::iterator Find(string_view key); -// ----------------------------------------------------------------------------- + std::vector
headers_; + }; -// Content-Type header. -// Syntax: -// Content-Type: text/html; charset=utf-8 -// Content-Type: multipart/form-data; boundary=something -class ContentType { -public: - explicit ContentType(string_view str = ""); + // ----------------------------------------------------------------------------- - void Parse(string_view str); + // Content-Type header. + // Syntax: + // Content-Type: text/html; charset=utf-8 + // Content-Type: multipart/form-data; boundary=something + class ContentType + { + public: + explicit ContentType(string_view str = ""); - void Reset(); + void Parse(string_view str); - bool Valid() const; + void Reset(); - bool multipart() const { - return multipart_; - } + bool Valid() const; - const std::string& media_type() const { - return media_type_; - } + bool multipart() const + { + return multipart_; + } - const std::string& charset() const { - assert(!multipart_); - return additional_; - } + const std::string& media_type() const + { + return media_type_; + } - const std::string& boundary() const { - assert(multipart_); - return additional_; - } + const std::string& charset() const + { + assert(!multipart_); + return additional_; + } -private: - void Init(string_view str); + const std::string& boundary() const + { + assert(multipart_); + return additional_; + } -private: - std::string media_type_; - std::string additional_; - bool multipart_ = false; -}; + private: + void Init(string_view str); -// ----------------------------------------------------------------------------- + private: + std::string media_type_; + std::string additional_; + bool multipart_ = false; + }; -// Content-Disposition header. -// Syntax: -// Content-Disposition: form-data -// Content-Disposition: form-data; name="fieldName" -// Content-Disposition: form-data; name="fieldName"; filename="filename.jpg" -// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition -class ContentDisposition { -public: - explicit ContentDisposition(string_view str) { - valid_ = Init(str); - } + // ----------------------------------------------------------------------------- - bool valid() const { - return valid_; - } + // Content-Disposition header. + // Syntax: + // Content-Disposition: form-data + // Content-Disposition: form-data; name="fieldName" + // Content-Disposition: form-data; name="fieldName"; filename="filename.jpg" + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + class ContentDisposition + { + public: + explicit ContentDisposition(string_view str) + { + valid_ = Init(str); + } - const std::string& name() const { - return name_; - } + bool valid() const + { + return valid_; + } - const std::string& file_name() const { - return file_name_; - } + const std::string& name() const + { + return name_; + } -private: - bool Init(string_view str); + const std::string& file_name() const + { + return file_name_; + } -private: - std::string name_; - std::string file_name_; - bool valid_ = false; -}; + private: + bool Init(string_view str); -// ----------------------------------------------------------------------------- + private: + std::string name_; + std::string file_name_; + bool valid_ = false; + }; -class FormPart; -using FormPartPtr = std::shared_ptr; + // ----------------------------------------------------------------------------- -// A part of the multipart form data. -class FormPart { -public: - FormPart() = default; + class FormPart; + using FormPartPtr = std::shared_ptr; - FormPart(const FormPart&) = delete; - FormPart& operator=(const FormPart&) = delete; + // A part of the multipart form data. + class FormPart + { + public: + FormPart() = default; - // Construct a non-file part. - // The data will be moved, no file name is needed. - // The media type is optional. If the data is a JSON string, you can specify - // media type as "application/json". - static FormPartPtr New(string_view name, std::string&& data, - string_view media_type = ""); + FormPart(const FormPart&) = delete; + FormPart& operator=(const FormPart&) = delete; - // Construct a file part. - // The file name will be extracted from path. - // The media type, if not provided, will be inferred from file extension. - static FormPartPtr NewFile(string_view name, const fs::path& path, - string_view media_type = ""); + // Construct a non-file part. + // The data will be moved, no file name is needed. + // The media type is optional. If the data is a JSON string, you can specify + // media type as "application/json". + static FormPartPtr New(string_view name, std::string&& data, + string_view media_type = ""); - // API: SERVER - const std::string& name() const { - return name_; - } + // Construct a file part. + // The file name will be extracted from path. + // The media type, if not provided, will be inferred from file extension. + static FormPartPtr NewFile(string_view name, const fs::path& path, + string_view media_type = ""); - // API: SERVER/PARSER - void set_name(const std::string& name) { - name_ = name; - } + void ReserveData(std::size_t capacity); - // API: SERVER - const std::string& file_name() const { - return file_name_; - } + // API: SERVER + const std::string& name() const + { + return name_; + } - // API: SERVER/PARSER - void set_file_name(const std::string& file_name) { - file_name_ = file_name; - } + // API: SERVER/PARSER + void set_name(const std::string& name) + { + name_ = name; + } - // API: SERVER - const std::string& media_type() const { - return media_type_; - } + // API: SERVER + const std::string& file_name() const + { + return file_name_; + } - // API: SERVER - const std::string& data() const { - return data_; - } + // API: SERVER/PARSER + void set_file_name(const std::string& file_name) + { + file_name_ = file_name; + } - // API: SERVER/PARSER - void AppendData(const std::string& data) { - data_.append(data); - } + // API: SERVER + const std::string& media_type() const + { + return media_type_; + } - // API: SERVER/PARSER - void AppendData(const char* data, std::size_t count) { - data_.append(data, count); - } + // API: SERVER + const std::string& data() const + { + return data_; + } - // API: CLIENT - void Prepare(Payload* payload); + // API: SERVER/PARSER + void AppendData(const std::string& data) + { + data_.append(data); + } - // Free the memory of the data. - void Free(); + // API: SERVER/PARSER + void AppendData(const char* data, std::size_t count) + { + data_.append(data, count); + } - // Get the size of the whole payload. - // Used by the request to calculate content length. - std::size_t GetSize(); + // API: CLIENT + void Prepare(Payload* payload); - // Get the size of the data. - std::size_t GetDataSize(); + // Free the memory of the data. + void Free(); - // Dump to output stream for logging purpose. - void Dump(std::ostream& os, string_view prefix) const; + // Get the size of the whole payload. + // Used by the request to calculate content length. + std::size_t GetSize(); -private: - // Generate headers from properties. - void SetHeaders(); + // Get the size of the data. + std::size_t GetDataSize(); -private: - // The name within the original HTML form. - // E.g., given HTML form: - // - // the name will be "file1". - std::string name_; + // Dump to output stream for logging purpose. + void Dump(std::ostream& os, string_view prefix) const; - // The path of the file to post. - fs::path path_; + private: + // Generate headers from properties. + void SetHeaders(); - // The original local file name. - // E.g., "baby.jpg". - std::string file_name_; + private: + // The name within the original HTML form. + // E.g., given HTML form: + // + // the name will be "file1". + std::string name_; - // The content-type if the media type is known (e.g., inferred from the file - // extension or operating system typing information) or as - // application/octet-stream. - // E.g., "image/jpeg". - std::string media_type_; + // The path of the file to post. + fs::path path_; - // Headers generated from the above properties. - // Only Used to prepare payload. - Headers headers_; + // The original local file name. + // E.g., "baby.jpg". + std::string file_name_; - std::string data_; -}; + // The content-type if the media type is known (e.g., inferred from the file + // extension or operating system typing information) or as + // application/octet-stream. + // E.g., "image/jpeg". + std::string media_type_; + + // Headers generated from the above properties. + // Only Used to prepare payload. + Headers headers_; + + std::string data_; + }; + + inline std::size_t g_max_multipart_size = 1024 * 1024 * 1024; } // namespace webcc diff --git a/webcc/webcc/connection.h b/webcc/webcc/connection.h index 9ff52fb..e5a9339 100644 --- a/webcc/webcc/connection.h +++ b/webcc/webcc/connection.h @@ -1,4 +1,4 @@ -#ifndef WEBCC_CONNECTION_H_ +#ifndef WEBCC_CONNECTION_H_ #define WEBCC_CONNECTION_H_ #include @@ -101,6 +101,9 @@ private: // The response to be sent back to the client. ResponsePtr response_; + + // 标识是否检查过请求头 + bool header_validated_ = false; }; } // namespace webcc diff --git a/webcc/webcc/globals.h b/webcc/webcc/globals.h index b38666b..fe38d0c 100644 --- a/webcc/webcc/globals.h +++ b/webcc/webcc/globals.h @@ -1,4 +1,4 @@ -#ifndef WEBCC_GLOBALS_H_ +#ifndef WEBCC_GLOBALS_H_ #define WEBCC_GLOBALS_H_ #include @@ -175,7 +175,7 @@ enum Status { kProxyAuthenticationRequired = 407, // 某些服务器会在空闲连接上发送此响应,即使客户端之前没有任何请求。这意味着服务器希望关闭此未使用的连接。 kRequestTimeout = 408, - // 当请求与服务器的当前状态冲突时,发送此响应。 + // 当请求与服务器的当前状态冲突时,发送此响应。在 kConflict = 409, // 当请求的内容已从服务器永久删除,且没有转发地址时,发送此响应。 kGone = 410, diff --git a/webcc/webcc/request_parser.h b/webcc/webcc/request_parser.h index 98c0389..504d201 100644 --- a/webcc/webcc/request_parser.h +++ b/webcc/webcc/request_parser.h @@ -1,70 +1,91 @@ -#ifndef WEBCC_REQUEST_PARSER_H_ +#ifndef WEBCC_REQUEST_PARSER_H_ #define WEBCC_REQUEST_PARSER_H_ #include #include #include "webcc/parser.h" +#include "webcc/view.h" -namespace webcc { +namespace webcc +{ -using ViewMatcher = - std::function; + using ViewMatcher = + std::function; -class Request; + class Request; -class RequestParser : public Parser { -public: - RequestParser(); + class RequestParser : public Parser + { + public: + RequestParser(); - ~RequestParser() override = default; + ~RequestParser() override = default; - void Init(Request* request, ViewMatcher view_matcher); + void Init(Request* request, ViewMatcher view_matcher); -private: - // Override to match the URL against views and check if the matched view - // asks for data streaming. - bool OnHeadersEnd() override; + // 【新增】:检查 Header 是否已解析完毕 + bool IsHeaderParsed() const + { + return header_parsed_; + } - bool ParseStartLine(const std::string& line) override; + ViewPtr MatchedView() const + { + return matched_view_; + } - // Override to handle multipart form data which is request only. - bool ParseContent(const char* data, std::size_t length) override; + private: + // Override to match the URL against views and check if the matched view + // asks for data streaming. + bool OnHeadersEnd() override; - // Multipart specific parsing helpers. + bool ParseStartLine(const std::string& line) override; - bool ParseMultipartContent(const char* data, std::size_t length); - bool ParsePartHeaders(bool* need_more_data); - bool GetNextBoundaryLine(std::size_t* b_off, std::size_t* b_len, bool* ended); + // Override to handle multipart form data which is request only. + bool ParseContent(const char* data, std::size_t length) override; - // Check if the str.substr(off, count) is a boundary. - bool IsBoundary(const std::string& str, std::size_t off, - std::size_t count, bool* end = nullptr) const; + // Multipart specific parsing helpers. -private: - // The result request message. - Request* request_ = nullptr; + bool ParseMultipartContent(const char* data, std::size_t length); + bool ParsePartHeaders(bool* need_more_data); + bool GetNextBoundaryLine(std::size_t* b_off, std::size_t* b_len, bool* ended); - // A function for matching view once the headers of a request has been - // received. The parsing will stop and fail if no view can be matched. - ViewMatcher view_matcher_; + // Check if the str.substr(off, count) is a boundary. + bool IsBoundary(const std::string& str, std::size_t off, + std::size_t count, bool* end = nullptr) const; - // Form data parsing steps. - enum class Step { - kStart, - kBoundaryParsed, - kHeadersParsed, - kEnded, - }; + private: + // The result request message. + Request* request_ = nullptr; - Step step_ = Step::kStart; + // A function for matching view once the headers of a request has been + // received. The parsing will stop and fail if no view can be matched. + ViewMatcher view_matcher_; - // The current form part being parsed. - FormPartPtr part_; + // Form data parsing steps. + enum class Step + { + kStart, + kBoundaryParsed, + kHeadersParsed, + kEnded, + }; - // All form parts parsed. - std::vector form_parts_; -}; + Step step_ = Step::kStart; + + // The current form part being parsed. + FormPartPtr part_; + + // All form parts parsed. + std::vector form_parts_; + + // 【新增】:Header 解析完成标志 + bool header_parsed_ = false; + + // View映射(用于请求头检查) + ViewPtr matched_view_ = nullptr; + }; } // namespace webcc diff --git a/webcc/webcc/router.h b/webcc/webcc/router.h index 47f0844..b1153d8 100644 --- a/webcc/webcc/router.h +++ b/webcc/webcc/router.h @@ -32,7 +32,7 @@ public: // Return if a view is matched or not. // If the view asks for data streaming, |stream| will be set to true. bool MatchView(const std::string& method, const std::string& url, - bool* stream); + bool* stream, ViewPtr* out_view = nullptr); // Direct access for ViewPtr pointers. // This can be used as server-based ip block/condiction checks diff --git a/webcc/webcc/server.h b/webcc/webcc/server.h index 5ff9873..de151cc 100644 --- a/webcc/webcc/server.h +++ b/webcc/webcc/server.h @@ -16,138 +16,145 @@ #include "webcc/router.h" #include "webcc/url.h" -namespace webcc { +namespace webcc +{ -class Server : public Router { -public: - Server(boost::asio::ip::tcp protocol, std::uint16_t port, - const fs::path& doc_root = {}); + using HeaderValidator = std::function; - Server(const Server&) = delete; - Server& operator=(const Server&) = delete; + class Server : public Router + { + public: + Server(boost::asio::ip::tcp protocol, std::uint16_t port, + const fs::path& doc_root = {}); - ~Server() = default; + Server(const Server&) = delete; + Server& operator=(const Server&) = delete; - void set_buffer_size(std::size_t buffer_size) { - if (buffer_size > 0) { - buffer_size_ = buffer_size; - } - } + ~Server() = default; - void set_file_chunk_size(std::size_t file_chunk_size) { - assert(file_chunk_size > 0); - file_chunk_size_ = file_chunk_size; - } + void set_buffer_size(std::size_t buffer_size) + { + if (buffer_size > 0) + { + buffer_size_ = buffer_size; + } + } - // Start and run the server. - // This method is blocking so will not return until Stop() is called (from - // another thread) or a signal like SIGINT is caught. - // When the request of a connection has been read, the connection is put into - // a queue waiting for some worker thread to process. Normally, the more - // |workers| you have, the more concurrency you gain (the concurrency also - // depends on the number of CPU cores). The worker thread pops connections - // from the queue one by one, prepares the response by the user provided View, - // then sends it back to the client. - // Meanwhile, the (event) loop, i.e., io_context, is also running in a number - // (|loops|) of threads. Normally, one thread for the loop is good enough, but - // it could be more than that. - void Run(std::size_t workers = 1, std::size_t loops = 1); + void set_file_chunk_size(std::size_t file_chunk_size) + { + assert(file_chunk_size > 0); + file_chunk_size_ = file_chunk_size; + } - // Stop the server. - // This should be called from another thread since the Run() is blocking. - void Stop(); + // Start and run the server. + // This method is blocking so will not return until Stop() is called (from + // another thread) or a signal like SIGINT is caught. + // When the request of a connection has been read, the connection is put into + // a queue waiting for some worker thread to process. Normally, the more + // |workers| you have, the more concurrency you gain (the concurrency also + // depends on the number of CPU cores). The worker thread pops connections + // from the queue one by one, prepares the response by the user provided View, + // then sends it back to the client. + // Meanwhile, the (event) loop, i.e., io_context, is also running in a number + // (|loops|) of threads. Normally, one thread for the loop is good enough, but + // it could be more than that. + void Run(std::size_t workers = 1, std::size_t loops = 1); - // Is the server running? - bool IsRunning() const; + // Stop the server. + // This should be called from another thread since the Run() is blocking. + void Stop(); - // For High-Level api deleloper: to set the default server name insteaed of - // webcc Added by UnknownObject at 2022-09-04 - void SetDefaultServerName(std::string server_name); + // Is the server running? + bool IsRunning() const; -private: - // Register signals which indicate when the server should exit. - void AddSignals(); + // For High-Level api deleloper: to set the default server name insteaed of + // webcc Added by UnknownObject at 2022-09-04 + void SetDefaultServerName(std::string server_name); - // Wait for a signal to stop the server. - void AsyncWaitSignals(); + private: + // Register signals which indicate when the server should exit. + void AddSignals(); - // Listen on the given port. - bool Listen(std::uint16_t port); + // Wait for a signal to stop the server. + void AsyncWaitSignals(); - // Accept connections asynchronously. - void AsyncAccept(); + // Listen on the given port. + bool Listen(std::uint16_t port); - // Stop acceptor and worker threads, close all pending connections, and - // finally stop the event loop. - void DoStop(); + // Accept connections asynchronously. + void AsyncAccept(); - // Worker thread routine. - void WorkerRoutine(); + // Stop acceptor and worker threads, close all pending connections, and + // finally stop the event loop. + void DoStop(); - // Clear pending connections from the queue and stop worker threads. - void StopWorkers(); + // Worker thread routine. + void WorkerRoutine(); - // Handle a connection (or more precisely, the request inside it). - // Get the request from the connection, process it, prepare the response, - // then send the response back to the client. - // The connection will keep alive if it's a persistent connection. When next - // request comes, this connection will be put back to the queue again. - virtual void Handle(ConnectionPtr connection); + // Clear pending connections from the queue and stop worker threads. + void StopWorkers(); - // Match the view by HTTP method and URL (path). - // Return if a view or static file is matched or not. - // If the view asks for data streaming, |stream| will be set to true. - bool MatchViewOrStatic(const std::string& method, const std::string& url, - bool* stream); + // Handle a connection (or more precisely, the request inside it). + // Get the request from the connection, process it, prepare the response, + // then send the response back to the client. + // The connection will keep alive if it's a persistent connection. When next + // request comes, this connection will be put back to the queue again. + virtual void Handle(ConnectionPtr connection); - // Serve static files from the doc root. - ResponsePtr ServeStatic(RequestPtr request); + // Match the view by HTTP method and URL (path). + // Return if a view or static file is matched or not. + // If the view asks for data streaming, |stream| will be set to true. + bool MatchViewOrStatic(const std::string& method, const std::string& url, + bool* stream, ViewPtr* out_view = nullptr); -private: - // tcp::v4() or tcp::v6() - boost::asio::ip::tcp protocol_; + // Serve static files from the doc root. + ResponsePtr ServeStatic(RequestPtr request); - // Port number. - std::uint16_t port_ = 0; + private: + // tcp::v4() or tcp::v6() + boost::asio::ip::tcp protocol_; - // The directory with the static files to be served. - fs::path doc_root_; + // Port number. + std::uint16_t port_ = 0; - // The size of the buffer for reading request. - std::size_t buffer_size_ = kBufferSize; + // The directory with the static files to be served. + fs::path doc_root_; - // The size of the chunk loaded into memory each time when serving a - // static file. - std::size_t file_chunk_size_ = 1024; + // The size of the buffer for reading request. + std::size_t buffer_size_ = kBufferSize; - // Is the server running? - bool running_ = false; + // The size of the chunk loaded into memory each time when serving a + // static file. + std::size_t file_chunk_size_ = 1024; - // The mutex for guarding the state of the server. - std::mutex state_mutex_; + // Is the server running? + bool running_ = false; - // The io_context used to perform asynchronous operations. - boost::asio::io_context io_context_; + // The mutex for guarding the state of the server. + std::mutex state_mutex_; - // Acceptor used to listen for incoming connections. - boost::asio::ip::tcp::acceptor acceptor_; + // The io_context used to perform asynchronous operations. + boost::asio::io_context io_context_; - // The connection pool which owns all live connections. - ConnectionPool pool_; + // Acceptor used to listen for incoming connections. + boost::asio::ip::tcp::acceptor acceptor_; - // The signals for processing termination notifications. - boost::asio::signal_set signals_; + // The connection pool which owns all live connections. + ConnectionPool pool_; - // Worker threads. - std::vector worker_threads_; + // The signals for processing termination notifications. + boost::asio::signal_set signals_; - // The queue with connection waiting for the workers to process. - Queue queue_; + // Worker threads. + std::vector worker_threads_; - // For High-Level api deleloper: to set the default server name insteaed of webcc - // Added by UnknownObject at 2022-09-04 - std::string server_name__; -}; + // The queue with connection waiting for the workers to process. + Queue queue_; + + // For High-Level api deleloper: to set the default server name insteaed of webcc + // Added by UnknownObject at 2022-09-04 + std::string server_name__; + }; } // namespace webcc diff --git a/webcc/webcc/view.h b/webcc/webcc/view.h index 24e9dd4..842e9ff 100644 --- a/webcc/webcc/view.h +++ b/webcc/webcc/view.h @@ -1,4 +1,4 @@ -#ifndef WEBCC_VIEW_H_ +#ifndef WEBCC_VIEW_H_ #define WEBCC_VIEW_H_ #include @@ -25,6 +25,14 @@ public: virtual bool Stream(const std::string& /*method*/) { return false; // No streaming by default } + + // 【核心新增】:请求头预校验虚函数 + // 当 Header 刚解析完毕、尚未接收 Body 时触发。 + // 返回 true 继续接收数据;返回 false 强行 RST 切断连接。 + virtual bool ValidateHeader(RequestPtr /*request*/) + { + return true; // 默认不校验,全放行 + } }; using ViewPtr = std::shared_ptr;