HTTP/2
Исходный код: lib/http2.js
Модуль node:http2 предоставляет реализацию протокола HTTP/2. Доступ к нему можно получить с помощью:
const http2 = require('node:http2'); copy Определение отсутствия поддержки криптографии
Node.js может быть собран без поддержки модуля node:crypto. В таких случаях попытка выполнить import из node:http2 или вызов require('node:http2') приведёт к ошибке.
При использовании CommonJS возникшую ошибку можно перехватить с помощью try/catch:
let http2;
try {
http2 = require('node:http2');
} catch (err) {
console.error('http2 support is disabled!');
} copy При использовании лексического ключевого слова ESM import ошибку можно перехватить, только если обработчик для process.on('uncaughtException') зарегистрирован до попытки загрузить модуль (например, с помощью модуля предварительной загрузки).
При использовании ESM, если код может выполняться в сборке Node.js без поддержки криптографии, рассмотрите возможность использовать функцию import() вместо лексического ключевого слова import:
let http2;
try {
http2 = await import('node:http2');
} catch (err) {
console.error('http2 support is disabled!');
} copy Базовый API
Базовый API предоставляет низкоуровневый интерфейс, специально разработанный для поддержки возможностей протокола HTTP/2. Он не предназначен для совместимости с существующим API модуля HTTP/1. Для этого предназначен API совместимости.
Базовый API http2 гораздо более симметричен для клиента и сервера, чем API http. Например, большинство событий, таких как 'error', 'connect' и 'stream', могут генерироваться как кодом на стороне клиента, так и кодом на стороне сервера.
Пример на стороне сервера
Ниже показан простой сервер HTTP/2, использующий базовый API. Поскольку браузеров с поддержкой HTTP/2 без шифрования не известно, при взаимодействии с клиентами-браузерами необходимо использовать http2.createSecureServer().
Модули JavaScript
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const server = createSecureServer({
key: readFileSync('localhost-privkey.pem'),
cert: readFileSync('localhost-cert.pem'),
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
// stream is a Duplex
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);CommonJS
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem'),
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
// stream is a Duplex
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);Чтобы создать сертификат и ключ для этого примера, выполните:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ -keyout localhost-privkey.pem -out localhost-cert.pem copy
Пример на стороне клиента
Ниже показан клиент HTTP/2:
Модули JavaScript
import { connect } from 'node:http2';
import { readFileSync } from 'node:fs';
const client = connect('https://localhost:8443', {
ca: readFileSync('localhost-cert.pem'),
});
client.on('error', (err) => console.error(err));
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
for (const name in headers) {
console.log(`${name}: ${headers[name]}`);
}
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
console.log(`\n${data}`);
client.close();
});
req.end();CommonJS
const http2 = require('node:http2');
const fs = require('node:fs');
const client = http2.connect('https://localhost:8443', {
ca: fs.readFileSync('localhost-cert.pem'),
});
client.on('error', (err) => console.error(err));
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
for (const name in headers) {
console.log(`${name}: ${headers[name]}`);
}
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
console.log(`\n${data}`);
client.close();
});
req.end();Класс: Http2Session
- Расширяет: <EventEmitter>
Экземпляры класса http2.Http2Session представляют активный сеанс связи между клиентом и сервером HTTP/2. Экземпляры этого класса не предназначены для непосредственного создания пользовательским кодом.
Поведение каждого экземпляра Http2Session будет немного различаться в зависимости от того, работает ли он как сервер или как клиент. Чтобы определить режим работы Http2Session, можно использовать свойство http2session.type. На стороне сервера пользовательскому коду редко приходится напрямую работать с объектом Http2Session: большинство действий обычно выполняется посредством взаимодействия с объектами Http2Server или Http2Stream.
Пользовательский код не создает экземпляры Http2Session напрямую. Экземпляры Http2Session на стороне сервера создаются экземпляром Http2Server при получении нового соединения HTTP/2. Экземпляры Http2Session на стороне клиента создаются с помощью метода http2.connect().
Http2Session и сокеты
При создании каждый экземпляр Http2Session связывается ровно с одним объектом net.Socket или tls.TLSSocket. При уничтожении Socket или Http2Session уничтожаются оба объекта.
Из-за особых требований протокола HTTP/2 к сериализации и обработке не рекомендуется считывать данные из экземпляра Socket, связанного с Http2Session, или записывать в него данные пользовательским кодом. Это может привести к неопределенному состоянию сеанса HTTP/2, в результате чего сеанс и сокет станут непригодными для использования.
После связывания Socket с Http2Session пользовательскому коду следует полагаться исключительно на API Http2Session.
Событие: 'close'
Событие 'close' генерируется после уничтожения Http2Session. Обработчик события не ожидает аргументов.
Событие: 'connect'
-
session<Http2Session> -
socket<net.Socket>
Событие 'connect' генерируется после успешного подключения Http2Session к удаленному узлу, когда становится возможен обмен данными.
Пользовательский код обычно не подписывается на это событие напрямую.
Событие: 'error'
-
error<Error>
Событие 'error' генерируется при возникновении ошибки во время обработки Http2Session.
Событие: 'frameError'
-
type<integer> Тип кадра. -
code<integer> Код ошибки. -
id<integer> Идентификатор потока (или0, если кадр не связан с потоком).
Событие 'frameError' генерируется при возникновении ошибки при попытке отправить кадр в рамках сеанса. Если кадр, который не удалось отправить, связан с определенным Http2Stream, предпринимается попытка сгенерировать событие 'frameError' для Http2Stream.
Если событие 'frameError' связано с потоком, поток будет закрыт и уничтожен сразу после события 'frameError'. Если событие не связано с потоком, Http2Session будет остановлен сразу после события 'frameError'.
Событие: 'goaway'
-
errorCode<number> Код ошибки HTTP/2, указанный в кадреGOAWAY. -
lastStreamID<number> Идентификатор последнего потока, успешно обработанного удаленным узлом (или0, если идентификатор не указан). -
opaqueData<Buffer> Если в кадреGOAWAYбыли дополнительные непрозрачные данные, будет передан экземплярBuffer, содержащий эти данные.
Событие 'goaway' генерируется при получении кадра GOAWAY.
Экземпляр Http2Session будет автоматически остановлен при генерации события 'goaway'.
Событие: 'localSettings'
-
settings<HTTP/2 Settings Object> Копия полученного кадраSETTINGS.
Событие 'localSettings' генерируется при получении кадра SETTINGS с подтверждением.
При использовании http2session.settings() для отправки новых настроек измененные настройки вступают в силу только после генерации события 'localSettings'.
session.settings({ enablePush: false });
session.on('localSettings', (settings) => {
/* Use the new settings */
}); copy Событие: 'ping'
-
payload<Buffer> Полезная нагрузка кадраPINGразмером 8 байт
Событие 'ping' генерируется при каждом получении кадра PING от подключенного узла.
Событие: 'remoteSettings'
-
settings<HTTP/2 Settings Object> Копия полученного кадраSETTINGS.
Событие 'remoteSettings' генерируется при получении нового кадра SETTINGS от подключенного узла.
session.on('remoteSettings', (settings) => {
/* Use the new settings */
}); copy Событие: 'stream'
-
stream<Http2Stream> Ссылка на поток -
headers<HTTP/2 Headers Object> Объект с описанием заголовков -
flags<number> Соответствующие числовые флаги -
rawHeaders<HTTP/2 Raw Headers> Массив, содержащий исходные заголовки
Событие 'stream' генерируется при создании нового Http2Stream.
session.on('stream', (stream, headers, flags) => {
const method = headers[':method'];
const path = headers[':path'];
// ...
stream.respond({
':status': 200,
'content-type': 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
}); copy На стороне сервера пользовательский код обычно не подписывается на это событие напрямую, а регистрирует обработчик события 'stream', генерируемого экземплярами net.Server или tls.Server, возвращаемыми соответственно методами http2.createServer() и http2.createSecureServer(), как показано в примере ниже:
Модули JavaScript
import { createServer } from 'node:http2';
// Create an unencrypted HTTP/2 server
const server = createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.on('error', (error) => console.error(error));
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);CommonJS
const http2 = require('node:http2');
// Create an unencrypted HTTP/2 server
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.on('error', (error) => console.error(error));
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);Хотя потоки HTTP/2 и сетевые сокеты не соответствуют друг другу один к одному, сетевая ошибка уничтожает каждый отдельный поток, поэтому ее необходимо обрабатывать на уровне потока, как показано выше.
Событие: 'timeout'
После вызова метода http2session.setTimeout() для установки периода ожидания для этого Http2Session событие 'timeout' генерируется, если на Http2Session не было активности в течение заданного количества миллисекунд. Обработчик события не ожидает аргументов.
session.setTimeout(2000);
session.on('timeout', () => { /* .. */ }); copy
http2session.alpnProtocol
- Тип: <string> | <undefined>
Значение будет равно undefined, если Http2Session еще не подключен к сокету, h2c, если Http2Session не подключен к TLSSocket, или свойству alpnProtocol подключенного TLSSocket.
http2session.close([callback])
-
callback<Function>
Корректно закрывает Http2Session, позволяя существующим потокам завершиться самостоятельно и запрещая создание новых экземпляров Http2Stream. После закрытия может быть вызван http2session.destroy(), если не осталось открытых экземпляров Http2Stream.
Если указана функция callback, она регистрируется как обработчик события 'close'.
http2session.closed
- Тип: <boolean>
Будет равно true, если этот экземпляр Http2Session закрыт, и false в противном случае.
http2session.connecting
- Тип: <boolean>
Будет равно true, если этот экземпляр Http2Session все еще подключается. Перед генерацией события connect и/или вызовом обратного вызова http2.connect ему будет присвоено значение false.
http2session.destroy([error][, code])
-
error<Error> ОбъектError, еслиHttp2Sessionуничтожается из-за ошибки. -
code<number> Код ошибки HTTP/2, отправляемый в заключительном кадреGOAWAY. Если он не указан, аerrorне равен undefined, по умолчанию используетсяINTERNAL_ERROR; в противном случае используетсяNO_ERROR.
Немедленно завершает Http2Session и связанный с ним net.Socket или tls.TLSSocket.
После уничтожения Http2Session сгенерирует событие 'close'. Если error не равен undefined, событие 'error' будет сгенерировано непосредственно перед событием 'close'.
Все оставшиеся открытые Http2Streams, связанные с Http2Session, также будут уничтожены.
http2session.destroyed
- Тип: <boolean>
Будет равно true, если этот экземпляр Http2Session уничтожен и больше не должен использоваться, и false в противном случае.
http2session.encrypted
- Тип: <boolean> | <undefined>
Значение равно undefined, если сокет сеанса Http2Session еще не подключен, true, если Http2Session подключен к TLSSocket, и false, если Http2Session подключен к сокету или потоку любого другого типа.
http2session.goaway([code[, lastStreamID[, opaqueData]]])
-
code<number> Код ошибки HTTP/2 -
lastStreamID<number> Числовой идентификатор последнего обработанногоHttp2Stream -
opaqueData<Buffer> | <TypedArray> | <DataView> ЭкземплярTypedArrayилиDataView, содержащий дополнительные данные для передачи в кадреGOAWAY.
Отправляет кадр GOAWAY подключенному узлу, не останавливая Http2Session.
http2session.localSettings
Объект без прототипа, описывающий текущие локальные настройки этого Http2Session. Локальные настройки относятся к этому экземпляру Http2Session.
http2session.originSet
- Тип: <string[]> | <undefined>
Если Http2Session подключен к TLSSocket, свойство originSet возвращает Array источников, для которых Http2Session можно считать авторитетным.
Свойство originSet доступно только при использовании защищенного TLS-соединения.
http2session.pendingSettingsAck
- Тип: <boolean>
Указывает, ожидает ли в данный момент Http2Session подтверждения отправленного кадра SETTINGS. Будет равно true после вызова метода http2session.settings(). Будет равно false после подтверждения всех отправленных кадров SETTINGS.
http2session.ping([payload, ]callback)
-
payload<Buffer> | <TypedArray> | <DataView> Необязательная полезная нагрузка ping. -
callback<Function> - Возвращает: <boolean>
Отправляет кадр PING подключенному узлу HTTP/2. Необходимо указать функцию callback. Метод вернет true, если PING был отправлен, и false в противном случае.
Максимальное количество ожидающих подтверждения ping определяется параметром конфигурации maxOutstandingPings. Максимальное значение по умолчанию — 10.
Если указан, payload должен быть объектом Buffer, TypedArray или DataView, содержащим 8 байт данных, которые будут переданы вместе с PING и возвращены с подтверждением ping.
Обратный вызов будет вызван с тремя аргументами: аргументом ошибки, равным null, если PING успешно подтвержден; аргументом duration, содержащим количество миллисекунд между отправкой ping и получением подтверждения; и Buffer, содержащим 8-байтовую полезную нагрузку PING.
session.ping(Buffer.from('abcdefgh'), (err, duration, payload) => {
if (!err) {
console.log(`Ping acknowledged in ${duration} milliseconds`);
console.log(`With payload '${payload.toString()}'`);
}
}); copy Если аргумент payload не указан, полезной нагрузкой по умолчанию будет 64-битная метка времени (в порядке байтов от младшего к старшему), обозначающая начало интервала PING.
http2session.ref()
Вызывает ref() для базового объекта net.Socket этого экземпляра Http2Session.
http2session.remoteSettings
Объект без прототипа, описывающий текущие удаленные настройки этого Http2Session. Удаленные настройки задаются подключенным узлом HTTP/2.
http2session.setLocalWindowSize(windowSize)
-
windowSize<number>
Устанавливает размер окна локальной конечной точки. windowSize — это общий размер окна, который необходимо установить, а не разница между размерами.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
const expectedWindowSize = 2 ** 20;
server.on('session', (session) => {
// Set local window size to be 2 ** 20
session.setLocalWindowSize(expectedWindowSize);
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
const expectedWindowSize = 2 ** 20;
server.on('session', (session) => {
// Set local window size to be 2 ** 20
session.setLocalWindowSize(expectedWindowSize);
});Для клиентов HTTP/2 подходящим событием будет 'connect' или 'remoteSettings'.
http2session.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function>
Используется для задания функции обратного вызова, которая вызывается, если на Http2Session нет активности в течение msecs миллисекунд. Указанный callback регистрируется как обработчик события 'timeout'.
http2session.socket
- Тип: <net.Socket> | <tls.TLSSocket>
Возвращает объект Proxy, который действует как net.Socket (или tls.TLSSocket), но ограничивает доступные методы теми, которые безопасно использовать с HTTP/2.
Вызов destroy, emit, end, pause, read, resume или write приведет к ошибке с кодом ERR_HTTP2_NO_SOCKET_MANIPULATION. Дополнительные сведения см. в разделе Http2Session и сокеты.
Метод setTimeout будет вызван для этого Http2Session.
Все остальные операции будут напрямую передаваться сокету.
http2session.state
Предоставляет различные сведения о текущем состоянии Http2Session.
- Тип: <Object>
-
effectiveLocalWindowSize<number> Текущий размер окна управления потоком на локальной стороне (приема) дляHttp2Session. -
effectiveRecvDataLength<number> Текущее количество байтов, полученных с момента последнегоWINDOW_UPDATEуправления потоком. -
nextStreamID<number> Числовой идентификатор, который будет использован при следующем создании новогоHttp2StreamэтимHttp2Session. -
localWindowSize<number> Количество байтов, которые удаленный узел может отправить без полученияWINDOW_UPDATE. -
lastProcStreamID<number> Числовой идентификаторHttp2Stream, для которого последним был получен кадрHEADERSилиDATA. -
remoteWindowSize<number> Количество байтов, которое этотHttp2Sessionможет отправить без полученияWINDOW_UPDATE. -
outboundQueueSize<number> Количество кадров в очереди исходящих данных для этогоHttp2Session. -
deflateDynamicTableSize<number> Текущий размер таблицы состояния сжатия исходящих заголовков в байтах. -
inflateDynamicTableSize<number> Текущий размер таблицы состояния сжатия входящих заголовков в байтах.
-
Объект, описывающий текущее состояние этого Http2Session.
http2session.settings([settings][, callback])
-
settings<HTTP/2 Settings Object> -
callback<Function> Обратный вызов, который вызывается после подключения сеанса или сразу же, если сеанс уже подключен.-
err<Error> | <null> -
settings<HTTP/2 Settings Object> Обновленный объектsettings. -
duration<integer>
-
Обновляет текущие локальные настройки этого Http2Session и отправляет новый кадр SETTINGS подключенному узлу HTTP/2.
После вызова свойство http2session.pendingSettingsAck будет равно true, пока сеанс ожидает подтверждения новых настроек от удаленного узла.
Новые настройки вступят в силу только после получения подтверждения SETTINGS и генерации события 'localSettings'. Пока ожидается подтверждение, можно отправить несколько кадров SETTINGS.
http2session.type
- Тип: <number>
Значение http2session.type будет равно http2.constants.NGHTTP2_SESSION_SERVER, если этот экземпляр Http2Session является сервером, и http2.constants.NGHTTP2_SESSION_CLIENT, если экземпляр является клиентом.
http2session.unref()
Вызывает unref() для базового объекта net.Socket этого экземпляра Http2Session.
Класс: ServerHttp2Session
- Наследует: <Http2Session>
serverhttp2session.altsvc(alt, originOrStream)
-
alt<string> Описание конфигурации альтернативной службы, определённое в RFC 7838. -
originOrStream<number> | <string> | <URL> | <Object> Строка URL, указывающая источник (илиObjectсо свойствомorigin), либо числовой идентификатор активногоHttp2Stream, указанный в свойствеhttp2stream.id.
Отправляет подключённому клиенту кадр ALTSVC (определённый в RFC 7838).
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('session', (session) => {
// Set altsvc for origin https://example.org:80
session.altsvc('h2=":8000"', 'https://example.org:80');
});
server.on('stream', (stream) => {
// Set altsvc for a specific stream
stream.session.altsvc('h2=":8000"', stream.id);
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('session', (session) => {
// Set altsvc for origin https://example.org:80
session.altsvc('h2=":8000"', 'https://example.org:80');
});
server.on('stream', (stream) => {
// Set altsvc for a specific stream
stream.session.altsvc('h2=":8000"', stream.id);
});Отправка кадра ALTSVC с указанным идентификатором потока означает, что альтернативная служба связана с источником указанного Http2Stream.
alt и строка источника должны содержать только байты ASCII и строго интерпретируются как последовательность байтов ASCII. Специальное значение 'clear' можно передать, чтобы очистить ранее заданную альтернативную службу для указанного домена.
Если аргумент originOrStream является строкой, она будет обработана как URL, и источник будет определён из неё. Например, источником HTTP URL 'https://example.org/foo/bar' является строка ASCII 'https://example.org'. Будет выброшена ошибка, если указанную строку невозможно обработать как URL или если невозможно определить допустимый источник.
В качестве originOrStream можно передать объект URL или любой объект со свойством origin; в этом случае будет использовано значение свойства origin. Значение свойства origin должно быть корректно сериализованным источником ASCII.
Указание альтернативных служб
Формат параметра alt строго определён в RFC 7838: это строка ASCII со списком протоколов «альтернативных» служб, разделённых запятыми и связанных с определённым узлом и портом.
Например, значение 'h2="example.org:81"' указывает, что протокол HTTP/2 доступен на узле 'example.org' через порт TCP/IP 81. Узел и порт должны быть заключены в кавычки (").
Можно указать несколько альтернатив, например: 'h2="example.org:81", h2=":82"'.
Идентификатор протокола ('h2' в примерах) может быть любым допустимым идентификатором протокола ALPN.
Реализация Node.js не проверяет синтаксис этих значений: они передаются без изменений в том виде, в каком предоставлены пользователем или получены от узла-пира.
serverhttp2session.origin(...origins)
-
origins<string> | <URL> | <Object> Одна или несколько строк URL, переданных в виде отдельных аргументов.
Отправляет подключённому клиенту кадр ORIGIN (определённый в RFC 8336), чтобы объявить набор источников, для которых сервер может предоставлять авторитетные ответы.
Модули JavaScript
import { createSecureServer } from 'node:http2';
const options = getSecureOptionsSomehow();
const server = createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});
server.on('session', (session) => {
session.origin('https://example.com', 'https://example.org');
});CommonJS
const http2 = require('node:http2');
const options = getSecureOptionsSomehow();
const server = http2.createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});
server.on('session', (session) => {
session.origin('https://example.com', 'https://example.org');
});Если в качестве origin передана строка, она будет обработана как URL, и источник будет определён из неё. Например, источником HTTP URL 'https://example.org/foo/bar' является строка ASCII 'https://example.org'. Будет выброшена ошибка, если указанную строку невозможно обработать как URL или если невозможно определить допустимый источник.
В качестве origin можно передать объект URL или любой объект со свойством origin; в этом случае будет использовано значение свойства origin. Значение свойства origin должно быть корректно сериализованным источником ASCII.
Кроме того, при создании нового HTTP/2-сервера с помощью метода http2.createSecureServer() можно использовать параметр origins:
Модули JavaScript
import { createSecureServer } from 'node:http2';
const options = getSecureOptionsSomehow();
options.origins = ['https://example.com', 'https://example.org'];
const server = createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});CommonJS
const http2 = require('node:http2');
const options = getSecureOptionsSomehow();
options.origins = ['https://example.com', 'https://example.org'];
const server = http2.createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});Класс: ClientHttp2Session
- Наследует: <Http2Session>
Событие: 'altsvc'
Событие 'altsvc' генерируется всякий раз, когда клиент получает кадр ALTSVC. Событие передаётся со значением ALTSVC, источником и идентификатором потока. Если в кадре ALTSVC не указан origin, значение origin будет пустой строкой.
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('https://example.org');
client.on('altsvc', (alt, origin, streamId) => {
console.log(alt);
console.log(origin);
console.log(streamId);
});CommonJS
const http2 = require('node:http2');
const client = http2.connect('https://example.org');
client.on('altsvc', (alt, origin, streamId) => {
console.log(alt);
console.log(origin);
console.log(streamId);
});Событие: 'origin'
-
origins<string[]>
Событие 'origin' генерируется всякий раз, когда клиент получает кадр ORIGIN. Событие передаётся с массивом строк origin. Значение http2session.originSet обновляется с учётом полученных источников.
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('https://example.org');
client.on('origin', (origins) => {
for (let n = 0; n < origins.length; n++)
console.log(origins[n]);
});CommonJS
const http2 = require('node:http2');
const client = http2.connect('https://example.org');
client.on('origin', (origins) => {
for (let n = 0; n < origins.length; n++)
console.log(origins[n]);
});Событие 'origin' генерируется только при использовании защищённого TLS-соединения.
clienthttp2session.request(headers[, options])
-
headers<HTTP/2 Headers Object> | <HTTP/2 Raw Headers> -
options<Object>-
endStream<boolean>true, если изначально следует закрыть доступную для записи сторонуHttp2Stream, например при отправке запросаGET, который не должен содержать тело. -
exclusive<boolean> Еслиtrueиparentуказывают на родительский поток, созданный поток становится единственной непосредственной зависимостью родительского потока, а все остальные существующие зависимые потоки становятся зависимыми от нового потока. По умолчанию:false. -
parent<number> Задаёт числовой идентификатор потока, от которого зависит вновь созданный поток. -
waitForTrailers<boolean> Если заданоtrue,Http2Streamсгенерирует событие'wantTrailers'после отправки последнего кадраDATA. -
signal<AbortSignal> Объект AbortSignal, который можно использовать для прерывания выполняющегося запроса.
-
-
Возвращает: <ClientHttp2Stream>
Только для экземпляров HTTP/2-клиента Http2Session: метод http2session.request() создаёт и возвращает экземпляр Http2Stream, который можно использовать для отправки HTTP/2-запроса подключённому серверу.
При первом создании ClientHttp2Session сокет может быть ещё не подключён. Если в это время вызывается clienthttp2session.request(), фактический запрос будет отложен до готовности сокета. Если session будет закрыт до выполнения фактического запроса, будет выброшена ошибка ERR_HTTP2_GOAWAY_SESSION.
Этот метод доступен только в том случае, если http2session.type равно http2.constants.NGHTTP2_SESSION_CLIENT.
Модули JavaScript
import { connect, constants } from 'node:http2';
const clientSession = connect('https://localhost:1234');
const {
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
} = constants;
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
req.on('response', (headers) => {
console.log(headers[HTTP2_HEADER_STATUS]);
req.on('data', (chunk) => { /* .. */ });
req.on('end', () => { /* .. */ });
});CommonJS
const http2 = require('node:http2');
const clientSession = http2.connect('https://localhost:1234');
const {
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
} = http2.constants;
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
req.on('response', (headers) => {
console.log(headers[HTTP2_HEADER_STATUS]);
req.on('data', (chunk) => { /* .. */ });
req.on('end', () => { /* .. */ });
});Если задан параметр options.waitForTrailers, событие 'wantTrailers' генерируется сразу после добавления в очередь последнего фрагмента данных тела для отправки. Затем можно вызвать метод http2stream.sendTrailers(), чтобы отправить завершающие заголовки узлу-пиру.
Если задан options.waitForTrailers, Http2Stream не будет автоматически закрыт после передачи последнего кадра DATA. Пользовательский код должен вызвать либо http2stream.sendTrailers(), либо http2stream.close(), чтобы закрыть Http2Stream.
Если задан options.signal вместе с AbortSignal, а затем для соответствующего AbortController вызывается abort, запрос сгенерирует событие 'error' с ошибкой AbortError.
Псевдозаголовки :method и :path не определены в headers; по умолчанию им присваиваются следующие значения:
-
:method='GET' -
:path=/
Класс: Http2Stream
- Расширяет: <stream.Duplex>
Каждый экземпляр класса Http2Stream представляет собой двунаправленный поток обмена данными HTTP/2 через экземпляр Http2Session. За время существования у одного экземпляра Http2Session может быть до 231-1 экземпляров Http2Stream.
Пользовательский код не создает экземпляры Http2Stream напрямую. Вместо этого они создаются, управляются и предоставляются пользовательскому коду через экземпляр Http2Session. На сервере экземпляры Http2Stream создаются либо в ответ на входящий HTTP-запрос (и передаются пользовательскому коду через событие 'stream'), либо в ответ на вызов метода http2stream.pushStream(). На клиенте экземпляры Http2Stream создаются и возвращаются при вызове метода http2session.request() или в ответ на входящее событие 'push'.
Класс Http2Stream является базовым для классов ServerHttp2Stream и ClientHttp2Stream, каждый из которых используется соответственно только на стороне сервера или клиента.
Все экземпляры Http2Stream являются потоками Duplex. Сторона Writable экземпляра Duplex используется для отправки данных подключенному узлу, а сторона Readable — для получения данных, отправленных подключенным узлом.
Для экземпляра Http2Stream по умолчанию используется кодировка текста UTF-8. При отправке текста с помощью Http2Stream укажите кодировку символов в заголовке 'content-type'.
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
}); copy
Http2Stream Жизненный цикл
Создание
На стороне сервера экземпляры ServerHttp2Stream создаются в следующих случаях:
- Получен новый кадр HTTP/2
HEADERSс ранее не использовавшимся идентификатором потока; - Вызван метод
http2stream.pushStream().
На стороне клиента экземпляры ClientHttp2Stream создаются при вызове метода http2session.request().
На клиенте экземпляр Http2Stream, возвращенный методом http2session.request(), может быть не готов к использованию, если родительский Http2Session еще не установлен полностью. В таких случаях операции, вызванные для Http2Stream, будут буферизованы до появления события 'ready'. Пользовательскому коду редко, если вообще когда-либо, требуется непосредственно обрабатывать событие 'ready'. Готовность экземпляра Http2Stream можно определить, проверив значение http2stream.id. Если значение равно undefined, поток еще не готов к использованию.
Уничтожение
Все экземпляры Http2Stream уничтожаются в следующих случаях:
- Подключенный узел получает кадр
RST_STREAMдля потока, а ожидающие данные были прочитаны (только для клиентских потоков). - Вызывается метод
http2stream.close(), а ожидающие данные были прочитаны (только для клиентских потоков). - Вызывается метод
http2stream.destroy()илиhttp2session.destroy().
При уничтожении экземпляра Http2Stream будет предпринята попытка отправить подключенному узлу кадр RST_STREAM.
При уничтожении экземпляра Http2Stream будет создано событие 'close'. Поскольку Http2Stream является экземпляром stream.Duplex, событие 'end' также будет создано, если данные потока в данный момент передаются. Событие 'error' также может быть создано, если http2stream.destroy() был вызван с экземпляром Error в качестве первого аргумента.
После уничтожения Http2Stream свойство http2stream.destroyed будет равно true, а свойство http2stream.rstCode будет содержать код ошибки RST_STREAM. После уничтожения экземпляр Http2Stream становится непригодным для использования.
Событие: 'aborted'
Событие 'aborted' возникает, когда экземпляр Http2Stream аварийно прерывается в ходе обмена данными. Обработчик этого события не ожидает аргументов.
Событие 'aborted' возникает только в том случае, если записываемая сторона Http2Stream еще не завершена.
Событие: 'close'
Событие 'close' возникает при уничтожении Http2Stream. После возникновения этого события экземпляр Http2Stream становится непригодным для использования.
Код ошибки HTTP/2, использованный при закрытии потока, можно получить с помощью свойства http2stream.rstCode. Если код отличается от NGHTTP2_NO_ERROR (0), также будет создано событие 'error'.
Событие: 'frameError'
-
type<integer> Тип кадра. -
code<integer> Код ошибки. -
id<integer> Идентификатор потока (или0, если кадр не связан с потоком).
Событие 'frameError' возникает при ошибке во время попытки отправить кадр. При вызове обработчик получает целочисленный аргумент, определяющий тип кадра, и целочисленный аргумент, определяющий код ошибки. Экземпляр Http2Stream будет уничтожен сразу после возникновения события 'frameError'.
Событие: 'ready'
Событие 'ready' возникает, когда Http2Stream открыт, ему присвоен id и он готов к использованию. Обработчик этого события не ожидает аргументов.
Событие: 'timeout'
Событие 'timeout' возникает, если для этого Http2Stream не было активности в течение количества миллисекунд, заданного с помощью http2stream.setTimeout(). Обработчик этого события не ожидает аргументов.
Событие: 'trailers'
-
headers<HTTP/2 Headers Object> Объект с описанием заголовков -
flags<number> Связанные с заголовками числовые флаги
Событие 'trailers' возникает при получении блока заголовков, связанного с завершающими полями заголовков. В функцию обратного вызова передаются объект заголовков HTTP/2 и связанные с заголовками флаги.
Это событие может не возникнуть, если http2stream.end() вызван до получения завершающих заголовков, а входящие данные не считываются и для них не настроен обработчик.
stream.on('trailers', (headers, flags) => {
console.log(headers);
}); copy Событие: 'wantTrailers'
Событие 'wantTrailers' возникает, когда Http2Stream поставил в очередь последний кадр DATA для отправки в кадре, а Http2Stream готов отправить завершающие заголовки. Чтобы это событие возникло при отправке запроса или ответа, необходимо задать параметр waitForTrailers.
http2stream.aborted
- Тип: <boolean>
Равно true, если экземпляр Http2Stream был аварийно прерван. В этом случае событие 'aborted' уже было создано.
http2stream.bufferSize
- Тип: <number>
Это свойство показывает количество символов, которые в данный момент буферизованы для записи. Подробнее см. net.Socket.bufferSize.
http2stream.close(code[, callback])
-
code<number> Беззнаковое 32-разрядное целое число, задающее код ошибки. По умолчанию:http2.constants.NGHTTP2_NO_ERROR(0x00). -
callback<Function> Необязательная функция, зарегистрированная для прослушивания события'close'.
Закрывает экземпляр Http2Stream, отправляя кадр RST_STREAM подключенному узлу HTTP/2.
http2stream.destroyed
- Тип: <boolean>
Равно true, если экземпляр Http2Stream уничтожен и больше не пригоден для использования.
http2stream.endAfterHeaders
- Тип: <boolean>
Равно true, если во входящем кадре HEADERS запроса или ответа был установлен флаг END_STREAM. Это означает, что дополнительные данные не ожидаются и читаемая сторона Http2Stream будет закрыта.
http2stream.id
- Тип: <number> | <undefined>
Числовой идентификатор потока данного экземпляра Http2Stream. Равно undefined, если идентификатор потока еще не назначен.
http2stream.pending
- Тип: <boolean>
Равно true, если экземпляру Http2Stream еще не назначен числовой идентификатор потока.
http2stream.priority(options)
Пустой метод, оставленный только для обеспечения обратной совместимости.
http2stream.rstCode
- Тип: <number>
Значение равно коду ошибки RST_STREAM, указанному в кодах ошибок, если Http2Stream уничтожен после получения кадра RST_STREAM от подключенного узла, вызова http2stream.close() или http2stream.destroy(). Равно undefined, если Http2Stream еще не закрыт.
http2stream.sentHeaders
Объект, содержащий отправленные исходящие заголовки для этого Http2Stream.
http2stream.sentInfoHeaders
Массив объектов, содержащих отправленные исходящие информационные (дополнительные) заголовки для этого Http2Stream.
http2stream.sentTrailers
Объект, содержащий отправленные исходящие завершающие заголовки для этого HttpStream.
http2stream.session
- Тип: <Http2Session>
Ссылка на экземпляр Http2Session, которому принадлежит этот Http2Stream. После уничтожения экземпляра Http2Stream значение будет равно undefined.
http2stream.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function>
Модули JavaScript
import { connect, constants } from 'node:http2';
const client = connect('http://example.org:8000');
const { NGHTTP2_CANCEL } = constants;
const req = client.request({ ':path': '/' });
// Cancel the stream if there's no activity after 5 seconds
req.setTimeout(5000, () => req.close(NGHTTP2_CANCEL));CommonJS
const http2 = require('node:http2');
const client = http2.connect('http://example.org:8000');
const { NGHTTP2_CANCEL } = http2.constants;
const req = client.request({ ':path': '/' });
// Cancel the stream if there's no activity after 5 seconds
req.setTimeout(5000, () => req.close(NGHTTP2_CANCEL));
http2stream.state
Предоставляет различную информацию о текущем состоянии Http2Stream.
- Тип: <Object>
-
localWindowSize<number> Количество байтов, которое подключенный узел может отправить для этогоHttp2Stream, не получивWINDOW_UPDATE. -
state<number> Флаг, указывающий текущее состояниеHttp2Streamна низком уровне, определяемое с помощьюnghttp2. -
localClose<number>1, если этотHttp2Streamзакрыт локально. -
remoteClose<number>1, если этотHttp2Streamзакрыт удаленно. -
sumDependencyWeight<number> Устаревшее свойство, всегда равно0. -
weight<number> Устаревшее свойство, всегда равно16.
-
Текущее состояние этого Http2Stream.
http2stream.sendTrailers(headers)
-
headers<HTTP/2 Headers Object>
Отправляет подключенному узлу HTTP/2 завершающий кадр HEADERS. Этот метод приводит к немедленному закрытию Http2Stream, и его можно вызывать только после возникновения события 'wantTrailers'. При отправке запроса или ответа необходимо задать параметр options.waitForTrailers, чтобы Http2Stream оставался открытым после последнего кадра DATA и можно было отправить завершающие заголовки.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond(undefined, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ xyz: 'abc' });
});
stream.end('Hello World');
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond(undefined, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ xyz: 'abc' });
});
stream.end('Hello World');
});Спецификация HTTP/1 запрещает включать в завершающие заголовки псевдозаголовки HTTP/2 (например, ':method', ':path' и т. д.).
Класс: ClientHttp2Stream
- Расширяет <Http2Stream>
Класс ClientHttp2Stream является расширением Http2Stream и используется исключительно HTTP/2-клиентами. Экземпляры Http2Stream на клиенте предоставляют такие события, как 'response' и 'push', которые актуальны только на стороне клиента.
Событие: 'continue'
Возникает, когда сервер отправляет статус 100 Continue, обычно потому что запрос содержал Expect: 100-continue. Это указание клиенту отправить тело запроса.
Событие: 'headers'
-
headers<HTTP/2 Headers Object> -
flags<number> -
rawHeaders<HTTP/2 Raw Headers>
Событие 'headers' возникает, когда для потока получен дополнительный блок заголовков, например блок информационных заголовков 1xx. В функцию обратного вызова передаются объект заголовков HTTP/2, связанные с заголовками флаги и заголовки в исходном формате (см. необработанные заголовки HTTP/2).
stream.on('headers', (headers, flags) => {
console.log(headers);
}); copy Событие: 'push'
-
headers<HTTP/2 Headers Object> -
flags<number>
Событие 'push' возникает при получении заголовков ответа для потока Server Push. В функцию обратного вызова передаются объект заголовков HTTP/2 и связанные с заголовками флаги.
stream.on('push', (headers, flags) => {
console.log(headers);
}); copy Событие: 'response'
-
headers<HTTP/2 Headers Object> -
flags<number> -
rawHeaders<HTTP/2 Raw Headers>
Событие 'response' возникает, когда от подключенного сервера HTTP/2 для этого потока получен кадр ответа HEADERS. Обработчик вызывается с тремя аргументами: Object, содержащим полученный объект заголовков HTTP/2, связанные с заголовками флаги и заголовки в исходном формате (см. необработанные заголовки HTTP/2).
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('https://localhost');
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
console.log(headers[':status']);
});CommonJS
const http2 = require('node:http2');
const client = http2.connect('https://localhost');
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
console.log(headers[':status']);
});Класс: ServerHttp2Stream
- Наследует: <Http2Stream>
Класс ServerHttp2Stream является расширением Http2Stream, используемым исключительно на HTTP/2-серверах. Экземпляры Http2Stream на сервере предоставляют дополнительные методы, такие как http2stream.pushStream() и http2stream.respond(), которые имеют смысл только на сервере.
http2stream.additionalHeaders(headers)
-
headers<HTTP/2 Headers Object>
Отправляет подключенному узлу HTTP/2 дополнительный информационный кадр HEADERS.
http2stream.headersSent
- Тип: <boolean>
Значение true, если заголовки были отправлены, и false в противном случае (только для чтения).
http2stream.pushAllowed
- Тип: <boolean>
Свойство только для чтения, соответствующее флагу SETTINGS_ENABLE_PUSH из последнего кадра SETTINGS удаленного клиента. Будет иметь значение true, если удаленный узел принимает потоки push, и false в противном случае. Настройки одинаковы для каждого Http2Stream в одном и том же Http2Session.
http2stream.pushStream(headers[, options], callback)
-
headers<HTTP/2 Headers Object> -
options<Object>-
exclusive<boolean> Еслиtrueиparentуказывает на родительский поток, созданный поток становится единственной непосредственной зависимостью родительского потока, а все остальные существующие зависимые потоки становятся зависимыми от вновь созданного потока. По умолчанию:false. -
parent<number> Указывает числовой идентификатор потока, от которого зависит вновь созданный поток.
-
-
callback<Function> Callback, вызываемый после инициализации потока push.-
err<Error> -
pushStream<ServerHttp2Stream> Возвращенный объектpushStream. -
headers<HTTP/2 Headers Object> Объект заголовков, с которым был инициализированpushStream.
-
Инициализирует поток push. Callback вызывается с новым экземпляром Http2Stream, созданным для потока push и переданным вторым аргументом, либо с Error, переданным первым аргументом.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.pushStream({ ':path': '/' }, (err, pushStream, headers) => {
if (err) throw err;
pushStream.respond({ ':status': 200 });
pushStream.end('some pushed data');
});
stream.end('some data');
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.pushStream({ ':path': '/' }, (err, pushStream, headers) => {
if (err) throw err;
pushStream.respond({ ':status': 200 });
pushStream.end('some pushed data');
});
stream.end('some data');
});Установка веса потока push в кадре HEADERS запрещена. Передайте значение weight в http2stream.priority, установив параметр silent в true, чтобы включить балансировку пропускной способности на стороне сервера между параллельными потоками.
Вызов http2stream.pushStream() из потока push запрещен и приведет к ошибке.
http2stream.respond([headers[, options]])
-
headers<HTTP/2 Headers Object> | <HTTP/2 Raw Headers> -
options<Object>
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.end('some data');
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.end('some data');
});Инициирует ответ. Если задан параметр options.waitForTrailers, событие 'wantTrailers' будет вызвано сразу после добавления в очередь последнего фрагмента данных полезной нагрузки для отправки. Затем можно использовать метод http2stream.sendTrailers(), чтобы отправить узлу завершающие поля заголовков.
Если задано options.waitForTrailers, объект Http2Stream не будет автоматически закрыт после передачи последнего кадра DATA. Пользовательский код должен вызвать http2stream.sendTrailers() или http2stream.close(), чтобы закрыть Http2Stream.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 }, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.end('some data');
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 }, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.end('some data');
});
http2stream.respondWithFD(fd[, headers[, options]])
-
fd<number> | <FileHandle> Дескриптор файла для чтения. -
headers<HTTP/2 Headers Object> -
options<Object>-
statCheck<Function> -
waitForTrailers<boolean> Если заданоtrue, объектHttp2Streamвызовет событие'wantTrailers'после отправки последнего кадраDATA. -
offset<number> Позиция смещения, с которой начинается чтение. -
length<number> Объем данных, отправляемых из fd.
-
Инициирует ответ, данные которого считываются из указанного дескриптора файла. Проверка указанного дескриптора файла не выполняется. Если при попытке чтения данных с помощью дескриптора файла возникает ошибка, объект Http2Stream будет закрыт с помощью кадра RST_STREAM со стандартным кодом INTERNAL_ERROR.
При использовании интерфейс Duplex объекта Http2Stream будет закрыт автоматически.
Модули JavaScript
import { createServer } from 'node:http2';
import { openSync, fstatSync, closeSync } from 'node:fs';
const server = createServer();
server.on('stream', (stream) => {
const fd = openSync('/some/file', 'r');
const stat = fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers);
stream.on('close', () => closeSync(fd));
});CommonJS
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createServer();
server.on('stream', (stream) => {
const fd = fs.openSync('/some/file', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers);
stream.on('close', () => fs.closeSync(fd));
});Можно указать необязательную функцию options.statCheck, чтобы предоставить пользовательскому коду возможность задать дополнительные заголовки содержимого на основе сведений fs.Stat указанного fd. Если указана функция statCheck, метод http2stream.respondWithFD() выполнит вызов fs.fstat() для сбора сведений о предоставленном дескрипторе файла.
Параметры offset и length можно использовать, чтобы ограничить ответ указанным диапазоном. Это можно использовать, например, для поддержки запросов HTTP Range.
Дескриптор файла или FileHandle не закрывается при закрытии потока, поэтому его нужно закрыть вручную, когда он больше не нужен. Одновременное использование одного дескриптора файла в нескольких потоках не поддерживается и может привести к потере данных. Повторное использование дескриптора файла после завершения потока поддерживается.
Если задан параметр options.waitForTrailers, событие 'wantTrailers' будет вызвано сразу после добавления в очередь последнего фрагмента данных полезной нагрузки для отправки. Затем можно использовать метод http2stream.sendTrailers(), чтобы отправить узлу завершающие поля заголовков.
Если задано options.waitForTrailers, объект Http2Stream не будет автоматически закрыт после передачи последнего кадра DATA. Пользовательский код должен вызвать http2stream.sendTrailers() или http2stream.close(), чтобы закрыть Http2Stream.
Модули JavaScript
import { createServer } from 'node:http2';
import { openSync, fstatSync, closeSync } from 'node:fs';
const server = createServer();
server.on('stream', (stream) => {
const fd = openSync('/some/file', 'r');
const stat = fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.on('close', () => closeSync(fd));
});CommonJS
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createServer();
server.on('stream', (stream) => {
const fd = fs.openSync('/some/file', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.on('close', () => fs.closeSync(fd));
});
http2stream.respondWithFile(path[, headers[, options]])
-
path<string> | <Buffer> | <URL> -
headers<HTTP/2 Headers Object> -
options<Object>-
statCheck<Function> -
onError<Function> Функция callback, вызываемая при возникновении ошибки до отправки. -
waitForTrailers<boolean> Если заданоtrue, объектHttp2Streamвызовет событие'wantTrailers'после отправки последнего кадраDATA. -
offset<number> Позиция смещения, с которой начинается чтение. -
length<number> Объем данных, отправляемых из fd.
-
Отправляет обычный файл в качестве ответа. В path должен быть указан обычный файл, иначе для объекта Http2Stream будет вызвано событие 'error'.
При использовании интерфейс Duplex объекта Http2Stream будет закрыт автоматически.
Можно указать необязательную функцию options.statCheck, чтобы предоставить пользовательскому коду возможность задать дополнительные заголовки содержимого на основе сведений fs.Stat указанного файла:
Если при попытке чтения данных файла возникает ошибка, объект Http2Stream будет закрыт с помощью кадра RST_STREAM со стандартным кодом INTERNAL_ERROR. Если определен callback onError, он будет вызван. В противном случае поток будет уничтожен.
Пример использования пути к файлу:
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
headers['last-modified'] = stat.mtime.toUTCString();
}
function onError(err) {
// stream.respond() can throw if the stream has been destroyed by
// the other side.
try {
if (err.code === 'ENOENT') {
stream.respond({ ':status': 404 });
} else {
stream.respond({ ':status': 500 });
}
} catch (err) {
// Perform actual error handling.
console.error(err);
}
stream.end();
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck, onError });
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
headers['last-modified'] = stat.mtime.toUTCString();
}
function onError(err) {
// stream.respond() can throw if the stream has been destroyed by
// the other side.
try {
if (err.code === 'ENOENT') {
stream.respond({ ':status': 404 });
} else {
stream.respond({ ':status': 500 });
}
} catch (err) {
// Perform actual error handling.
console.error(err);
}
stream.end();
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck, onError });
});Функцию options.statCheck также можно использовать для отмены операции отправки, вернув false. Например, условный запрос может проверить результаты stat, чтобы определить, изменился ли файл, и вернуть соответствующий ответ 304:
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
// Check the stat here...
stream.respond({ ':status': 304 });
return false; // Cancel the send operation
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck });
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
// Check the stat here...
stream.respond({ ':status': 304 });
return false; // Cancel the send operation
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck });
});Поле заголовка content-length будет установлено автоматически.
Параметры offset и length можно использовать, чтобы ограничить ответ указанным диапазоном. Это можно использовать, например, для поддержки запросов HTTP Range.
Функцию options.onError также можно использовать для обработки всех ошибок, которые могут возникнуть до начала передачи файла. По умолчанию поток уничтожается.
Если задан параметр options.waitForTrailers, событие 'wantTrailers' будет вызвано сразу после добавления в очередь последнего фрагмента данных полезной нагрузки для отправки. Затем можно использовать метод http2stream.sendTrailers(), чтобы отправить узлу завершающие поля заголовков.
Если задано options.waitForTrailers, объект Http2Stream не будет автоматически закрыт после передачи последнего кадра DATA. Пользовательский код должен вызвать http2stream.sendTrailers() или http2stream.close(), чтобы закрыть Http2Stream.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
});Класс: Http2Server
- Наследует: <net.Server>
Экземпляры Http2Server создаются с помощью функции http2.createServer(). Класс Http2Server не экспортируется напрямую модулем node:http2.
Событие: 'checkContinue'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Если зарегистрирован обработчик 'request' или для параметра http2.createServer() указана функция callback, событие 'checkContinue' вызывается при каждом получении запроса с HTTP Expect: 100-continue. Если это событие не обрабатывается, сервер автоматически отвечает соответствующим кодом состояния 100 Continue.
Для обработки этого события необходимо вызвать response.writeContinue(), если клиенту следует продолжить отправку тела запроса, либо сформировать подходящий ответ HTTP (например, 400 Bad Request), если клиенту не следует продолжать отправку тела запроса.
Когда это событие вызвано и обработано, событие 'request' вызвано не будет.
Событие: 'connection'
-
socket<stream.Duplex>
Это событие вызывается при установлении нового потока TCP. Обычно socket является объектом типа net.Socket. Как правило, пользователям не требуется обращаться к этому событию.
Пользователи также могут явно вызвать это событие, чтобы добавить соединения в HTTP-сервер. В этом случае можно передать любой поток Duplex.
Событие: 'request'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Вызывается при каждом поступлении запроса. В рамках одного сеанса может быть несколько запросов. См. API совместимости.
Событие: 'session'
-
session<ServerHttp2Session>
Событие 'session' вызывается при создании нового Http2Session сервером Http2Server.
Событие: 'sessionError'
-
error<Error> -
session<ServerHttp2Session>
Событие 'sessionError' вызывается, когда объект Http2Session, связанный с Http2Server, вызывает событие 'error'.
Событие: 'stream'
-
stream<Http2Stream> Ссылка на поток -
headers<HTTP/2 Headers Object> Объект с описанием заголовков -
flags<number> Связанные числовые флаги -
rawHeaders<HTTP/2 Raw Headers> Массив с необработанными заголовками
Событие 'stream' вызывается, когда объект Http2Session, связанный с сервером, вызывает событие 'stream'.
См. также событие 'stream' объекта Http2Session.
Модули JavaScript
import { createServer, constants } from 'node:http2';
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = constants;
const server = createServer();
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});CommonJS
const http2 = require('node:http2');
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = http2.constants;
const server = http2.createServer();
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});Событие: 'timeout'
Событие 'timeout' вызывается, если на сервере отсутствует активность в течение количества миллисекунд, заданного с помощью http2server.setTimeout(). По умолчанию: 0 (без тайм-аута)
server.close([callback])
-
callback<Function>
Запрещает серверу устанавливать новые сеансы. Это не препятствует созданию новых потоков запросов из-за постоянного характера сеансов HTTP/2. Чтобы корректно завершить работу сервера, вызовите http2session.close() для всех активных сеансов.
Если передан параметр callback, он будет вызван только после закрытия всех активных сеансов, хотя сервер уже перестал принимать новые сеансы. Подробнее см. net.Server.close().
server[Symbol.asyncDispose]()
Вызывает server.close() и возвращает promise, который выполняется после закрытия сервера.
server.setTimeout([msecs][, callback])
-
msecs<number> По умолчанию: 0 (без тайм-аута) -
callback<Function> - Возвращает: <Http2Server>
Используется для установки значения тайм-аута запросов HTTP/2-сервера и задания функции callback, которая вызывается при отсутствии активности в Http2Server в течение msecs миллисекунд.
Переданный callback регистрируется как обработчик события 'timeout'.
Если callback не является функцией, будет выброшена новая ошибка ERR_INVALID_ARG_TYPE.
server.timeout
- Тип: <number> Тайм-аут в миллисекундах. По умолчанию: 0 (без тайм-аута)
Количество миллисекунд бездействия, по истечении которого сокет считается неактивным.
Значение 0 отключает тайм-аут для входящих соединений.
Логика тайм-аута сокета настраивается при подключении, поэтому изменение этого значения влияет только на новые соединения с сервером, но не на существующие.
server.updateSettings([settings])
-
settings<HTTP/2 Settings Object>
Используется для обновления настроек сервера переданными значениями.
Для недопустимых значений settings выбрасывает ERR_HTTP2_INVALID_SETTING_VALUE.
Для недопустимого аргумента settings выбрасывает ERR_INVALID_ARG_TYPE.
Класс: Http2SecureServer
- Расширяет: <tls.Server>
Экземпляры Http2SecureServer создаются с помощью функции http2.createSecureServer(). Класс Http2SecureServer не экспортируется напрямую модулем node:http2.
Событие: 'checkContinue'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Если зарегистрирован обработчик события 'request' или в качестве аргумента передана функция обратного вызова http2.createSecureServer(), событие 'checkContinue' генерируется при каждом получении запроса с HTTP Expect: 100-continue. Если это событие не прослушивается, сервер автоматически отправит соответствующий код состояния 100 Continue.
Для обработки этого события необходимо вызвать response.writeContinue(), если клиенту следует продолжить отправку тела запроса, или сформировать подходящий ответ HTTP (например, 400 Bad Request), если клиенту не следует продолжать отправку тела запроса.
Когда это событие генерируется и обрабатывается, событие 'request' генерироваться не будет.
Событие: 'connection'
-
socket<stream.Duplex>
Это событие генерируется при установлении нового потока TCP, до начала TLS-рукопожатия. Обычно socket является объектом типа net.Socket. Как правило, пользователям не требуется обращаться к этому событию.
Пользователи также могут явно генерировать это событие для передачи соединений HTTP-серверу. В этом случае можно передать любой поток Duplex.
Событие: 'request'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Генерируется при каждом запросе. В рамках одного сеанса может быть несколько запросов. См. API совместимости.
Событие: 'session'
-
session<ServerHttp2Session>
Событие 'session' генерируется при создании нового Http2Session сервером Http2SecureServer.
Событие: 'sessionError'
-
error<Error> -
session<ServerHttp2Session>
Событие 'sessionError' генерируется, когда объект Http2Session, связанный с Http2SecureServer, генерирует событие 'error'.
Событие: 'stream'
-
stream<Http2Stream> Ссылка на поток -
headers<HTTP/2 Headers Object> Объект, описывающий заголовки -
flags<number> Соответствующие числовые флаги -
rawHeaders<HTTP/2 Raw Headers> Массив, содержащий исходные заголовки
Событие 'stream' генерируется, когда объект Http2Session, связанный с сервером, генерирует событие 'stream'.
См. также событие 'stream' объекта Http2Session.
Модули JavaScript
import { createSecureServer, constants } from 'node:http2';
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = constants;
const options = getOptionsSomehow();
const server = createSecureServer(options);
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});CommonJS
const http2 = require('node:http2');
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = http2.constants;
const options = getOptionsSomehow();
const server = http2.createSecureServer(options);
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});Событие: 'timeout'
Событие 'timeout' генерируется, если на сервере нет активности в течение заданного количества миллисекунд, указанного с помощью http2secureServer.setTimeout(). По умолчанию: 2 минуты.
Событие: 'unknownProtocol'
-
socket<stream.Duplex>
Событие 'unknownProtocol' генерируется, когда подключающийся клиент не может согласовать допустимый протокол (то есть HTTP/2 или HTTP/1.1). Обработчик события получает сокет для обработки. Если обработчик этого события не зарегистрирован, соединение завершается. Тайм-аут можно задать с помощью параметра 'unknownProtocolTimeout', передаваемого в http2.createSecureServer().
В предыдущих версиях Node.js это событие генерировалось, если allowHTTP1 имеет значение false и во время TLS-рукопожатия клиент не отправлял расширение ALPN или отправлял расширение ALPN, не включающее HTTP/2 (h2). В более новых версиях Node.js это событие генерируется только в том случае, если allowHTTP1 имеет значение false и клиент не отправляет расширение ALPN. Если клиент отправляет расширение ALPN, не включающее HTTP/2 (или HTTP/1.1, если allowHTTP1 имеет значение true), TLS-рукопожатие завершится ошибкой, и защищённое соединение установлено не будет.
См. API совместимости.
server.close([callback])
-
callback<Function>
Запрещает серверу устанавливать новые сеансы. Это не препятствует созданию новых потоков запросов из-за постоянного характера сеансов HTTP/2. Чтобы корректно завершить работу сервера, вызовите http2session.close() для всех активных сеансов.
Если указан callback, он будет вызван только после закрытия всех активных сеансов, хотя сервер уже перестанет принимать новые сеансы. Дополнительные сведения см. в разделе tls.Server.close().
server.setTimeout([msecs][, callback])
-
msecs<number> По умолчанию:120000(2 минуты) -
callback<Function> - Возвращает: <Http2SecureServer>
Используется для задания значения тайм-аута запросов защищённого сервера http2 и установки функции обратного вызова, которая вызывается при отсутствии активности на Http2SecureServer в течение msecs миллисекунд.
Указанная функция обратного вызова регистрируется как обработчик события 'timeout'.
Если callback не является функцией, будет выброшена новая ошибка ERR_INVALID_ARG_TYPE.
server.timeout
- Тип: <number> Тайм-аут в миллисекундах. По умолчанию: 0 (без тайм-аута)
Количество миллисекунд бездействия, после которого считается, что время ожидания сокета истекло.
Значение 0 отключает тайм-аут для входящих соединений.
Логика тайм-аута сокета настраивается при установлении соединения, поэтому изменение этого значения повлияет только на новые соединения с сервером, но не на существующие.
server.updateSettings([settings])
-
settings<HTTP/2 Settings Object>
Используется для обновления настроек сервера указанными значениями.
Для недопустимых значений settings выбрасывается ERR_HTTP2_INVALID_SETTING_VALUE.
Для недопустимого аргумента settings выбрасывается ERR_INVALID_ARG_TYPE.
http2.createServer([options][, onRequestHandler])
-
options<Object>-
maxDeflateDynamicTableSize<number> Задаёт максимальный размер динамической таблицы для сжатия полей заголовков. По умолчанию:4Kib. -
maxSettings<number> Задаёт максимальное количество записей настроек в каждом кадреSETTINGS. Минимально допустимое значение —1. По умолчанию:32. -
maxSessionMemory<number> Задаёт максимальный объём памяти, который разрешено использовать объектуHttp2Session. Значение указывается в мегабайтах: например,1соответствует 1 мегабайту. Минимально допустимое значение —1. Это ограничение основано на кредитах: существующиеHttp2Streamмогут привести к превышению лимита, но создание новых экземпляровHttp2Streamбудет отклонено, пока лимит превышен. В текущий лимит засчитываются текущее количество сеансовHttp2Stream, текущий объём памяти, используемый таблицами сжатия заголовков, текущий объём данных в очереди на отправку, а также неподтверждённые кадрыPINGиSETTINGS. По умолчанию:10. -
maxHeaderListPairs<number> Задаёт максимальное количество записей заголовков. Это аналогичноserver.maxHeadersCountилиrequest.maxHeadersCountв модулеnode:http. Минимальное значение —4. По умолчанию:128. -
maxOutstandingPings<number> Задаёт максимальное количество ожидающих подтверждения ping-запросов. По умолчанию:10. -
maxSendHeaderBlockLength<number> Задаёт максимально допустимый размер сериализованного сжатого блока заголовков. Попытки отправить заголовки, превышающие этот лимит, приведут к генерации события'frameError', а поток будет закрыт и уничтожен. Хотя этот параметр задаёт максимально допустимый размер всего блока заголовков,nghttp2(внутренняя библиотека http2) ограничивает каждую распакованную пару ключ/значение значением65536. -
paddingStrategy<number> Стратегия определения объёма заполнения для кадровHEADERSиDATA. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Возможные значения:-
http2.constants.PADDING_STRATEGY_NONE: Заполнение не применяется. -
http2.constants.PADDING_STRATEGY_MAX: Применяется максимальный объём заполнения, определяемый внутренней реализацией. -
http2.constants.PADDING_STRATEGY_ALIGNED: Выполняются попытки добавить достаточное заполнение, чтобы общая длина кадра, включая 9-байтовый заголовок, была кратна 8. Для каждого кадра существует максимальное допустимое количество байтов заполнения, определяемое текущим состоянием управления потоком и настройками. Если это максимальное значение меньше количества, необходимого для выравнивания, используется максимальное значение, и общая длина кадра не обязательно будет кратна 8 байтам.
-
-
peerMaxConcurrentStreams<number> Задаёт максимальное количество параллельных потоков для удалённого узла, как если бы был получен кадрSETTINGS. Значение будет переопределено, если удалённый узел задаст собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
maxSessionInvalidFrames<integer> Задаёт максимальное количество недопустимых кадров, которое будет допускаться до закрытия сеанса. По умолчанию:1000. -
maxSessionRejectedStreams<integer> Задаёт максимальное количество отклонённых при создании потоков, которое будет допускаться до закрытия сеанса. Каждое отклонение связано с ошибкойNGHTTP2_ENHANCE_YOUR_CALM, которая должна сообщить удалённому узлу, что ему не следует открывать новые потоки. Поэтому дальнейшее открытие потоков считается признаком некорректного поведения удалённого узла. По умолчанию:100. -
settings<HTTP/2 Settings Object> Начальные настройки, отправляемые удалённому узлу при подключении. -
streamResetBurst<number> иstreamResetRate<number> Задают ограничение частоты для входящих сбросов потока (кадров RST_STREAM). Чтобы параметры вступили в силу, необходимо задать оба значения; по умолчанию они равны 1000 и 33 соответственно. -
remoteCustomSettings<Array> Массив целочисленных значений, определяющих типы настроек, включаемые в свойствоCustomSettingsобъекта remoteSettings. Дополнительные сведения о допустимых типах настроек см. в свойствеCustomSettingsобъектаHttp2Settings. -
Http1IncomingMessage<http.IncomingMessage> Указывает классIncomingMessageдля резервного перехода на HTTP/1. Полезно для расширения исходногоhttp.IncomingMessage. По умолчанию:http.IncomingMessage. -
Http1ServerResponse<http.ServerResponse> Указывает классServerResponseдля резервного перехода на HTTP/1. Полезно для расширения исходногоhttp.ServerResponse. По умолчанию:http.ServerResponse. -
Http2ServerRequest<http2.Http2ServerRequest> Указывает используемый классHttp2ServerRequest. Полезно для расширения исходногоHttp2ServerRequest. По умолчанию:Http2ServerRequest. -
Http2ServerResponse<http2.Http2ServerResponse> Указывает используемый классHttp2ServerResponse. Полезно для расширения исходногоHttp2ServerResponse. По умолчанию:Http2ServerResponse. -
unknownProtocolTimeout<number> Задаёт тайм-аут в миллисекундах, который сервер должен ожидать после генерации события'unknownProtocol'. Если к этому моменту сокет не будет уничтожен, сервер уничтожит его. По умолчанию:10000. -
strictFieldWhitespaceValidation<boolean> Если значениеtrue, включается строгая проверка начальных и конечных пробелов в именах и значениях полей заголовков HTTP/2 согласно RFC-9113. По умолчанию:true. -
...options<Object> Можно указать любой параметрnet.createServer().
-
-
onRequestHandler<Function> См. API совместимости - Возвращает: <Http2Server>
Возвращает экземпляр net.Server, который создаёт и управляет экземплярами Http2Session.
Поскольку неизвестно ни одного браузера, поддерживающего незашифрованный HTTP/2, при взаимодействии с клиентами-браузерами необходимо использовать http2.createSecureServer().
Модули JavaScript
import { createServer } from 'node:http2';
// Create an unencrypted HTTP/2 server.
// Since there are no browsers known that support
// unencrypted HTTP/2, the use of `createSecureServer()`
// is necessary when communicating with browser clients.
const server = createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);CommonJS
const http2 = require('node:http2');
// Create an unencrypted HTTP/2 server.
// Since there are no browsers known that support
// unencrypted HTTP/2, the use of `http2.createSecureServer()`
// is necessary when communicating with browser clients.
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);
http2.createSecureServer(options[, onRequestHandler])
-
options<Object>-
allowHTTP1<boolean> При значенииtrueвходящие подключения клиентов, не поддерживающих HTTP/2, будут переключены на HTTP/1.x. См. событие'unknownProtocol'. См. согласование ALPN. По умолчанию:false. -
maxDeflateDynamicTableSize<number> Задает максимальный размер динамической таблицы для сжатия полей заголовков. По умолчанию:4Kib. -
maxSettings<number> Задает максимальное количество записей настроек в каждом кадреSETTINGS. Минимально допустимое значение —1. По умолчанию:32. -
maxSessionMemory<number> Задает максимальный объем памяти, который разрешено использоватьHttp2Session. Значение указывается в мегабайтах, например1равно 1 мегабайту. Минимально допустимое значение —1. Это ограничение, основанное на кредитах: уже существующиеHttp2Streams могут привести к превышению лимита, но новые экземплярыHttp2Streamбудут отклонены, пока лимит превышен. В текущий лимит входят текущее количество сеансовHttp2Stream, объем памяти, используемый таблицами сжатия заголовков, данные, ожидающие отправки, а также неподтвержденные кадрыPINGиSETTINGS. По умолчанию:10. -
maxHeaderListPairs<number> Задает максимальное количество записей заголовков. Это аналогичноserver.maxHeadersCountилиrequest.maxHeadersCountв модулеnode:http. Минимальное значение —4. По умолчанию:128. -
maxOutstandingPings<number> Задает максимальное количество ожидающих подтверждения ping-запросов. По умолчанию:10. -
maxSendHeaderBlockLength<number> Задает максимально допустимый размер сериализованного сжатого блока заголовков. Попытка отправить заголовки, превышающие этот предел, приведет к генерации события'frameError'и закрытию и уничтожению потока. -
paddingStrategy<number> Стратегия определения размера заполнения для кадровHEADERSиDATA. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Значением может быть одно из следующих:-
http2.constants.PADDING_STRATEGY_NONE: заполнение не применяется. -
http2.constants.PADDING_STRATEGY_MAX: применяется максимально возможное заполнение, определяемое внутренней реализацией. -
http2.constants.PADDING_STRATEGY_ALIGNED: предпринимается попытка применить достаточное заполнение, чтобы общая длина кадра, включая 9-байтовый заголовок, была кратна 8. Для каждого кадра максимально допустимое число байтов заполнения определяется текущим состоянием управления потоком и настройками. Если это максимальное значение меньше рассчитанного количества, необходимого для выравнивания, используется максимальное значение, и общая длина кадра не обязательно будет кратна 8 байтам.
-
-
peerMaxConcurrentStreams<number> Задает максимальное количество параллельных потоков для удаленного узла так, как если бы был получен кадрSETTINGS. Значение будет переопределено, если удаленный узел задаст собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
maxSessionInvalidFrames<integer> Задает максимальное количество недопустимых кадров, которое будет допускаться до закрытия сеанса. По умолчанию:1000. -
maxSessionRejectedStreams<integer> Задает максимальное количество потоков, отклоненных при создании, которое будет допускаться до закрытия сеанса. Каждое отклонение сопровождается ошибкойNGHTTP2_ENHANCE_YOUR_CALM, которая должна сообщить узлу, что не следует открывать новые потоки; поэтому дальнейшие попытки их открыть расцениваются как признак некорректного поведения узла. По умолчанию:100. -
settings<HTTP/2 Settings Object> Начальные настройки, отправляемые удаленному узлу при подключении. -
streamResetBurst<number> иstreamResetRate<number> Задают ограничение частоты входящих сбросов потока (кадр RST_STREAM). Чтобы параметры действовали, необходимо задать оба; значения по умолчанию — 1000 и 33 соответственно. -
remoteCustomSettings<Array> Массив целочисленных значений определяет типы настроек, включаемые в свойствоcustomSettingsобъекта remoteSettings. Дополнительную информацию о допустимых типах настроек см. в свойствеcustomSettingsобъектаHttp2Settings. -
...options<Object> Можно указать любые параметрыtls.createServer(). Для серверов обычно требуются параметры идентификации (pfxилиkey/cert). -
origins<string[]> Массив строк origin, отправляемых в кадреORIGINсразу после создания нового серверногоHttp2Session. -
unknownProtocolTimeout<number> Задает время ожидания сервера в миллисекундах после генерации события'unknownProtocol'. Если к этому моменту сокет не был уничтожен, сервер уничтожит его. По умолчанию:10000. -
strictFieldWhitespaceValidation<boolean> Если задано значениеtrue, включается строгая проверка начальных и конечных пробелов в именах и значениях полей заголовков HTTP/2 в соответствии с RFC-9113. По умолчанию:true.
-
-
onRequestHandler<Function> См. API совместимости - Возвращает: <Http2SecureServer>
Возвращает экземпляр tls.Server, который создает экземпляры Http2Session и управляет ими.
Модули JavaScript
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const options = {
key: readFileSync('server-key.pem'),
cert: readFileSync('server-cert.pem'),
};
// Create a secure HTTP/2 server
const server = createSecureServer(options);
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);CommonJS
const http2 = require('node:http2');
const fs = require('node:fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
};
// Create a secure HTTP/2 server
const server = http2.createSecureServer(options);
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);
http2.connect(authority[, options][, listener])
-
authority<string> | <URL> Удаленный сервер HTTP/2, к которому выполняется подключение. Это должен быть минимальный корректный URL с префиксомhttp://илиhttps://, именем узла и IP-портом (если используется нестандартный порт). Данные пользователя (идентификатор и пароль), путь, строка запроса и фрагмент URL игнорируются. -
options<Object>-
maxDeflateDynamicTableSize<number> Задает максимальный размер динамической таблицы для сжатия полей заголовков. По умолчанию:4Kib. -
maxSettings<number> Задает максимальное количество записей настроек в каждом кадреSETTINGS. Минимально допустимое значение —1. По умолчанию:32. -
maxSessionMemory<number> Задает максимальный объем памяти, который разрешено использоватьHttp2Session. Значение указывается в мегабайтах, например1равно 1 мегабайту. Минимально допустимое значение —1. Это ограничение, основанное на кредитах: уже существующиеHttp2Streams могут привести к превышению лимита, но новые экземплярыHttp2Streamбудут отклонены, пока лимит превышен. В текущий лимит входят текущее количество сеансовHttp2Stream, объем памяти, используемый таблицами сжатия заголовков, данные, ожидающие отправки, а также неподтвержденные кадрыPINGиSETTINGS. По умолчанию:10. -
maxHeaderListPairs<number> Задает максимальное количество записей заголовков. Это аналогичноserver.maxHeadersCountилиrequest.maxHeadersCountв модулеnode:http. Минимальное значение —1. По умолчанию:128. -
maxOutstandingPings<number> Задает максимальное количество ожидающих подтверждения ping-запросов. По умолчанию:10. -
maxReservedRemoteStreams<number> Задает максимальное количество зарезервированных потоков push, которые клиент может одновременно принимать. Когда текущее количество зарезервированных потоков push превысит этот предел, новые потоки push, отправленные сервером, будут автоматически отклоняться. Минимально допустимое значение — 0. Максимально допустимое значение — 232-1. Отрицательное значение устанавливает для этого параметра максимально допустимое значение. По умолчанию:200. -
maxSendHeaderBlockLength<number> Задает максимально допустимый размер сериализованного сжатого блока заголовков. Попытка отправить заголовки, превышающие этот предел, приведет к генерации события'frameError'и закрытию и уничтожению потока. -
paddingStrategy<number> Стратегия определения размера заполнения для кадровHEADERSиDATA. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Значением может быть одно из следующих:-
http2.constants.PADDING_STRATEGY_NONE: заполнение не применяется. -
http2.constants.PADDING_STRATEGY_MAX: применяется максимально возможное заполнение, определяемое внутренней реализацией. -
http2.constants.PADDING_STRATEGY_ALIGNED: предпринимается попытка применить достаточное заполнение, чтобы общая длина кадра, включая 9-байтовый заголовок, была кратна 8. Для каждого кадра максимально допустимое число байтов заполнения определяется текущим состоянием управления потоком и настройками. Если это максимальное значение меньше рассчитанного количества, необходимого для выравнивания, используется максимальное значение, и общая длина кадра не обязательно будет кратна 8 байтам.
-
-
peerMaxConcurrentStreams<number> Задает максимальное количество параллельных потоков для удаленного узла так, как если бы был получен кадрSETTINGS. Значение будет переопределено, если удаленный узел задаст собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
protocol<string> Протокол для подключения, если он не указан вauthority. Значением может быть'http:'или'https:'. По умолчанию:'https:' -
settings<HTTP/2 Settings Object> Начальные настройки, отправляемые удаленному узлу при подключении. -
remoteCustomSettings<Array> Массив целочисленных значений определяет типы настроек, включаемые в свойствоCustomSettingsобъекта remoteSettings. Дополнительную информацию о допустимых типах настроек см. в свойствеCustomSettingsобъектаHttp2Settings. -
createConnection<Function> Необязательная функция обратного вызова, которая получает экземплярURL, переданный вconnect, и объектoptions, а затем возвращает любой потокDuplex, который будет использоваться как подключение для этого сеанса. -
...options<Object> Можно указать любые параметрыnet.connect()илиtls.connect(). -
unknownProtocolTimeout<number> Задает время ожидания сервера в миллисекундах после генерации события'unknownProtocol'. Если к этому моменту сокет не был уничтожен, сервер уничтожит его. По умолчанию:10000. -
strictFieldWhitespaceValidation<boolean> Если задано значениеtrue, включается строгая проверка начальных и конечных пробелов в именах и значениях полей заголовков HTTP/2 в соответствии с RFC-9113. По умолчанию:true.
-
-
listener<Function> Будет зарегистрирована как однократный обработчик события'connect'. - Возвращает: <ClientHttp2Session>
Возвращает экземпляр ClientHttp2Session.
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('https://localhost:1234');
/* Use the client */
client.close();CommonJS
const http2 = require('node:http2');
const client = http2.connect('https://localhost:1234');
/* Use the client */
client.close();
http2.constants
Коды ошибок для RST_STREAM и GOAWAY
| Значение | Название | Константа |
|---|---|---|
0x00 |
Нет ошибки | http2.constants.NGHTTP2_NO_ERROR |
0x01 |
Ошибка протокола | http2.constants.NGHTTP2_PROTOCOL_ERROR |
0x02 |
Внутренняя ошибка | http2.constants.NGHTTP2_INTERNAL_ERROR |
0x03 |
Ошибка управления потоком | http2.constants.NGHTTP2_FLOW_CONTROL_ERROR |
0x04 |
Истекло время ожидания настроек | http2.constants.NGHTTP2_SETTINGS_TIMEOUT |
0x05 |
Поток закрыт | http2.constants.NGHTTP2_STREAM_CLOSED |
0x06 |
Ошибка размера кадра | http2.constants.NGHTTP2_FRAME_SIZE_ERROR |
0x07 |
Поток отклонен | http2.constants.NGHTTP2_REFUSED_STREAM |
0x08 |
Отмена | http2.constants.NGHTTP2_CANCEL |
0x09 |
Ошибка сжатия | http2.constants.NGHTTP2_COMPRESSION_ERROR |
0x0a |
Ошибка подключения | http2.constants.NGHTTP2_CONNECT_ERROR |
0x0b |
Снизьте нагрузку | http2.constants.NGHTTP2_ENHANCE_YOUR_CALM |
0x0c |
Недостаточный уровень безопасности | http2.constants.NGHTTP2_INADEQUATE_SECURITY |
0x0d |
Требуется HTTP/1.1 | http2.constants.NGHTTP2_HTTP_1_1_REQUIRED |
Событие 'timeout' генерируется, если на сервере отсутствует активность в течение заданного количества миллисекунд, указанного с помощью http2server.setTimeout().
http2.getDefaultSettings()
- Возвращает: <HTTP/2 Settings Object>
Возвращает объект, содержащий настройки по умолчанию для экземпляра Http2Session. Этот метод каждый раз возвращает новый экземпляр объекта, поэтому возвращенные экземпляры можно безопасно изменять и использовать.
http2.getPackedSettings([settings])
-
settings<HTTP/2 Settings Object> - Возвращает: <Buffer>
Возвращает экземпляр Buffer, содержащий сериализованное представление заданных настроек HTTP/2 в соответствии со спецификацией HTTP/2. Предназначен для использования с полем заголовка HTTP2-Settings.
Модули JavaScript
import { getPackedSettings } from 'node:http2';
const packed = getPackedSettings({ enablePush: false });
console.log(packed.toString('base64'));
// Prints: AAIAAAAACommonJS
const http2 = require('node:http2');
const packed = http2.getPackedSettings({ enablePush: false });
console.log(packed.toString('base64'));
// Prints: AAIAAAAA
http2.getUnpackedSettings(buf)
-
buf<Buffer> | <TypedArray> Упакованные настройки. - Возвращает: <HTTP/2 Settings Object>
Возвращает объект настроек HTTP/2, содержащий десериализованные настройки из заданного Buffer, созданного с помощью http2.getPackedSettings().
http2.performServerHandshake(socket[, options])
-
socket<stream.Duplex> -
options<Object> Можно указать любые параметрыhttp2.createServer(). - Возвращает: <ServerHttp2Session>
Создает сеанс сервера HTTP/2 на основе существующего сокета.
http2.sensitiveHeaders
- Тип: <symbol>
Этот символ можно задать как свойство объекта заголовков HTTP/2 со значением-массивом, чтобы указать список заголовков, считающихся конфиденциальными. Подробнее см. в разделе Конфиденциальные заголовки.
Объект заголовков
Заголовки представлены в виде собственных свойств объектов JavaScript. Ключи свойств при сериализации преобразуются в нижний регистр. Значения свойств должны быть строками (в противном случае они будут приведены к строкам) или Array строк, чтобы отправить несколько значений для одного поля заголовка.
const headers = {
':status': '200',
'content-type': 'text-plain',
'ABC': ['has', 'more', 'than', 'one', 'value'],
};
stream.respond(headers); copy Объекты заголовков, передаваемые функциям обратного вызова, имеют прототип null. Это означает, что стандартные методы объектов JavaScript, такие как Object.prototype.toString() и Object.prototype.hasOwnProperty(), работать не будут.
Для входящих заголовков:
- Заголовок
:statusпреобразуется вnumber. - Дубликаты
:status,:method,:authority,:scheme,:path,:protocol,age,authorization,access-control-allow-credentials,access-control-max-age,access-control-request-method,content-encoding,content-language,content-length,content-location,content-md5,content-range,content-type,date,dnt,etag,expires,from,host,if-match,if-modified-since,if-none-match,if-range,if-unmodified-since,last-modified,location,max-forwards,proxy-authorization,range,referer,retry-after,tk,upgrade-insecure-requests,user-agentилиx-content-type-optionsотбрасываются. -
set-cookieвсегда является массивом. Дубликаты добавляются в массив. - Значения дублирующихся заголовков
cookieобъединяются с помощью строки '; '. - Значения всех остальных заголовков объединяются с помощью строки ', '.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});Исходные заголовки
В некоторых API, помимо формата объекта, заголовки также можно передавать или получать в виде необработанного плоского массива, сохраняющего порядок и повторяющиеся ключи для соответствия исходному формату передачи.
В этом формате ключи и значения находятся в одном списке. Это не список кортежей. Поэтому элементы со смещениями, кратными двум, являются ключами, а элементы со смещениями, не кратными двум, — соответствующими значениями. Дублирующиеся заголовки не объединяются, поэтому каждая пара «ключ — значение» представлена отдельно.
Это может быть полезно, например, для прокси-серверов, где существующие заголовки нужно пересылать точно в том виде, в каком они были получены, или для повышения производительности, если заголовки уже доступны в исходном формате.
const rawHeaders = [ ':status', '404', 'content-type', 'text/plain', ]; stream.respond(rawHeaders); copy
Конфиденциальные заголовки
Заголовки HTTP/2 можно пометить как конфиденциальные, то есть алгоритм сжатия заголовков HTTP/2 никогда не будет индексировать их. Это может быть полезно для значений заголовков с низкой энтропией, которые могут представлять ценность для злоумышленника, например Cookie или Authorization. Для этого добавьте имя заголовка в свойство [http2.sensitiveHeaders] в виде элемента массива:
const headers = {
':status': '200',
'content-type': 'text-plain',
'cookie': 'some-cookie',
'other-sensitive-header': 'very secret data',
[http2.sensitiveHeaders]: ['cookie', 'other-sensitive-header'],
};
stream.respond(headers); copy Для некоторых заголовков, например Authorization и коротких заголовков Cookie, этот флаг устанавливается автоматически.
Это свойство также устанавливается для полученных заголовков. Оно содержит имена всех заголовков, помеченных как конфиденциальные, включая заголовки, получившие эту отметку автоматически.
Для исходных заголовков это свойство по-прежнему должно задаваться для массива, например rawHeadersArray[http2.sensitiveHeaders] = ['cookie'], а не в виде отдельной пары ключ — значение внутри самого массива.
Объект настроек
API http2.getDefaultSettings(), http2.getPackedSettings(), http2.createServer(), http2.createSecureServer(), http2session.settings(), http2session.localSettings и http2session.remoteSettings либо возвращают, либо принимают в качестве входных данных объект, определяющий параметры конфигурации объекта Http2Session. Эти объекты являются обычными объектами JavaScript, содержащими следующие свойства.
-
headerTableSize<number> Указывает максимальное количество байтов, используемых для сжатия заголовков. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:4096. -
enablePush<boolean> Указывает,trueли потоки HTTP/2 Push на экземплярахHttp2Session. По умолчанию:true. -
initialWindowSize<number> Указывает начальный размер окна отправителя в байтах для управления потоком на уровне потока. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:65535. -
maxFrameSize<number> Указывает размер полезной нагрузки самого большого кадра в байтах. Минимальное допустимое значение — 16 384. Максимальное допустимое значение — 224-1. По умолчанию:16384. -
maxConcurrentStreams<number> Указывает максимальное количество параллельных потоков, разрешённых дляHttp2Session. Значение по умолчанию отсутствует, что означает, по крайней мере теоретически, что в любой момент времени вHttp2Sessionодновременно могут быть открыты 232-1 потоков. Минимальное значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:4294967295. -
maxHeaderListSize<number> Указывает максимальный размер (несжатый объём в октетах) списка заголовков, который будет принят. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:65535. -
maxHeaderSize<number> Псевдоним дляmaxHeaderListSize. -
enableConnectProtocol<boolean> Указывает,trueли протокол «Extended Connect», определённый в RFC 8441. Эта настройка имеет смысл только в том случае, если она отправлена сервером. После включения настройкиenableConnectProtocolдля данногоHttp2Sessionеё нельзя отключить. По умолчанию:false. -
customSettings<Object> Указывает дополнительные настройки, которые пока не реализованы в node и нижележащих библиотеках. Ключ объекта задаёт числовое значение типа настройки (согласно реестру «HTTP/2 SETTINGS», созданному в [RFC 7540]), а значения — фактическое числовое значение настроек. Тип настройки должен быть целым числом в диапазоне от 1 до 2^16-1. Желательно, чтобы это был тип настройки, который ещё не обрабатывается node, то есть в настоящее время он должен быть больше 6, хотя это не является ошибкой. Значения должны быть беззнаковыми целыми числами в диапазоне от 0 до 2^32-1. В настоящее время поддерживается не более 10 пользовательских настроек. Эта функция поддерживается только для отправки SETTINGS или получения значений настроек, указанных в параметрахremoteCustomSettingsобъекта сервера или клиента. Не смешивайте механизмcustomSettingsдля идентификатора настройки с интерфейсами для настроек, обрабатываемых встроенными средствами: в будущей версии node настройка может получить встроенную поддержку.
Все дополнительные свойства объекта настроек игнорируются.
Обработка ошибок
При использовании модуля node:http2 могут возникать ошибки нескольких типов:
Ошибки проверки возникают, если передан неверный аргумент, параметр или значение настройки. О них всегда сообщается синхронно с помощью throw.
Ошибки состояния возникают при попытке выполнить действие в неподходящий момент (например, отправить данные в поток после его закрытия). О них сообщается либо синхронно с помощью throw, либо через событие 'error' объекта Http2Stream, Http2Session или HTTP/2 Server — в зависимости от места и времени возникновения ошибки.
Внутренние ошибки возникают при неожиданном сбое сеанса HTTP/2. О них сообщается через событие 'error' объекта Http2Session или HTTP/2 Server.
Ошибки протокола возникают при нарушении различных ограничений протокола HTTP/2. О них сообщается либо синхронно с помощью throw, либо через событие 'error' объекта Http2Stream, Http2Session или HTTP/2 Server — в зависимости от места и времени возникновения ошибки.
Обработка недопустимых символов в именах и значениях заголовков
Реализация HTTP/2 обрабатывает недопустимые символы в именах и значениях HTTP-заголовков строже, чем реализация HTTP/1.
Имена полей заголовков не учитывают регистр и передаются по сети только в нижнем регистре. API Node.js позволяет задавать имена заголовков с символами разного регистра (например, Content-Type), но при передаче они будут преобразованы в нижний регистр (например, content-type).
Имена полей заголовков должны содержать только один или несколько следующих символов ASCII: a-z, A-Z, 0-9, !, #, $, %, &, ', *, +, -, ., ^, _, ` (обратная кавычка), | и ~.
Использование недопустимых символов в имени поля HTTP-заголовка приведёт к закрытию потока с сообщением об ошибке протокола.
Значения полей заголовков обрабатываются менее строго, однако в них не следует использовать символы новой строки или возврата каретки, а также следует ограничиваться символами US-ASCII согласно требованиям спецификации HTTP.
Потоки Push на стороне клиента
Чтобы получать потоки Push на стороне клиента, добавьте обработчик события 'stream' для объекта ClientHttp2Session:
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('http://localhost');
client.on('stream', (pushedStream, requestHeaders) => {
pushedStream.on('push', (responseHeaders) => {
// Process response headers
});
pushedStream.on('data', (chunk) => { /* handle pushed data */ });
});
const req = client.request({ ':path': '/' });CommonJS
const http2 = require('node:http2');
const client = http2.connect('http://localhost');
client.on('stream', (pushedStream, requestHeaders) => {
pushedStream.on('push', (responseHeaders) => {
// Process response headers
});
pushedStream.on('data', (chunk) => { /* handle pushed data */ });
});
const req = client.request({ ':path': '/' });Поддержка метода CONNECT
Метод CONNECT позволяет использовать сервер HTTP/2 в качестве прокси для TCP/IP-соединений.
Простой TCP-сервер:
Модули JavaScript
import { createServer } from 'node:net';
const server = createServer((socket) => {
let name = '';
socket.setEncoding('utf8');
socket.on('data', (chunk) => name += chunk);
socket.on('end', () => socket.end(`hello ${name}`));
});
server.listen(8000);CommonJS
const net = require('node:net');
const server = net.createServer((socket) => {
let name = '';
socket.setEncoding('utf8');
socket.on('data', (chunk) => name += chunk);
socket.on('end', () => socket.end(`hello ${name}`));
});
server.listen(8000);Прокси HTTP/2 CONNECT:
Модули JavaScript
import { createServer, constants } from 'node:http2';
const { NGHTTP2_REFUSED_STREAM, NGHTTP2_CONNECT_ERROR } = constants;
import { connect } from 'node:net';
const proxy = createServer();
proxy.on('stream', (stream, headers) => {
if (headers[':method'] !== 'CONNECT') {
// Only accept CONNECT requests
stream.close(NGHTTP2_REFUSED_STREAM);
return;
}
const auth = new URL(`tcp://${headers[':authority']}`);
// It's a very good idea to verify that hostname and port are
// things this proxy should be connecting to.
const socket = connect(auth.port, auth.hostname, () => {
stream.respond();
socket.pipe(stream);
stream.pipe(socket);
});
socket.on('error', (error) => {
stream.close(NGHTTP2_CONNECT_ERROR);
});
});
proxy.listen(8001);CommonJS
const http2 = require('node:http2');
const { NGHTTP2_REFUSED_STREAM } = http2.constants;
const net = require('node:net');
const proxy = http2.createServer();
proxy.on('stream', (stream, headers) => {
if (headers[':method'] !== 'CONNECT') {
// Only accept CONNECT requests
stream.close(NGHTTP2_REFUSED_STREAM);
return;
}
const auth = new URL(`tcp://${headers[':authority']}`);
// It's a very good idea to verify that hostname and port are
// things this proxy should be connecting to.
const socket = net.connect(auth.port, auth.hostname, () => {
stream.respond();
socket.pipe(stream);
stream.pipe(socket);
});
socket.on('error', (error) => {
stream.close(http2.constants.NGHTTP2_CONNECT_ERROR);
});
});
proxy.listen(8001);Клиент HTTP/2 CONNECT:
Модули JavaScript
import { connect, constants } from 'node:http2';
const client = connect('http://localhost:8001');
// Must not specify the ':path' and ':scheme' headers
// for CONNECT requests or an error will be thrown.
const req = client.request({
':method': 'CONNECT',
':authority': 'localhost:8000',
});
req.on('response', (headers) => {
console.log(headers[constants.HTTP2_HEADER_STATUS]);
});
let data = '';
req.setEncoding('utf8');
req.on('data', (chunk) => data += chunk);
req.on('end', () => {
console.log(`The server says: ${data}`);
client.close();
});
req.end('Jane');CommonJS
const http2 = require('node:http2');
const client = http2.connect('http://localhost:8001');
// Must not specify the ':path' and ':scheme' headers
// for CONNECT requests or an error will be thrown.
const req = client.request({
':method': 'CONNECT',
':authority': 'localhost:8000',
});
req.on('response', (headers) => {
console.log(headers[http2.constants.HTTP2_HEADER_STATUS]);
});
let data = '';
req.setEncoding('utf8');
req.on('data', (chunk) => data += chunk);
req.on('end', () => {
console.log(`The server says: ${data}`);
client.close();
});
req.end('Jane');Расширенный протокол CONNECT
RFC 8441 определяет расширение «Extended CONNECT Protocol» для HTTP/2, которое можно использовать для организации соединения с Http2Stream с помощью метода CONNECT в качестве туннеля для других протоколов связи (например, WebSockets).
Серверы HTTP/2 включают поддержку Extended CONNECT Protocol с помощью настройки enableConnectProtocol:
Модули JavaScript
import { createServer } from 'node:http2';
const settings = { enableConnectProtocol: true };
const server = createServer({ settings });CommonJS
const http2 = require('node:http2');
const settings = { enableConnectProtocol: true };
const server = http2.createServer({ settings });Получив от сервера кадр SETTINGS, указывающий на возможность использования расширенного CONNECT, клиент может отправлять запросы CONNECT с псевдозаголовком HTTP/2 ':protocol':
Модули JavaScript
import { connect } from 'node:http2';
const client = connect('http://localhost:8080');
client.on('remoteSettings', (settings) => {
if (settings.enableConnectProtocol) {
const req = client.request({ ':method': 'CONNECT', ':protocol': 'foo' });
// ...
}
});CommonJS
const http2 = require('node:http2');
const client = http2.connect('http://localhost:8080');
client.on('remoteSettings', (settings) => {
if (settings.enableConnectProtocol) {
const req = client.request({ ':method': 'CONNECT', ':protocol': 'foo' });
// ...
}
});API совместимости
API совместимости призвано обеспечить при работе с HTTP/2 впечатления разработчика, схожие с HTTP/1, чтобы можно было создавать приложения с поддержкой и HTTP/1, и HTTP/2. Это API предназначено только для публичного API HTTP/1. Однако многие модули используют внутренние методы или состояние, которые не поддерживаются, поскольку реализация полностью отличается.
В следующем примере создаётся сервер HTTP/2 с помощью API совместимости:
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
});CommonJS
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
});Чтобы создать сервер, поддерживающий HTTPS и HTTP/2, см. раздел Согласование ALPN. Переход с серверов HTTP/1 без TLS не поддерживается.
API совместимости HTTP/2 состоит из Http2ServerRequest и Http2ServerResponse. Они обеспечивают совместимость API с HTTP/1, но не скрывают различия между протоколами. Например, сообщение состояния для кодов HTTP игнорируется.
Согласование ALPN
Согласование ALPN позволяет поддерживать HTTPS и HTTP/2 через один и тот же сокет. Объекты req и res могут относиться как к HTTP/1, так и к HTTP/2, поэтому приложение должно ограничиваться публичным API HTTP/1 и определять, можно ли использовать более расширенные возможности HTTP/2.
В следующем примере создаётся сервер, поддерживающий оба протокола:
Модули JavaScript
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');
const server = createSecureServer(
{ cert, key, allowHTTP1: true },
onRequest,
).listen(8000);
function onRequest(req, res) {
// Detects if it is a HTTPS request or HTTP/2
const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ?
req.stream.session : req;
res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify({
alpnProtocol,
httpVersion: req.httpVersion,
}));
}CommonJS
const { createSecureServer } = require('node:http2');
const { readFileSync } = require('node:fs');
const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');
const server = createSecureServer(
{ cert, key, allowHTTP1: true },
onRequest,
).listen(4443);
function onRequest(req, res) {
// Detects if it is a HTTPS request or HTTP/2
const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ?
req.stream.session : req;
res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify({
alpnProtocol,
httpVersion: req.httpVersion,
}));
}Событие 'request' работает одинаково и для HTTPS, и для HTTP/2.
Класс: http2.Http2ServerRequest
- Наследует: <stream.Readable>
Объект Http2ServerRequest создаётся объектом http2.Server или http2.SecureServer и передаётся в качестве первого аргумента событию 'request'. Он может использоваться для доступа к состоянию, заголовкам и данным запроса.
Событие: 'aborted'
Событие 'aborted' возникает, когда экземпляр Http2ServerRequest неожиданно прерывается во время обмена данными.
Событие 'aborted' возникает только в том случае, если записывающая сторона Http2ServerRequest не была завершена.
Событие: 'close'
Указывает, что базовый объект Http2Stream был закрыт. Как и 'end', это событие возникает только один раз для каждого ответа.
request.aborted
- Тип: <boolean>
Свойство request.aborted принимает значение true, если запрос был прерван.
request.authority
- Тип: <string>
Псевдополе заголовка authority запроса. Поскольку HTTP/2 позволяет задавать в запросах либо :authority, либо host, это значение берётся из req.headers[':authority'], если оно присутствует. В противном случае оно берётся из req.headers['host'].
request.complete
- Тип: <boolean>
Свойство request.complete принимает значение true, если запрос был завершён, прерван или уничтожен.
request.connection
request.socket.- Тип: <net.Socket> | <tls.TLSSocket>
См. request.socket.
request.destroy([error])
-
error<Error>
Вызывает destroy() для объекта Http2Stream, получившего объект Http2ServerRequest. Если передан error, возникает событие 'error', а error передаётся в качестве аргумента всем обработчикам этого события.
Ничего не делает, если поток уже уничтожен.
request.headers
- Тип: <Object>
Объект заголовков запроса/ответа.
Пары «ключ-значение», содержащие имена и значения заголовков. Имена заголовков приведены к нижнему регистру.
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers); copy В HTTP/2 путь запроса, имя хоста, протокол и метод представлены специальными заголовками, начинающимися с символа : (например, ':path'). Эти специальные заголовки включаются в объект request.headers. Не изменяйте эти специальные заголовки случайным образом, иначе могут возникнуть ошибки. Например, удаление всех заголовков из запроса приведёт к ошибкам:
removeAllHeaders(request.headers); assert(request.url); // Fails because the :path header has been removed copy
request.httpVersion
- Тип: <string>
Для серверного запроса — версия HTTP, отправленная клиентом. Для ответа клиента — версия HTTP подключённого сервера. Возвращает '2.0'.
Кроме того, message.httpVersionMajor — это первое целое число, а message.httpVersionMinor — второе.
request.method
- Тип: <string>
Метод запроса в виде строки. Только для чтения. Примеры: 'GET', 'DELETE'.
request.rawHeaders
- Тип: <HTTP/2 Raw Headers>
Исходный список заголовков запроса/ответа в точности в том виде, в котором он был получен.
// Prints something like: // // [ 'user-agent', // 'this is invalid because there can be only one', // 'User-Agent', // 'curl/7.22.0', // 'Host', // '127.0.0.1:8000', // 'ACCEPT', // '*/*' ] console.log(request.rawHeaders); copy
request.rawTrailers
- Тип: <string[]>
Исходные ключи и значения завершающих заголовков запроса/ответа в точности в том виде, в котором они были получены. Заполняется только при событии 'end'.
request.scheme
- Тип: <string>
Псевдополе заголовка scheme запроса, указывающее на часть URL-адреса цели, содержащую схему.
request.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function> - Возвращает: <http2.Http2ServerRequest>
Устанавливает значение тайм-аута для объекта Http2Stream равным msecs. Если передан callback, он добавляется в качестве обработчика события 'timeout' объекта ответа.
Если обработчик события 'timeout' не добавлен для запроса, ответа или сервера, объекты Http2Stream уничтожаются по истечении тайм-аута. Если для событий 'timeout' запроса, ответа или сервера задан обработчик, обработку сокетов с истёкшим тайм-аутом необходимо выполнять явно.
request.socket
- Тип: <net.Socket> | <tls.TLSSocket>
Возвращает объект Proxy, который действует как net.Socket (или tls.TLSSocket), но применяет геттеры, сеттеры и методы с учётом логики HTTP/2.
Свойства destroyed, readable и writable извлекаются из объекта request.stream и задаются для него.
Методы destroy, emit, end, on и once вызываются для объекта request.stream.
Метод setTimeout вызывается для объекта request.stream.session.
Вызов pause, read, resume и write приводит к ошибке с кодом ERR_HTTP2_NO_SOCKET_MANIPULATION. Подробнее см. раздел Http2Session и сокеты.
Все остальные взаимодействия будут напрямую передаваться сокету. При использовании TLS вызовите request.socket.getPeerCertificate(), чтобы получить данные аутентификации клиента.
request.trailers
- Тип: <Object>
Объект завершающих заголовков запроса/ответа. Заполняется только при событии 'end'.
request.url
- Тип: <string>
Строка URL-адреса запроса. Она содержит только URL-адрес, указанный в фактическом HTTP-запросе. Если запрос имеет вид:
GET /status?name=ryan HTTP/1.1 Accept: text/plain copy
то request.url будет иметь значение:
'/status?name=ryan' copy
Чтобы разобрать URL-адрес на составляющие, можно использовать new URL():
$ node
> new URL('/status?name=ryan', 'http://example.com')
URL {
href: 'http://example.com/status?name=ryan',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/status',
search: '?name=ryan',
searchParams: URLSearchParams { 'name' => 'ryan' },
hash: ''
} copy Класс: http2.Http2ServerResponse
- Наследует: <Stream>
Этот объект создается внутренними средствами HTTP-сервера, а не пользователем. Он передается в качестве второго параметра события 'request'.
Событие: 'close'
Указывает, что базовый Http2Stream был завершен до вызова response.end() или до того, как его вызов стал возможен для сброса данных.
Событие: 'finish'
Возникает, когда ответ отправлен. Точнее, это событие возникает, когда последний фрагмент заголовков и тела ответа передан мультиплексору HTTP/2 для отправки по сети. Это не означает, что клиент уже что-либо получил.
После этого события объект ответа больше не будет генерировать никаких событий.
response.addTrailers(headers)
-
headers<Object>
Этот метод добавляет к ответу HTTP завершающие заголовки (заголовки в конце сообщения).
При попытке задать имя или значение поля заголовка, содержащие недопустимые символы, будет выброшена ошибка TypeError.
response.appendHeader(name, value)
-
name<string> -
value<string> | <string[]>
Добавляет одно значение заголовка в объект заголовков.
Если значение является массивом, это равносильно многократному вызову данного метода.
Если для заголовка ранее не было задано значений, это равносильно вызову response.setHeader().
При попытке задать имя или значение поля заголовка, содержащие недопустимые символы, будет выброшена ошибка TypeError.
// Returns headers including "set-cookie: a" and "set-cookie: b"
const server = http2.createServer((req, res) => {
res.setHeader('set-cookie', 'a');
res.appendHeader('set-cookie', 'b');
res.writeHead(200);
res.end('ok');
}); copy
response.connection
response.socket.- Тип: <net.Socket> | <tls.TLSSocket>
См. response.socket.
response.createPushResponse(headers, callback)
-
headers<HTTP/2 Headers Object> Объект с описанием заголовков -
callback<Function> Вызывается после завершенияhttp2stream.pushStream()либо в случае сбоя или отклонения попытки создать отправленный серверомHttp2Stream, либо если состояниеHttp2ServerRequestзакрыто до вызова методаhttp2stream.pushStream()-
err<Error> -
res<http2.Http2ServerResponse> Вновь созданный объектHttp2ServerResponse
-
Вызывает http2stream.pushStream() с указанными заголовками и в случае успеха оборачивает переданный Http2Stream во вновь созданный Http2ServerResponse в качестве параметра обратного вызова. Если Http2ServerRequest закрыт, обратный вызов вызывается с ошибкой ERR_HTTP2_INVALID_STREAM.
response.end([data[, encoding]][, callback])
-
data<string> | <Buffer> | <Uint8Array> -
encoding<string> -
callback<Function> - Возвращает: <this>
Этот метод сообщает серверу, что все заголовки и тело ответа отправлены и сервер должен считать это сообщение завершенным. Метод response.end() НЕОБХОДИМО вызвать для каждого ответа.
Если задан data, это равносильно вызову response.write(data, encoding), за которым следует response.end(callback).
Если задан callback, он будет вызван после завершения потока ответа.
response.finished
response.writableEnded.- Тип: <boolean>
Логическое значение, указывающее, завершен ли ответ. Изначально равно false. После выполнения response.end() значение станет true.
response.getHeader(name)
Возвращает заголовок, который уже помещен в очередь, но еще не отправлен клиенту. Регистр символов в имени не учитывается.
const contentType = response.getHeader('content-type'); copy
response.getHeaderNames()
- Возвращает: <string[]>
Возвращает массив с уникальными именами текущих исходящих заголовков. Все имена заголовков записаны в нижнем регистре.
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie'] copy
response.getHeaders()
- Возвращает: <Object>
Возвращает поверхностную копию текущих исходящих заголовков. Поскольку используется поверхностная копия, значения-массивы можно изменять без дополнительных вызовов различных методов модуля http, связанных с заголовками. Ключи возвращенного объекта — это имена заголовков, а значения — соответствующие значения заголовков. Все имена заголовков записаны в нижнем регистре.
Объект, возвращаемый методом response.getHeaders(), не наследуется по цепочке прототипов от JavaScript-объекта Object. Это означает, что типичные методы Object, такие как obj.toString(), obj.hasOwnProperty() и другие, не определены и не будут работать.
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headers = response.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } copy
response.hasHeader(name)
Возвращает true, если заголовок с именем name в данный момент задан среди исходящих заголовков. При сопоставлении имен заголовков регистр не учитывается.
const hasContentType = response.hasHeader('content-type'); copy
response.headersSent
- Тип: <boolean>
Значение true, если заголовки отправлены, и false в противном случае (только для чтения).
response.removeHeader(name)
-
name<string>
Удаляет заголовок, поставленный в очередь для неявной отправки.
response.removeHeader('Content-Encoding'); copy
response.sendDate
- Тип: <boolean>
Если значение равно true, заголовок Date будет автоматически сформирован и отправлен в ответе, если он еще не присутствует среди заголовков. По умолчанию равно true.
Отключать эту возможность следует только при тестировании; протокол HTTP требует наличия заголовка Date в ответах.
response.setHeader(name, value)
-
name<string> -
value<string> | <string[]>
Задает одно значение заголовка для неявных заголовков. Если такой заголовок уже есть среди заголовков, которые предстоит отправить, его значение будет заменено. Чтобы отправить несколько заголовков с одинаковым именем, используйте массив строк.
response.setHeader('Content-Type', 'text/html; charset=utf-8'); copy или
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); copy При попытке задать имя или значение поля заголовка, содержащие недопустимые символы, будет выброшена ошибка TypeError.
Заголовки, заданные с помощью response.setHeader(), объединяются с заголовками, переданными в response.writeHead(); приоритет имеют заголовки, переданные в response.writeHead().
// Returns content-type = text/plain
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
}); copy
response.setTimeout(msecs[, callback])
-
msecs<number> -
callback<Function> - Возвращает: <http2.Http2ServerResponse>
Устанавливает значение времени ожидания для Http2Stream равным msecs. Если указан обратный вызов, он добавляется в качестве обработчика события 'timeout' объекта ответа.
Если обработчик события 'timeout' не добавлен к запросу, ответу или серверу, при истечении времени ожидания Http2Stream уничтожаются. Если обработчик назначен событиям 'timeout' запроса, ответа или сервера, обработку сокетов, для которых истекло время ожидания, необходимо выполнять явно.
response.socket
- Тип: <net.Socket> | <tls.TLSSocket>
Возвращает объект Proxy, который действует как net.Socket (или tls.TLSSocket), но применяет геттеры, сеттеры и методы согласно логике HTTP/2.
Свойства destroyed, readable и writable считываются из response.stream и задаются для него.
Методы destroy, emit, end, on и once вызываются для response.stream.
Метод setTimeout вызывается для response.stream.session.
При обращении к pause, read, resume и write будет выброшена ошибка с кодом ERR_HTTP2_NO_SOCKET_MANIPULATION. Дополнительные сведения см. в разделе Http2Session и сокеты.
Все остальные операции будут напрямую перенаправлены сокету.
Модули JavaScript
import { createServer } from 'node:http2';
const server = createServer((req, res) => {
const ip = req.socket.remoteAddress;
const port = req.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);CommonJS
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
const ip = req.socket.remoteAddress;
const port = req.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);
response.statusCode
- Тип: <number>
При использовании неявных заголовков (если явно не вызывается response.writeHead()) это свойство определяет код состояния, который будет отправлен клиенту при сбросе заголовков.
response.statusCode = 404; copy
После отправки заголовка ответа клиенту это свойство содержит отправленный код состояния.
response.statusMessage
- Тип: <string>
Сообщение о состоянии не поддерживается HTTP/2 (RFC 7540 8.1.2.4). Возвращается пустая строка.
response.writableEnded
- Тип: <boolean>
Равно true после вызова response.end(). Это свойство не указывает, были ли данные сброшены; для этого используйте writable.writableFinished.
response.write(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> | <Uint8Array> -
encoding<string> -
callback<Function> - Возвращает: <boolean>
Если этот метод вызывается до вызова response.writeHead(), он переключается в режим неявных заголовков и сбрасывает неявные заголовки.
Отправляет фрагмент тела ответа. Этот метод можно вызывать несколько раз, чтобы передать последовательные части тела.
В модуле node:http тело ответа опускается, если запрос является запросом HEAD. Аналогично, ответы 204 и 304 не должны содержать тело сообщения.
chunk может быть строкой или буфером. Если chunk — строка, второй параметр указывает способ ее кодирования в поток байтов. По умолчанию encoding равно 'utf8'. callback будет вызван после сброса этого фрагмента данных.
Это необработанное тело HTTP, не связанное с кодировками составных тел более высокого уровня, которые могут использоваться.
При первом вызове response.write() клиенту отправляются буферизованные заголовки и первый фрагмент тела. При втором вызове response.write() Node.js предполагает, что данные будут передаваться потоком, и отправляет новые данные отдельно. Иными словами, ответ буферизуется до первого фрагмента тела.
Возвращает true, если все данные успешно сброшены в буфер ядра. Возвращает false, если все данные или их часть поставлены в очередь в памяти пользовательского пространства. Событие 'drain' возникает, когда буфер снова освобождается.
response.writeContinue()
Отправляет клиенту статус 100 Continue, указывая, что следует отправить тело запроса. См. событие 'checkContinue' у Http2Server и Http2SecureServer.
response.writeEarlyHints(hints)
-
hints<Object>
Отправляет клиенту статус 103 Early Hints с заголовком Link, указывающим, что пользовательский агент может предварительно загрузить связанные ресурсы или установить предварительное соединение с ними. hints — это объект, содержащий значения заголовков, которые будут отправлены в сообщении с ранними подсказками.
Пример
const earlyHintsLink = '</styles.css>; rel=preload; as=style';
response.writeEarlyHints({
'link': earlyHintsLink,
});
const earlyHintsLinks = [
'</styles.css>; rel=preload; as=style',
'</scripts.js>; rel=preload; as=script',
];
response.writeEarlyHints({
'link': earlyHintsLinks,
}); copy
response.writeHead(statusCode[, statusMessage][, headers])
-
statusCode<number> -
statusMessage<string> -
headers<HTTP/2 Headers Object> | <HTTP/2 Raw Headers> - Возвращает: <http2.Http2ServerResponse>
Отправляет заголовок ответа на запрос. Код состояния — это трехзначный код состояния HTTP, например 404. Последний аргумент, headers, содержит заголовки ответа.
Возвращает ссылку на Http2ServerResponse, чтобы можно было объединять вызовы в цепочку.
Для совместимости с HTTP/1 в качестве второго аргумента можно передать удобочитаемое statusMessage. Однако, поскольку statusMessage не имеет смысла в HTTP/2, этот аргумент не повлияет на результат, а процесс выдаст предупреждение.
const body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain; charset=utf-8',
}); copy Content-Length указывается в байтах, а не в символах. Чтобы определить количество байтов в заданной кодировке, можно использовать API Buffer.byteLength(). В исходящих сообщениях Node.js не проверяет, совпадает ли значение Content-Length с длиной передаваемого тела. Однако при получении сообщений Node.js автоматически отклоняет сообщения, если Content-Length не соответствует фактическому размеру полезной нагрузки.
Этот метод можно вызвать для сообщения не более одного раза до вызова response.end().
Если response.write() или response.end() вызываются до этого метода, неявные/изменяемые заголовки будут вычислены и эта функция будет вызвана.
Заголовки, заданные с помощью response.setHeader(), объединяются с заголовками, переданными в response.writeHead(); приоритет имеют заголовки, переданные в response.writeHead().
// Returns content-type = text/plain
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
}); copy При попытке задать имя или значение поля заголовка, содержащие недопустимые символы, будет выброшена ошибка TypeError.
Сбор показателей производительности HTTP/2
API Performance Observer можно использовать для сбора основных показателей производительности каждого экземпляра Http2Session и Http2Stream.
Модули JavaScript
import { PerformanceObserver } from 'node:perf_hooks';
const obs = new PerformanceObserver((items) => {
const entry = items.getEntries()[0];
console.log(entry.entryType); // prints 'http2'
if (entry.name === 'Http2Session') {
// Entry contains statistics about the Http2Session
} else if (entry.name === 'Http2Stream') {
// Entry contains statistics about the Http2Stream
}
});
obs.observe({ entryTypes: ['http2'] });CommonJS
const { PerformanceObserver } = require('node:perf_hooks');
const obs = new PerformanceObserver((items) => {
const entry = items.getEntries()[0];
console.log(entry.entryType); // prints 'http2'
if (entry.name === 'Http2Session') {
// Entry contains statistics about the Http2Session
} else if (entry.name === 'Http2Stream') {
// Entry contains statistics about the Http2Stream
}
});
obs.observe({ entryTypes: ['http2'] });Свойство entryType объекта PerformanceEntry будет равно 'http2'.
Свойство name объекта PerformanceEntry будет равно либо 'Http2Stream', либо 'Http2Session'.
Если name равно Http2Stream, PerformanceEntry будет содержать следующие дополнительные свойства:
-
bytesRead<number> Количество байтов кадраDATA, полученных для этогоHttp2Stream. -
bytesWritten<number> Количество байтов кадраDATA, отправленных для этогоHttp2Stream. -
id<number> Идентификатор связанногоHttp2Stream -
timeToFirstByte<number> Количество миллисекунд междуPerformanceEntrystartTimeи получением первого кадраDATA. -
timeToFirstByteSent<number> Количество миллисекунд междуPerformanceEntrystartTimeи отправкой первого кадраDATA. -
timeToFirstHeader<number> Количество миллисекунд междуPerformanceEntrystartTimeи получением первого заголовка.
Если name равно Http2Session, PerformanceEntry будет содержать следующие дополнительные свойства:
-
bytesRead<number> Количество байтов, полученных для этогоHttp2Session. -
bytesWritten<number> Количество байтов, отправленных для этогоHttp2Session. -
framesReceived<number> Количество кадров HTTP/2, полученныхHttp2Session. -
framesSent<number> Количество кадров HTTP/2, отправленныхHttp2Session. -
maxConcurrentStreams<number> Максимальное количество одновременно открытых потоков за время существованияHttp2Session. -
pingRTT<number> Количество миллисекунд между отправкой кадраPINGи получением подтверждения для него. Присутствует только в том случае, если кадрPINGбыл отправлен черезHttp2Session. -
streamAverageDuration<number> Средняя длительность (в миллисекундах) для всех экземпляровHttp2Stream. -
streamCount<number> Количество экземпляровHttp2Stream, обработанныхHttp2Session. -
type<string> Равно либо'server', либо'client'и указывает типHttp2Session.
Примечание о :authority и host
HTTP/2 требует, чтобы запросы содержали либо псевдозаголовок :authority, либо заголовок host. При создании запроса HTTP/2 напрямую предпочтительно использовать :authority, а при преобразовании из HTTP/1 (например, в прокси) — host.
API совместимости использует host, если :authority отсутствует. Дополнительную информацию см. в разделе request.authority. Однако, если вы не используете API совместимости (или напрямую используете req.headers), вам необходимо самостоятельно реализовать любое резервное поведение.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v24.x/docs/api/http2.html