WebServer项目——HTTPresponse详解

HTTPresponse简介

这个类和HTTPrequest相反,是给相应的连接生成相应报文的。HTTPrequest是解析请求行,请求头和数据体,那么HTTPresponse就是生成请求行,请求头和数据体。

HTTPresponse的组成

所需变量和自定义的数据结构

首先,我们需要一个变量code_来代表HTTP的状态。

在HTTPrequest中解析到的路径信息是相对路径,我们还需要补全,所以需要一个变量path_代表解析得到的路径,一个变量srcDir_表示根目录,除此之外,我们还需要一个哈希表提供4XX状态码到响应文件路径的映射。

我们在实现所需函数的过程中,需要知道HTTP连接是否处于KeepAlive状态,所以用一个变量isKeepAlive_表示。

由于使用了共享内存,所以也需要变量和数据结构指示相关信息:

1
2
char* mmFile_;
struct stat mmFileStat_;

所以,总结如下:

1
2
3
4
5
6
7
8
9
10
11
12
int code_;
bool isKeepAlive_;

std::string path_;
std::string srcDir_;

char* mmFile_;
struct stat mmFileStat_;

static const std::unordered_map<std::string, std::string> SUFFIX_TYPE;
static const std::unordered_map<int, std::string> CODE_STATUS;
static const std::unordered_map<int, std::string> CODE_PATH;

其中,哈希表SUFFIX_TYPE表示后缀名到文件类型的映射关系,哈希表CODE_STATUS表示状态码到相应状态(字符串类型)的映射。

构造函数和析构函数

这个类中的构造函数和析构函数就是默认的,不需要做什么操作。虽然会有初始化的函数,但是不需要在这里初始化,因为需要初始化srcDir在这里没法获取。

生成响应报文函数

这个类的主要部分就是就是生成相应报文,也就是生成请求行,请求头和数据体,分别对应以下函数:

1
2
3
void addStateLine_(Buffer& buffer);
void addResponseHeader_(Buffer& buffer);
void addResponseContent_(Buffer& buffer);

在设计的时候,对于4XX的状态码是分开考虑的,这部分由函数:

1
void errorHTML_();

实现。

在添加请求头的时候,我们需要得到文件类型信息,这个由函数:

1
std::string getFileType_();

实现。

在添加数据体的函数中,如果所请求的文件打不开,我们需要返回相应的错误信息,这个功能由函数:

1
void errorContent(Buffer& buffer,std::string message);

实现。

最后,生成响应报文的主函数为:

1
void makeResponse(Buffer& buffer);

暴露给外界的接口

返回状态码的函数:

1
int code() const {return code_;}

返回文件信息的函数:

1
2
char* file();
size_t fileLen() const;

其他函数

初始化函数:

1
void init(const std::string& srcDir,std::string& path,bool isKeepAlive=false,int code=-1);

共享内存的扫尾函数:

1
void unmapFile_();

HTTPresponse的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class HTTPresponse
{
public:
HTTPresponse();
~HTTPresponse();

void init(const std::string& srcDir,std::string& path,bool isKeepAlive=false,int code=-1);
void makeResponse(Buffer& buffer);
void unmapFile_();
char* file();
size_t fileLen() const;
void errorContent(Buffer& buffer,std::string message);
int code() const {return code_;}


private:
void addStateLine_(Buffer& buffer);
void addResponseHeader_(Buffer& buffer);
void addResponseContent_(Buffer& buffer);

void errorHTML_();
std::string getFileType_();

int code_;
bool isKeepAlive_;

std::string path_;
std::string srcDir_;

char* mmFile_;
struct stat mmFileStat_;

static const std::unordered_map<std::string, std::string> SUFFIX_TYPE;
static const std::unordered_map<int, std::string> CODE_STATUS;
static const std::unordered_map<int, std::string> CODE_PATH;

};