Table of contents
4. Server response information
4. Relationship between domain name and IP
3. Design request and response class basic data structure
1. Basic concepts of HTTP
1. What is HTTP?
HTTP (HyperText Transfer Protocol) is a transfer protocol for transferring hypertext from an Internet server to a local browser. It is an application layer protocol and a standard for publishing and receiving HTML pages.
2. What is an HTTP client
An HTTP client is an application that sends HTTP requests and receives responses. It can be a web browser such as Google Chrome or Mozilla Firefox, or a command-line tool such as curl or wget.
3. HTTP message structure
An HTTP message consists of four parts: request line, request header, blank line, and request body.
1). Request line: contains request method, URL and HTTP protocol version;
2). Request header: contains client information, content information, etc.;
3). Blank line: used to separate the request header and the request body;
4). Request body: contains the data sent by the client.
Examples of message requests are as follows:
POST / HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: _ga=GA1.2.2045678901234567890; _gid=GA1.2.2045678901234567890; _gat_gtag_UA_1234567890_1=1
name=John&age=20
4. Server response information
The server response consists of the following parts:
1). Status line: contains HTTP protocol version, status code and description information, for example: HTTP/1.1 200 OK
2). Response header: contains some information on the server side, such as Content-Type, Content-Length, etc.
3). Empty line: used to separate the response header and response body.
4). Response body: contains the resource content requested by the client.
An example of a response message is as follows:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Connection: keep-alive
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
2. Related concepts
1. Website URL
URL (Uniform Resource Locator) is a resource locator used to locate resources on the Internet.
It is a universal string that can be used to identify a specific web page, image, file or other resource.
A full URL includes:
Protocol (Protocol), Domain Name (Domain Name), Port Number (Port Number), Path (Path) and Parameters (Parameters).
For example: https://www.example.com:8080/path/to/file?param1=value1¶m2=value2
2. IP address
An IP address (Internet Protocol Address) is an address used to locate a device in a computer network.
It is a 32-bit binary number, usually represented as 4 decimal digits separated by periods (eg 192.168.1.1).
3. Domain name
The IP address is not easy to remember, so the domain name (Domain Name) appears
4. Relationship between domain name and IP
An IP address is a string of four numbers that identifies a computer's location on the Internet. A domain name is a name that can be remembered by people, and it can map an IP address to a more readable name.
There is a one-to-many relationship between IP addresses and domain names. An IP address can correspond to multiple domain names, but a domain name has only one IP address.
5. Domain name resolution
Although the domain name is easy for people to remember, the machines only know each other's IP addresses. The conversion work between them is called domain name resolution, which is completed by a dedicated domain name resolution server DNS.
6、DNS
DNS (Domain Name System) is a distributed database system used to convert domain names into IP addresses. It is a distributed, hierarchical, and scalable database for storing and retrieving the mapping relationship between domain names and IP addresses.
3. Design request and response class basic data structure
The following is the data structure used in my project, just to help understand the main idea, not necessarily suitable for other projects.
1. Request class definition
typedef std::map<std::string,std::string> MAPSTRSTR;
class HTTPD_API CHttpRequest
{
char m_host[64];
char m_method[8];
char m_uri[1023];
char m_ssl;
MAPSTRSTR* m_map;
MAPSTRSTR* m_mParam;
public:
CHttpRequest() {
m_ssl=0;
m_map=m_mParam=0;
}
// host:port, GET|POST, /aaa/aaa.html?query_string
CHttpRequest(const char* host,const char* method,const char* uri) {
m_ssl=0;
m_map=m_mParam=0;
Set(host,method,uri);
}
~CHttpRequest() {
if(m_map) {
delete m_map;
m_map=0;
}
if(m_mParam) {
delete m_mParam;
m_mParam=0;
}
}
// http[s]://host:port/abc.html?query_string, GET|POST
void Set(const char* url,const char* method);
// host:port, GET|POST, /aaa/aaa.html?query_string
void Set(const char* host,const char* method,const char* uri) {
strcpyN(m_host,host,sizeof(m_host));
strcpyN(m_method,method,sizeof(m_method));
strcpyN(m_uri,uri,sizeof(m_uri));
}
int IsSsl() const { return m_ssl; }
void SetSsl(int ssl) { m_ssl = ssl; }
int GetHostPort(char* szHost, int size) const;
// header
void AddPair(const char* key,const char* v) {
if(!m_map) m_map=new MAPSTRSTR;
(*m_map)[key]=v;
}
// query_string
void AddParam(const char* key,const char* v) {
if(!m_mParam) m_mParam=new MAPSTRSTR;
(*m_mParam)[key]=v;
}
const char* Format(CBinBuf& req,const char* ctype,const char* data,int l);
const char* GetURL()
{
return m_uri;
}
const char* GetHost()
{
return m_host;
}
const char* Method()
{
return m_method;
}
};
// return
// 0: http
// 1: https
HTTPD_API int http_parse_hostport(const char* url, char* host, int hsize, int& port, char* uri, int usize);
void CHttpRequest::Set(const char* url,const char* method)
{
char host[128],uri[256];
int port;
int ssl = http_parse_hostport(url,host,sizeof(host),port,uri,sizeof(uri));
if(!method) method="GET";
char szHost[256];
if(port==80 || port==443) strcpy(szHost,host);
else sprintf(szHost,"%s:%d",host,port);
Set(szHost,method,uri);
m_ssl = ssl;
}
2. Response class definition
// when act as http client or http server.
class HTTPD_API CHttpResponse
{
MAPSTRSTR m_map;
#ifdef ENABLE_HTTP2
const char* FormatV2(int code,MAPSTRSTR& mheader,const char* data=0,int len=0,int bHead=0,uint64_t ctlen=0);
public:
CBinBuf m_v2Body;
#endif
public:
char m_v2;
CBinBuf m_bf;
public:
CHttpResponse(int v2=0) {
m_v2 = v2;
}
void AddPair(const char* key,const char* v) {
m_map[key]=v;
}
const char* Format(int code,const char* reason,int keepalive,const char* data=0,int len=0,int bHead=0,uint64_t ctlen=0);
const char* Format(int code,const char* reason,int keepalive,MAPSTRSTR& mheader,const char* data=0,int len=0,int bHead=0,uint64_t ctlen=0);
};
Format is mainly used to format response information
const char* CHttpResponse::Format(int code,const char* reason,int keepalive,MAPSTRSTR& mheader,const char* data,int len,int bHead,uint64_t ctlen)
{
if(!ctlen) ctlen=len;
#ifdef ENABLE_HTTP2
if(m_v2) {
return FormatV2(code, mheader, data, len, bHead, ctlen);
}
#endif
// Status-Line
m_bf.Format("HTTP/1.1 %03d %s\r\n",code,reason);
// Date
char szTm[32];
m_bf.AppendFormat("Date: %s\r\n",rfc1123_date(time(0),szTm));
// Server
m_bf.AppendFormat("Server: banhttpd/%s\r\n",g_httpd_ver);
m_bf.AppendFormat("X-Frame-Options: SAMEORIGIN\r\n");
if(keepalive) {
m_bf.Append("Connection: Keep-Alive\r\nKeep-Alive: timeout=5, max=100\r\n");
} else {
m_bf.Append("Connection: close\r\n");
}
// Content-Type
if(mheader.find("Content-Type")!=mheader.end()) {
m_bf.AppendFormat("Content-Type: %s\r\n",mheader["Content-Type"].c_str());
}
// Content-Length
m_bf.AppendFormat("Content-Length: %llu\r\n",ctlen);
for(MAPSTRSTR::iterator it=mheader.begin();it!=mheader.end();++it) {
if( strcmp(it->first.c_str(),"Content-Type")==0
|| strcmp(it->first.c_str(),"Content-Length")==0)
{
continue;
}
m_bf.AppendFormat("%s: %s\r\n",it->first.c_str(),it->second.c_str());
}
// end header
m_bf.Append("\r\n",2);
// body
if(!bHead) m_bf.Append(data,len);
m_bf.ReleaseBuffer();
return m_bf.GetPtr();
}