行业知识
在Linux上实现HTTP服务器,进行前端对后端的文件上传和下载(实现线程池,epoll等)
2026-11-12 01:48:26
来源:互联网转载
一、初步了解和实现。
在五月初的时候接触到了一个编程网站,比较入门级,但是通过每个阶段的小目标设计来实现项目的最终功能,也能了解到一些相关的知识,所以试着做了一下里面HTTP服务器的c++建设,虽然之前也有做,但是其实那个也有点久之前了,这一次想着通过简单复习,顺便把一些和Linux高性能服务器的相关知识也一并用上。
Catalog | CodeCrafters(每个月都有免费的简单项目练手,而且可以简单发布在你的github上)
GitHub - asexe/http-: codecrafters这是这个项目我在github上的实现
#include #include #include #include #include #include #include #include #include #include #include #include #include std::string captureAfterKey(const std::string& input) { std::size_t echoPos = input.find("/echo/"); if (echoPos == std::string::npos) { // 如果没有找到 /echo/,返回空字符串 return ""; } // 从 /echo/ 后面开始查找空格 std::size_t spacePos = input.find(' ', echoPos + 6); // /echo/ 长度为6 if (spacePos == std::string::npos) { // 如果没有找到空格,取从 /echo/ 后面到字符串末尾的部分 return input.substr(echoPos + 6); } else { // 如果找到了空格,取空格前的部分 return input.substr(echoPos + 6, spacePos - echoPos - 6); }}std::string extractUserAgent(const std::string& request) { std::size_t userAgentPos = request.find("User-Agent: "); if (userAgentPos == std::string::npos) { // 如果没有找到 User-Agent 头,返回空字符串 return ""; } // 找到 User-Agent 头,现在找到该行的结束位置 std::size_t endOfLinePos = request.find("\r\n", userAgentPos); if (endOfLinePos == std::string::npos) { // 如果没有找到行结束,返回空字符串 return ""; } // 提取 User-Agent 头的值 return request.substr(userAgentPos + sizeof("User-Agent: ") - 1, endOfLinePos - userAgentPos - sizeof("User-Agent: ") + 1);}// 新增函数,用于读取文件内容并返回std::string readFileContent(const std::string& filePath) { std::ifstream fileStream(filePath, std::ios::binary | std::ios::ate); if (fileStream) { std::streamsize size = fileStream.tellg(); fileStream.seekg(0, std::ios::beg); std::string content; content.resize(size); if (size > 0) { fileStream.read(&content[0], size); } return content; } else { return ""; }}// 新增函数,用于读取文件内容并返回std::string readFileContent(const std::string& directory, const std::string& filename) { std::ifstream fileStream((directory + "/" + filename).c_str(), std::ios::binary | std::ios::ate); if (fileStream) { std::streamsize size = fileStream.tellg(); fileStream.seekg(0, std::ios::beg); std::string content((std::istreambuf_iterator(fileStream)), std::istreambuf_iterator()); return content; } else { return ""; }}std::string handlePostRequest(const std::string& request, const std::string& directory) { std::string response; std::string filename; std::string fileContent; // 查找 POST 请求正文的开始 size_t postHeaderEnd = request.find("\r\n\r\n") + 4; if (postHeaderEnd != std::string::npos) { // 获取 POST 请求正文内容 fileContent = request.substr(postHeaderEnd); // 提取文件名,假设它紧跟在 "POST /files/" 之后 size_t filenameStart = request.find("POST /files/") + 11; size_t filenameEnd = request.find(" ", filenameStart); // 假设文件名之后有一个空格 if (filenameEnd != std::string::npos) { filename = request.substr(filenameStart, filenameEnd - filenameStart); // 构造完整的文件路径 std::string filePath = directory + "/" + filename; // 保存文件 std::ofstream outFile(filePath, std::ios::binary); if (outFile) { outFile