在对Peer类的源码解析中提到,peer.data_
字段中存放了用于接收Http请求的结构,即Request类,Request类用于存放解析后Http请求。
在此之前需要了解一下HTTP 请求的结构:
发起一个简单的http请求,查看chrome的请求头以及响应头的信息: Request/Respone Body
请求头
- 请求行(RequestLine)
- 请求方法:GET
- URI:/ping?k1=v1&k2=v2
- 协议版本:HTTP/1.1
- 请求头部(Headers)
头部都是一个KV的字符串,比较重要的如:- Host:127.0.0.1:9080
- Connection: keep-alive,长链接
- Cookie
- 请求体(Body)
GET方法是没有请求体的,其传递的数据一查询参数(Query Parameters)的形式存在
响应头
- 状态行(ResponseLine)
- 版本协议:HTTP/1.1
- 状态码:200
- 状态信息:OK
- 响应头部
- Connection: keep-alive,长链接
- Content-Length:4,响应体的长度
- 响应体
通常时HTML页面,长度由响应头部的Content-Length指定,单位为字节。
Message Class
在Pistache的实现中,Request类、Respone类都继承自父类Message。父类Message描述了Http请求(或响应)的大部分信息:
class Message
{
public:
friend class Private::HeadersStep;
friend class Private::BodyStep;
friend class ResponseWriter;
Message() = default;
explicit Message(Version version);
Message(const Message& other) = default;
Message& operator=(const Message& other) = default;
Message(Message&& other) = default;
Message& operator=(Message&& other) = default;
Version version() const;
Code code() const;
const std::string& body() const;
std::string body();
const CookieJar& cookies() const;
CookieJar& cookies();
const Header::Collection& headers() const;
Header::Collection& headers();
protected:
Version version_ = Version::Http11;
Code code_;
std::string body_;
CookieJar cookies_;
Header::Collection headers_;
};
成员变量
protected
-
Version version_ = Version::Http11;
对应协议版本,默认即Http11(HTTP1.1) -
Code code_;
状态码,用于响应头中 -
std::string body_;
请求体或者响应体,其大小受到Endpoint.Options.maxRequestSize_
和Endpoint.Options.maxResponseSize_
的限制 -
CookieJar cookies_;
用于接受或发送cookie,cookie本身也是HTTP协议定义的一种信息交互机制 -
Header::Collection headers_;
用于接受或发送头信息
Request Class
class Request : public Message
{
public:
friend class Private::RequestLineStep;
friend class RequestBuilder;
Request() = default;
Request(const Request& other) = default;
Request& operator=(const Request& other) = default;
Request(Request&& other) = default;
Request& operator=(Request&& other) = default;
Method method() const;
const std::string& resource() const;
const Uri::Query& query() const;
const Address& address() const;
void copyAddress(const Address& address) { address_ = address; }
std::chrono::milliseconds timeout() const;
private:
Method method_;
std::string resource_;
Uri::Query query_;
Address address_;
std::chrono::milliseconds timeout_ = std::chrono::milliseconds(0);
};
成员变量
private
-
Method method_;
请求头的第一个字段,请求方式:GET -
std::string resource_;
请求的资源路径即,URI:/ping -
Uri::Query query_;
请求的查询参数,即url中”?“后面的部分,GET方法传递消息的方式,讲义K-V的方式存放到query_中 -
Address address_;
client端的地址信息,由peer赋值,因为在http的请求头中是不包括这部分的。 -
std::chrono::milliseconds timeout_ = std::chrono::milliseconds(0);
超时时间,用于client端,默认不设置超时。
成员函数
无论是Request 还是 Message 的成员函数,都是简单的getter,真正的接收TCP数据,进行解析(parser),最后赋值到Request中,还需要ParserImpl类。
网友评论