行业知识
Util工具类功能设计与类设计(http模块一)
2026-11-12 07:51:09
来源:互联网转载
���录
类功能
类定义
类实现
编译测试
Split分割字符串测试
ReadFile读取测试
WriteFile写入测试
UrlEncode编码测试
UrlDecode编码测试
StatuDesc状态码信息获取测试
ExtMime后缀名获取文件mime测试
IsDirectory&IsRegular测试
VaildPath请求路径有效性判断测试
总编译
补充
trunc截断
编码格式的规定
md5sum校验和比较两个文件是否一致
新增gdb调试手法
类功能
类定义
#include "../server.hpp"class Util{ public : // 字符串分割函数 size_t Split(); // 读取文件内容 static bool ReadFile(); // 向文件写入数据 static bool WriteFile(); // URL编码 static bool UrlEncode(); // URL解码 static bool UrlDecode(); // 响应状态码的描述信息获取 static std::string StatuDesc(); // 根据文件后缀名获取文件mime static std::string ExtMime(); // 判断一个文件是否是一个目录 static bool IsDirectory(); // 判断一个文件是否是一个普通文件 static bool IsRegular(); // http请求的资源路径有效性判断 static bool VaildPath();}; 类实现
#include "../server.hpp"#include #include class Util{public: // 字符串分割函数 static size_t Split(const std::string &src, const std::string &sep, std::vector *arry) { size_t offset = 0; // 有10个字符,offset是查找的起始位置,范围应该是0~9,offset==10就代表已经越界了,返回查找的位置 while (offset push_back(src.substr(offset)); return arry->size(); } if (pos == offset) { offset = pos + sep.size(); continue; // 当前字符串是一个空串,没有内容 } arry->push_back(src.substr(offset, pos - offset)); offset = pos + sep.size(); } return arry->size(); } // 读取文件的所有内容,将读取到的内容放到一个容器中 static bool ReadFile(const std::string &filename, std::string *buf) { std::ifstream ifs(filename, std::ios::binary); // 以二进制的方式读取 if (ifs.is_open() == false) { printf("OPEN %s FILE FAILED!!", filename.c_str()); return false; } size_t fsize = 0; // 偏移量 ifs.seekg(0, ifs.end); // 跳转读写位置到末尾 fsize = ifs.tellg(); // 获取当前读写位置相对于起始位置的偏移量,从末尾偏移量刚好就是文件大小 ifs.seekg(0, ifs.beg); // 跳转到起始位置 buf->resize(fsize); // 开辟文件大小的空间 ifs.read(&(*buf)[0], fsize); // c_str()返回的是一个const,所以不行 if (ifs.good() == false) { printf("READ %s FILE FAILED!!", filename.c_str()); ifs.close(); return false; } ifs.close(); return true; } // 向文件写入数据 static bool WriteFile(const std::string &filename, const std::string &buf) { std::ofstream ofs(filename, std::ios::binary | std::ios::trunc); if (ofs.is_open() == false) { printf("OPEN %s FILE FAILED!!", filename.c_str()); return false; } ofs.write(buf.c_str(), buf.size()); if (ofs.good() == false) { ERR_LOG("WRITE %s FILE FAILED!", filename.c_str()); ofs.close(); return false; } ofs.close(); return true; } // URL编码,避免URL中资源路径与查询字符串中的特殊字符与HTTP请求中特殊字符产生歧义 // 编码格式:将特殊字符的ascii值,转换为两个16进制字符,前缀% C++ -> C%2B%2B // 不编码的特殊字符: RFC3986文档规定 . - _ ~ 字母,数字属于绝对不编码字符 // RFC3986文档规定,编码格式 %HH // W3C标准中规定,查询字符串中的空格,需要编码为+, 解码则是+转空格 static std::string UrlEncode(const std::string url, bool convert_space_to_plus) { std::string res; for (auto &c : url) { if (c == '.' || c == '-' || c == '_' || c == '~' || isalnum(c)) { res += c; continue; } if (c == ' ' && convert_space_to_plus == true) { res += '+'; continue; } // 剩下的字符都是需要编码成为 %HH 格式 char tmp[4] = {0}; // snprintf 与 printf比较类似,都是格式化字符串,只不过一个是打印,一个是放到一块空间中 snprintf(tmp, 4, "%%%02X", c); res += tmp; } return res; } static char HEXTOI(char c) { if (c >= '0' && c = 'a' && c = 'A' && c 2b %2b->2 second; } return "Unknow"; } // 根据文件后缀名获取文件mime static std::string ExtMime(const std::string &filename) { std::unordered_map _mime_msg = { {".aac", "audio/aac"}, {".abw", "application/x-abiword"}, {".arc", "application/x-freearc"}, {".avi", "video/x-msvideo"}, {".azw", "application/vnd.amazon.ebook"}, {".bin", "application/octet-stream"}, {".bmp", "image/bmp"}, {".bz", "application/x-bzip"}, {".bz2", "application/x-bzip2"}, {".csh", "application/x-csh"}, {".css", "text/css"}, {".csv", "text/csv"}, {".doc", "application/msword"}, {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, {".eot", "application/vnd.ms-fontobject"}, {".epub", "application/epub+zip"}, {".gif", "image/gif"}, {".htm", "text/html"}, {".html", "text/html"}, {".ico", "image/vnd.microsoft.icon"}, {".ics", "text/calendar"}, {".jar", "application/java-archive"}, {".jpeg", "image/jpeg"}, {".jpg", "image/jpeg"}, {".js", "text/javascript"}, {".json", "application/json"}, {".jsonld", "application/ld+json"}, {".mid", "audio/midi"}, {".midi", "audio/x-midi"}, {".mjs", "text/javascript"}, {".mp3", "audio/mpeg"}, {".mpeg", "video/mpeg"}, {".mpkg", "application/vnd.apple.installer+xml"}, {".odp", "application/vnd.oasis.opendocument.presentation"}, {".ods", "application/vnd.oasis.opendocument.spreadsheet"}, {".odt", "application/vnd.oasis.opendocument.text"}, {".oga", "audio/ogg"}, {".ogv", "video/ogg"}, {".ogx", "application/ogg"}, {".otf", "font/otf"}, {".png", "image/png"}, {".pdf", "application/pdf"}, {".ppt", "application/vnd.ms-powerpoint"}, {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, {".rar", "application/x-rar-compressed"}, {".rtf", "application/rtf"}, {".sh", "application/x-sh"}, {".svg", "image/svg+xml"}, {".swf", "application/x-shockwave-flash"}, {".tar", "application/x-tar"}, {".tif", "image/tiff"}, {".tiff", "image/tiff"}, {".ttf", "font/ttf"}, {".txt", "text/plain"}, {".vsd", "application/vnd.visio"}, {".wav", "audio/wav"}, {".weba", "audio/webm"}, {".webm", "video/webm"}, {".webp", "image/webp"}, {".woff", "font/woff"}, {".woff2", "font/woff2"}, {".xhtml", "application/xhtml+xml"}, {".xls", "application/vnd.ms-excel"}, {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, {".xml", "application/xml"}, {".xul", "application/vnd.mozilla.xul+xml"}, {".zip", "application/zip"}, {".3gp", "video/3gpp"}, {".3g2", "video/3gpp2"}, {".7z", "application/x-7z-compressed"}, }; // a.b.txt 获取文件名 size_t pos = filename.find_last_of('.'); if (pos != std::string::npos) return "application/octet-stream"; // 没找着,表示文件是一个二进制文件 // 根据扩展名,获取mime std::string ext = filename.substr(pos); auto it = _mime_msg.find(ext); if (it == _mime_msg.end()) return "application/octet-stream"; return it->second; } // 判断一个文件是否是一个目录 static bool IsDirectory(const std::string &filename) { struct stat st; int ret = stat(filename.c_str(), &st); if (ret 编译测试
各个函数依次测试功能
Split分割字符串测试
ReadFile读取测试
WriteFile写入测试
UrlEncode编码测试
UrlDecode编码测试
StatuDesc状态码信息获取测试
ExtMime后缀名获取文件mime测试
IsDirectory&IsRegular测试
VaildPath请求路径有效性判断测试
总编译
无异常,符合预期
测试案例代码
int main(){ std::cout
上一篇:怎么进电脑进服务器?