const CRLFCRLF = Buffer.from('\r\n\r\n');
const EOF = Buffer.from('\0');
const console = require('console');
const net = require('net');
const http = require('http');
const server = net.createServer()
.on('error', console.error)
.on('connection', (socket) => {
let chunks = Buffer.from([]);
const data = {};
socket
.on('error', console.error)
.on('data', (chunk) => {
chunks = Buffer.concat([chunks, chunk]);
if (!data.headers) {
const index = chunks.indexOf(CRLFCRLF);
if (0 <= index) {
const [requestLine, ...headerLines] = chunks.slice(0, index).toString().split('\r\n');
chunks = chunks.slice(index + CRLFCRLF.length);
const [method, uri, version] = requestLine.split(/\s+/);
Object.assign(data, {method, uri, version});
const headers = data.headers = {};
for (const line of headerLines) {
const delimiterIndex = line.indexOf(':');
const key = line.slice(0, delimiterIndex).trim().toLowerCase();
const value = line.slice(delimiterIndex + 1).trim();
headers[key] = value;
}
data.contentLength = parseInt(headers['content-length'], 10);
data.checkEOF = 0 <= data.contentLength
? (chunks) => data.contentLength <= chunks.length
: (chunks) => 0 <= chunks.indexOf(EOF);
}
}
if (data.checkEOF && data.checkEOF(chunks)) {
const responseBody = Buffer.concat([
Buffer.from('##START##\n'),
chunks,
Buffer.from('\n##END##'),
]);
socket.write(Buffer.from([
'HTTP/1.0 200 GOOD',
'content-type: text/plain',
`content-length: ${responseBody.length}`,
'\r\n',
].join('\r\n')));
socket.write(responseBody);
socket.end();
}
});
})
.once('listening', () => {
const requestBody = Buffer.from('Hello!!!');
const req = http.request({
host: '127.0.0.1',
port: server.address().port,
method: 'POST',
headers: {
'content-type': 'text/plain',
'content-length': `${requestBody.length}`,
},
})
.on('error', console.error)
.once('response', (res) => {
console.log(`${res.statusCode} ${res.statusMessage}`);
console.log(`res.headers: ${JSON.stringify(res.headers, null, 2)}`);
const chunks = [];
res
.on('error', console.error)
.on('data', (chunk) => chunks.push(chunk))
.once('end', () => {
console.log(`${Buffer.concat(chunks)}`);
})
});
req.write(requestBody);
req.end();
})
.listen(3000);