提供HTTP服务,主要包含以下几个模块:
HttpMethod
与HTTP状态HttpStatus
。HttpRequest
和HttpResponse
。HttpRequestParser
和HttpResponseParser
。HttpSession
。HttpConnection
,用于发起GET/POST等请求,支持连接池。HTTP模块依赖nodejs/http-parser提供的HTTP解析器,并且直接复用了nodejs/http-parser中定义的HTTP方法与状态枚举。
包括HttpMethod和HttpStatus两个定义,如下:
/* Request Methods */ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ XX(1, GET, GET) \ XX(2, HEAD, HEAD) \ XX(3, POST, POST) \ XX(4, PUT, PUT) \ ... /* Status Codes */ #define HTTP_STATUS_MAP(XX) \ XX(100, CONTINUE, Continue) \ XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ XX(102, PROCESSING, Processing) \ XX(200, OK, OK) \ XX(201, CREATED, Created) \ XX(202, ACCEPTED, Accepted) \ XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ ... |
/** * @brief HTTP方法枚举 */ enum class HttpMethod { #define XX(num, name, string) name = num, HTTP_METHOD_MAP(XX) #undef XX INVALID_METHOD }; /** * @brief HTTP状态枚举 */ enum class HttpStatus { #define XX(code, name, desc) name = code, HTTP_STATUS_MAP(XX) #undef XX }; |
包括HttpRequest和HttpResponse两个结构,用于封装HTTP请求与响应。
关于HTTP请求和响应的格式可参考HTTP消息 - HTTP | MDN,以下是一个HTTP请求与响应的示例:
对于HTTP请求,需要关注HTTP方法,请求路径和参数,HTTP版本,HTTP头部的key-value结构,Cookies,以及HTTP Body内容。
对于HTTP响应,需要关注HTTP版本,响应状态码,响应字符串,响应头部的key-value结构,以及响应的Body内容。
输入字节流,解析HTTP消息,包括HttpRequestParser和HttpResponseParser两个结构。
HTTP解析器基于nodejs/http-parser实现,通过套接字读到HTTP消息后将消息内容传递给解析器,解析器通过回调的形式通知调用方HTTP解析的内容。
以下是HTTP解析器的类协作图:
继承自SocketStream,实现了在套接字流上读取HTTP请求与发送HTTP响应的功能,在读取HTTP请求时需要借助HTTP解析器,以便于将套接字流上的内容解析成HTTP请求。以下是HttpSession的继承关系图:
继承自TcpServer,重载handleClient方法,将accept后得到的客户端套接字封装成HttpSession结构,以便于接收和发送HTTP消息。
提供HTTP请求路径到处理类的映射,用于规范化的HTTP消息处理流程。
HTTP Servlet包括两部分,第一部分是Servlet对象,每个Servlet对象表示一种处理HTTP消息的方法,第二部分是ServletDispatch,它包含一个请求路径到Servlet对象的映射,用于指定一个请求路径该用哪个Servlet来处理。
以下是Servlet对象用于处理请求的声明:
用于发起GET/POST等请求并获取响应,支持设置超时,keep-alive,支持连接池。
HTTP服务端的业务模型是接收请求→ 发送响应,而HTTP客户端的业务模型是发送请求→ 接收响应。
关于连接池,是指提前预备好一系列已接建立连接的socket,这样,在发起请求时,可以直接从中选择一个进行通信,而不用重复创建套接字→ 发起connect→ 发起请求 的流程。
连接池与发起请求时的keep-alive参数有关,如果使用连接池来发起GET/POST请求,在未设置keep-alive时,连接池并没有什么卵用。