电商网官方网站,黄山旅游攻略自助游,农业科技公司网站建设,天津建设工程投标信息一、Util模块 二、实现思想
#xff08;一#xff09;管理
实现一些工具接口读取文件内容向文件写入内容URL编码URL解码通过HTTP状态码获取描述信息通过文件后缀名获取mime判断一个文件是不是目录判断一个文件是否是一个普通文件HTTP资源路径有效性判断
#xff08;二一管理
实现一些工具接口读取文件内容向文件写入内容URL编码URL解码通过HTTP状态码获取描述信息通过文件后缀名获取mime判断一个文件是不是目录判断一个文件是否是一个普通文件HTTP资源路径有效性判断
二意义
在协议支持模块中当需要某些零碎功能的时候便于使用
三功能设计
class Util {public:// 字符串分割函数size_t Spilt();// 读取文件内容static bool ReadFile() {}// 向文件写入内容static bool WriteFile();// URL编码static bool UrlEncode();// URL解码static bool UrlDecode();// 通过HTTP状态码获取描述信息static std::string StatusDesc();// 根据文件后缀名获取文件MINEstatic std::string ExtMine();// 判断一个文件是不是目录static bool IsDirectory();//判断一个文件是否是一个普通文件static bool IsRegular();//HTTP资源路径有效性判断static bool VaildPath();
};三、代码
class Util {public://字符串分割函数,将src字符串按照sep字符进行分割得到的各个字串放到arry中最终返回字串的数量static size_t Split(const std::string src, const std::string sep, std::vectorstd::string *arry) {size_t offset 0;// 有10个字符offset是查找的起始位置范围应该是0~9offset10就代表已经越界了while(offset src.size()) {size_t pos src.find(sep, offset);//在src字符串偏移量offset处开始向后查找sep字符/字串返回查找到的位置if (pos std::string::npos) {//没有找到特定的字符//将剩余的部分当作一个字串放入arry中if(pos src.size()) break;arry-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();}//读取文件的所有内容将读取的内容放到一个Buffer中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);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 9) {return c - 0;}else if (c a c z) {return c - a 10;}else if (c A c Z) {return c - A 10;}return -1; }static std::string UrlDecode(const std::string url, bool convert_plus_to_space) {//遇到了%则将紧随其后的2个字符转换为数字第一个数字左移4位然后加上第二个数字 - 2b %2b-2 4 11std::string res;for (int i 0; i url.size(); i) {if (url[i] convert_plus_to_space true) {res ;continue;}if (url[i] % (i 2) url.size()) {char v1 HEXTOI(url[i 1]);char v2 HEXTOI(url[i 2]);char v v1 * 16 v2;res v;i 2;continue;}res url[i];}return res;}//响应状态码的描述信息获取static std::string StatuDesc(int statu) {auto it _statu_msg.find(statu);if (it ! _statu_msg.end()) {return it-second;}return Unknow;}//根据文件后缀名获取文件mimestatic std::string ExtMime(const std::string filename) {// a.b.txt 先获取文件扩展名size_t pos filename.find_last_of(.);if (pos std::string::npos) {return application/octet-stream;}//根据扩展名获取mimestd::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 0) {return false;}return S_ISDIR(st.st_mode);}//判断一个文件是否是一个普通文件static bool IsRegular(const std::string filename) {struct stat st;int ret stat(filename.c_str(), st);if (ret 0) {return false;}return S_ISREG(st.st_mode);}//http请求的资源路径有效性判断// /index.html --- 前边的/叫做相对根目录 映射的是某个服务器上的子目录// 想表达的意思就是客户端只能请求相对根目录中的资源其他地方的资源都不予理会// /../login, 这个路径中的..会让路径的查找跑到相对根目录之外这是不合理的不安全的static bool ValidPath(const std::string path) {//思想按照/进行路径分割根据有多少子目录计算目录深度有多少层深度不能小于0std::vectorstd::string subdir;Split(path, /, subdir);int level 0;for (auto dir : subdir) {if (dir ..) {level--; //任意一层走出相对根目录就认为有问题if (level 0) return false;continue;}level;}return true;}
};状态码
std::unordered_mapint, std::string _statu_msg {{100, Continue},{101, Switching Protocol},{102, Processing},{103, Early Hints},{200, OK},{201, Created},{202, Accepted},{203, Non-Authoritative Information},{204, No Content},{205, Reset Content},{206, Partial Content},{207, Multi-Status},{208, Already Reported},{226, IM Used},{300, Multiple Choice},{301, Moved Permanently},{302, Found},{303, See Other},{304, Not Modified},{305, Use Proxy},{306, unused},{307, Temporary Redirect},{308, Permanent Redirect},{400, Bad Request},{401, Unauthorized},{402, Payment Required},{403, Forbidden},{404, Not Found},{405, Method Not Allowed},{406, Not Acceptable},{407, Proxy Authentication Required},{408, Request Timeout},{409, Conflict},{410, Gone},{411, Length Required},{412, Precondition Failed},{413, Payload Too Large},{414, URI Too Long},{415, Unsupported Media Type},{416, Range Not Satisfiable},{417, Expectation Failed},{418, Im a teapot},{421, Misdirected Request},{422, Unprocessable Entity},{423, Locked},{424, Failed Dependency},{425, Too Early},{426, Upgrade Required},{428, Precondition Required},{429, Too Many Requests},{431, Request Header Fields Too Large},{451, Unavailable For Legal Reasons},{501, Not Implemented},{502, Bad Gateway},{503, Service Unavailable},{504, Gateway Timeout},{505, HTTP Version Not Supported},{506, Variant Also Negotiates},{507, Insufficient Storage},{508, Loop Detected},{510, Not Extended},{511, Network Authentication Required}
};std::unordered_mapstd::string, std::string _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/epubzip},{.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/ldjson},{.mid, audio/midi},{.midi, audio/x-midi},{.mjs, text/javascript},{.mp3, audio/mpeg},{.mpeg, video/mpeg},{.mpkg, application/vnd.apple.installerxml},{.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/svgxml},{.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/xhtmlxml},{.xls, application/vnd.ms-excel},{.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet},{.xml, application/xml},{.xul, application/vnd.mozilla.xulxml},{.zip, application/zip},{.3gp, video/3gpp},{.3g2, video/3gpp2},{.7z, application/x-7z-compressed}
};