一、项目设计思路
用于之后协议使用的工具类
二、静态成员函数
1、分割函数 static size_t Split(const string &src, const string &sep, vector<string> *array)
string.find(const string &str, size_t pos = 0)
string.substr(size_t pos = 0, size_t len = npos)
(1)循环分割,offset 作为起始点不能越界,所以小于 src.size()
(2)find 如果没有找到结果表示已经到了最后一个子串,如果此时返回的 pos == src.size() 就说明最后一个子串是空串,跳过,如果不是空串就放入数组并返回
(3)find 如果找到了结果,先判断返回位置是否是 offset,是就表示这个子串是空串,跳过,如果不是就放入数组,移动偏移量 offset
2、读取文件内容 static bool ReadFile(const string &filename, string *buf)
(1)创建 ifstream,二进制打开文件
(2)获取文件大小:移动读写位置到文件末尾:ifs.seekg(0, end),获取读写位置到文件头部的偏移量:size = ifs.tellg(),最后恢复读写位置到文件头:ifs.seekg(0, beg)
(3)buf 扩容(resize)并且读取文件数据到缓冲区 buf:ifs.read(&((*buf)[0]), size)
(4)若上一步操作有问题:ifs.good() == false 就关闭 ifs, 最后也要关闭 ifs
3、写入文件数据 static bool Write(const string &filename, string &buf)
(1)创建 otstream,二进制并截断打开文件(binary | trunc)
(2)ofs.write(buf.c_str(), buf.size()) 将缓冲区里面的数据写入文件
(3)若上一步操作有问题:ofs.good() == false 就关闭 ofs, 最后也要关闭 ofs
4、URL编码 static string UrlEncode(const string &url, bool convert_space_to_plus)
URL编码规则:
将特殊字符的ascii转化成两个16进制字符,前缀%
绝对不编码字符:. - _ ~ 和数字字母
RFC3986文档规定,编码格式 %HH
W3C标准中规定,查询字符串中的空格,需要编码为+, 解码则是+转空格
特殊字符转化格式:"%%%02X"
5、URL解码 static string UrlDecode(const string &url, bool convert_plus_to_space)
遇到%,先判断后面是否有两位字符,有就进行特殊字符解码:第一个数 << 4 + 第二个数,解码完后一定要向后移动两位!!!
6、获取应答状态码描述 static string StatusDesc(const int status)
哈希表查找返回
7、获取文件后缀转文件扩展名 static string ExtMime(const string &filename)
string.find_last_of(char c, size_t pos)
先获取文件后缀,没找到返回二进制文件,找到提取后哈斯表查找返回
8、判断文件是否是目录 / 普通文件
(1)先定义 struct stat st;
(2)函数 stat 获取文件名的各种属性
(3)最后宏判断
目录:S_ISDIR(st.st_mod)
普通文件:S_ISREG(st.st_mod)
9、判断HTTP资源请求路径是否合法 static bool ValidPath(const string &path)
目的:不能让用户请求相对根目录以外的资源
思路:分割资源请求路径,在分析过程中若遇到 .. 就返回到上一层,如果超过了相对根目录就直接返回 false