const http = require('http');
const net = require('net');
const url = require('url');
// ============== COMMON ==============
console.log(http.METHODS);
console.log(http.STATUS_CODES);
console.log(http.globalAgent);
// ============== Server ==============
const server = http.createServer();
server.maxHeadersCount = 2000;
server.keepAliveTimeout = 5000;
server.timeout = 120000;
server.setTimeout(120000, function () {
console.log('Server timeout');
});
server.on('connection', function (socket) {
console.log('Client connected');
});
// Используется только, если запрос с типом GET или POST
server.on('request', function (request, response) {
console.log(request.headers);
console.log(request.rawHeaders);
console.log(request.httpVersion);
console.log(request.method);
console.log(request.trailers);
console.log(request.url);
// console.log(request.socket.getPeerCertificate()); // Use with HTTPS support only
request.setTimeout(120000, function () {
console.log('Client request timeout');
});
// request.destroy('my error'); // Работает вместе с request.on('aborted') и request.on('close')
request.on('aborted', function () {
console.log('Request has been aborted by the client');
});
request.on('close', function () {
console.log('Underlying connection was closed');
});
let clientData = '';
request.on('data', function (chunk) {
clientData += chunk;
});
request.on('end', function () {
console.log(request.rawTrailers);
console.log(clientData);
response.setTimeout(1200000, function () {
console.log('Server sockt timeout');
});
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']); // Will be merged with any headers passed to response.writeHead()
console.log('Cookie Header: ' + response.getHeader('Set-Cookie'));
console.log('Header names: ' + response.getHeaderNames());
console.log(response.getHeaders());
if (response.hasHeader('Set-Cookie')) {console.log('Header Set-Cookie set');}
response.removeHeader('Set-Cookie');
response.writeContinue(); // Server sends a "100 Continue" HTTP response
// response.statusCode = 404; // Задачется, если не испоьзуется response.writeHead()
// response.statusMessage = 'Not found'; // Задачется, если не испоьзуется response.writeHead()
response.writeHead(200, 'OK', {'Content-Type': 'text/html'}); // Note that 'Content-Length' is given in bytes not characters.
if (response.headersSent) {console.log('Headers sent');}
if (response.sendDate) {console.log('Date header sent');}
response.write('Response from server');
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end(); // MUST be called on each response.
server.close();
});
response.on('close', function () {
console.log('Underlying connection was terminated before response.end() was called or able to flush');
});
response.on('finish', function () {
console.log('Server responce ended');
if (response.finished) {console.log('Responce finished');}
});
});
// Используется только, если запрос с типом CONNECT вместо GET или POST
server.on('connect', function (request, clientSocket, head) {
// Connect to an origin server
const urlFromClient = url.parse('http://' + request.url);
const serverSocket = net.connect(urlFromClient.port, urlFromClient.hostname, function () {
clientSocket.write(
'HTTP/1.1 200 Connection Established\r\n'
+ 'Proxy-agent: Node.js-Proxy\r\n'
+ '\r\n'
);
serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
});
// Используется только, если запрос с заголовками 'Connection': 'Upgrade' и 'Upgrade': 'websocket'
server.on('upgrade', function (request, socket, head) {
socket.write(
'HTTP/1.1 101 Web Socket Protocol Handshake\r\n'
+ 'Upgrade: WebSocket\r\n'
+ 'Connection: Upgrade\r\n'
+ '\r\n'
);
socket.pipe(socket); // echo back
});
// Нужно только, если клиент устанавливает заголовок Expect с 100-continue
server.on('checkContinue', function (request, response) {
console.log('Server get 100 Continue');
response.writeContinue();
});
// Нужно только, если клиент устанавливает заголовок Expect не с 100-continue
server.on('checkExpectation', function (request, response) {
console.log('Emitted each time a request with an HTTP Expect header is received, where the value is not 100-continue');
});
// Нужен если клиент посылает ошибку
server.on('clientError', function (error, socket) {
console.log('Client emited error');
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.on('error', function (error) {
console.log('Server error: ' + error.message);
});
server.on('close', function () {
console.log('Server closed');
});
server.listen(8080, '127.0.0.5', function (error) {
if (error) {throw error;}
console.log('Server started at 127.0.0.5:8080');
if (server.listening) {
console.log('Server is listening');
}
});
// ============== Client ==============
const options = {
method: 'GET' // 'POST' // 'CONNECT'
, protocol: 'http:'
, auth: 'username:password'
, hostname: '127.0.0.5'
, port: 8080
, path: '/' // 'www.google.com:80'
, agent: new http.Agent({
keepAlive: true // Соединение с сервером должно сохраняться и не разрываться для отправки через него следующих запросов request
, keepAliveMsecs: 1000
, maxSockets: Infinity
, maxFreeSockets: 256
})
, headers: {
'My-Header': 'Hello'
// , 'Connection': 'Upgrade' // Это заголовок нужен, если нужен upgrade подключения
// , 'Upgrade': 'websocket' // Это заголовок нужен, если нужен upgrade подключения
}
, timeout: 120000
};
const client = http.request(options);
client.once('response', function (response) {
console.log(response.headers);
console.log(response.rawHeaders);
console.log(response.httpVersion);
console.log(response.statusCode);
console.log(response.statusMessage);
console.log(response.trailers);
response.setEncoding('utf8');
let serverData = '';
response.on('data', function (chunk) {
serverData += chunk;
});
response.on('end', function () {
console.log(serverData);
});
});
// Используется только, если запрос с типом CONNECT
client.on('connect', function (response, socket, head) {
console.log('Connect emitted each time a server responds to a request with a CONNECT method.');
// Make a request over an HTTP tunnel
socket.on('data', function (chunk) {
console.log(chunk.toString());
});
socket.on('end', function () {
console.log('Connection to Google closed');
server.close();
});
socket.write(
'GET / HTTP/1.1\r\n'
+ 'Host: www.google.com:80\r\n'
+ 'Connection: close\r\n'
+ '\r\n'
);
socket.end();
});
client.on('socket', function () {
console.log('Emitted after a socket is assigned to this request.');
});
client.on('abort', function () {
console.log('Request has been aborted by the client');
});
client.on('aborted', function () {
console.log('Request has been aborted by the server');
});
// Используется только, если сервер выполнил response.writeContinue()
client.on('continue', function () {
console.log('Server sends a "100 Continue" HTTP response');
});
// Используется только, если запрос с заголовками 'Connection': 'Upgrade' и 'Upgrade': 'websocket'
client.on('upgrade', function (response, socket, upgradeHead) {
console.log('Client upgraded');
socket.end();
process.exit(0);
});
client.on('error', function (error) {
console.log('Client error: ' + error.message);
});
client.setHeader('My-Other-Header', 'Hi');
console.log(client.getHeader('My-Header')); // 'Hello'
client.removeHeader('My-Header');
// client.setHeader('Expect', '100-continue'); // Нужно только, если сервер ожидает событие checkContinue
// client.setHeader('Expect', 'not-100-continue'); // Нужно только, если сервер ожидает событие checkExpectation
client.setNoDelay(true);
client.setSocketKeepAlive(true, 1000);
client.setTimeout(10, function () {
console.log('Client timeout');
});
client.flushHeaders(); // Обычно заголовки и данные упаковываются в единый пакет для отправки. flushHeaders() не деалет эту оптимизацию.
client.write('Client data');
// client.abort();
if (client.aborted) {
console.log('Client aborted');
}
client.end(); // MUST always call
Комментариев нет:
Отправить комментарий