C++网络编程实战项目--Sinetlib网络库(5)——HTTP服务器设计与实现

Sinetlib内嵌了一个简易的HTTP服务器,实现了url匹配和静态资源访问,可以使用作为RESTful API的后台。

整体架构

整体是建立在网络库连接的抽象上的,但服务器接收到消息,将其解析成HTTP Request,然后通过路由器进行匹配,得到匹配的Hander进行处理,如果没有匹配则直接返回404 Response。处理完生成对应的Response发送回去。
C++网络编程实战项目--Sinetlib网络库(5)——HTTP服务器设计与实现

解析

对于http请求的解析,使用HttpParser,主要是使用有限状态机来进行字符串匹配。

路由

这里的设计参考了golang的mux包,首先Router下有多个Route,每个Route下又有多个Matcher

每个Matcher都对应了一条匹配条件,比如要求请求的方法为GET。当一个请求匹配了Route下的所有条件,即匹配成功这个Route,就可以得到该Route的处理函数来处理Request了。如果没有匹配的Route,那么就使用默认的处理函数,即返回404页面。

Matcher的匹配主要是通过正则表达式来进行,用户可以利用正则表达式来取得一些参数,具体请参考github上的README. md

静态资源

文件的访问由File处理,它主要是提供该文件或目录的相关信息,并通过mmap内存映射方式将文件读取出来。

当用户访问资源时,相应的处理函数由FileHandler提供。

示例

#include "httpserver.h"

void OnHttpCallback(const HttpRequest& request, std::unordered_map<std::string, std::string>& match_map, HttpResponse* response)
{
    response->SetStatusCode(HttpResponse::OK);
    response->SetStatusMessage("OK");
    response->SetContentType("text/html");

    std::string body = "temp test page";
    response->AddHeader("Content-Length", std::to_string(body.size()));
    response->AppendHeaderToBuffer();
    response->AppendBodyToBuffer(body);
}

int main()
{
    Looper loop;
    HttpServer s(&loop, 8888, 4);

    s.NewRoute()
    ->SetPath("/path/{name:[a-zA-Z]+}")
    ->SetHeader("Connection", "keep-alive")
    ->SetHandler(OnHttpCallback);
    
    s.NewRoute()
    ->SetPrefix("/file/")
    ->SetHandler(s.GetFileHandler("/home/"));

    s.Start();
    loop.Start();
}

使用上述程序,并通过浏览器访问,效果如下:

测试页面
C++网络编程实战项目--Sinetlib网络库(5)——HTTP服务器设计与实现

静态资源
C++网络编程实战项目--Sinetlib网络库(5)——HTTP服务器设计与实现