HTTP protocol parsing
1. Iso-osi seven-layer network model
-
The application layer
An interface between a network service and an end user. Protocol: HTTP FTP
-
Presentation layer (five-layer model application layer)
Data representation, security, compression. The formats are JPEG, ASCll, EBCDIC, encryption format and so on
-
Session layer (five-tier model application layer)
Establish, manage, and terminate sessions. The corresponding host process refers to the ongoing session between the local host and the remote host
-
The transport layer
Defines the protocol port numbers for transmitting data, as well as flow control and error-checking. The protocols are as follows: TCP UDP: Once the data packet leaves the network adapter, it enters the network transmission layer
-
At the network layer, logical address is addressed to select paths between different networks. The protocols are as follows: IP (IPV4 IPV6)
-
Data link layer
Establish logical connection, hardware address addressing, error checking and other functions. (defined by the underlying network protocol) combines bits into bytes and then into frames, accesses media with MAC addresses, errors found but not corrected.
-
The physical layer
Establish, maintain, and disconnect physical connections. (Protocols defined by the underlying network)
Flow: There is no obvious division of units, only the correct order is guaranteed
Port: The received data packets are distributed to each application
Require (‘net’) : node dependency library
Package:
IP address:
Libnet /libpcap: Libnet constructs IP packets and sends them. Libpcap grabs all packets that flow through the nic
Full-duplex channels do not have precedence, but HTTP must be initiated by the client and the server returns a response
2. Prepare the server environment
-
POST / HTTP/1.1
Request line
-
Host: 127.0.0.1 content-type: application/x – WWW – form – urlencoded
headers
-
field1=aaa&code=x%3D1
body
const http = require('http');
http.createServer((request, response) => {
let body = [];
request.on('error',(err) => {
console.error(err);
}).on('data',(chunk) =>{
body.push(chunk.toString())
}).on('end',()=>{
body = Buffer.concat(body).toString();
console.log('body:',body);
response.writeHead(200,{'Content-T':'text/html'});
response.end("
123
")
})
}).listen(8080);
console.log('server started');
Copy the code
Implement an HTTP request
const net = require("net");
class Request {
constructor(option) {
this.method = option.method || 'GET';
this.host = option.host;
this.port = option.port || 80;
this.path = option.path || '/';
this.body = option.body || {};
this.headers = option.headers || {};
if(! this.headers["Content-Type"]){
this.headers["Content-Type"] = "application/x-www-form-urlencoded"
}
if(this.headers["Content-Type"= = ="application/json"){
this.bodyText = JSON.stringify(this.body)
}else if(this.headers["Content-Type"= = ="application/x-www-form-urlencoded"){
this.bodyText = Object.keys(this.body).map(key => `${key}=${encodeURIComponent(this.body[key])}`).join('&')
}
this.headers["Content-Length"] = this.bodyText.length;
}
send() {return new Promise((resolve, reject) => {
//.....
});
}
}
void async function () {
let request = new Request({
method: "POST",
host: "127.0.0.1",
port: "8088",
path: "/",
headers: {
["X-Foo2"] :"customed"
},
body: {
name: 'Midsummer'}})letresponse = await request.send(); console.log(response); } ()Copy the code
4. Write send function and understand response format
- State line HTTP/1.1 200 (HTTP status code) OK
- headers
- body
Send a request
C. Response D. response
- The Response must be piecewise constructed, so we’ll “assemble” it with a ResponseParser
- ResponseText, we use the state machine to analyze the structure of the text
C) Response body d) response body
- The body of a Response may have a different structure depending on the Content-Type, so we’ll use a subparser structure to solve the problem
- Using TrunkedBodyParser as an example, we also use the state machine to process the body format