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' поток будет закрыт и уничтожен. Если событие не связано с потоком, сразу после события 'frameError' будет остановлен Http2Session.
Событие: '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> 8-байтовая полезная нагрузка кадраPING
Событие '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. После вызова метода http2session.settings() значение будет true. Когда все отправленные кадры SETTINGS будут подтверждены, значение станет false.
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);
});Для клиентов http2 подходящим событием будет '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.
Также можно использовать параметр origins при создании нового сервера HTTP/2 с помощью метода http2.createSecureServer():
Модули 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> Задаёт числовой идентификатор потока, от которого зависит вновь созданный поток. -
weight<number> Задаёт относительную зависимость потока по отношению к другим потокам с тем же значениемparent. Значение — число от1до256включительно. Эта возможность объявлена устаревшей в RFC 9113, и её поддержка будет удалена в будущих версиях Node.js. -
waitForTrailers<boolean> Если задано значениеtrue, объектHttp2Streamсгенерирует событие'wantTrailers'после отправки последнего кадраDATA. -
signal<AbortSignal> AbortSignal, который можно использовать для прерывания выполняющегося запроса.
-
-
Возвращает: <ClientHttp2Stream>
Только для экземпляров HTTP/2 Client 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 пользовательский код должен вызвать http2stream.sendTrailers() или http2stream.close().
Если задано значение options.signal вместе с AbortSignal, а затем вызван abort для соответствующего AbortController, запрос сгенерирует событие '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 создаются в следующих случаях:
- Получен новый кадр
HEADERSHTTP/2 с ранее не использовавшимся идентификатором потока; - Вызван метод
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'.
Событие: 'error'
-
error<Error>
Событие 'error' генерируется при возникновении ошибки во время обработки Http2Stream.
Событие: 'frameError'
-
type<integer> Тип кадра. -
code<integer> Код ошибки. -
id<integer> Идентификатор потока (или0, если кадр не связан с потоком).
Событие 'frameError' генерируется при возникновении ошибки во время попытки отправить кадр. При вызове функция-обработчик получает целочисленный аргумент, определяющий тип кадра, и целочисленный аргумент, определяющий код ошибки. Экземпляр Http2Stream будет немедленно уничтожен после генерации события 'frameError'.
Событие: 'ready'
Событие 'ready' генерируется, когда Http2Stream открыт, ему присвоен id и его можно использовать. Обработчик события не ожидает аргументов.
Событие: 'timeout'
Событие 'timeout' генерируется, если в течение количества миллисекунд, заданного с помощью http2stream.setTimeout(), для этого Http2Stream не поступало никаких данных. Обработчик события не ожидает аргументов.
Событие: '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)
-
options<Object>-
exclusive<boolean> Еслиtrueиparentуказывают на родительский поток, этот поток становится единственной непосредственной зависимостью родительского потока, а все остальные существующие зависимости становятся зависимыми от этого потока. По умолчанию:false. -
parent<number> Указывает числовой идентификатор потока, от которого зависит этот поток. -
weight<number> Указывает относительную зависимость потока по отношению к другим потокам с тем жеparent. Значение — число от1до256включительно. -
silent<boolean> Если значение равноtrue, изменяет приоритет локально, не отправляя подключенному узлу кадрPRIORITY.
-
Обновляет приоритет этого экземпляра Http2Stream.
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> Суммарный вес всех экземпляровHttp2Stream, зависящих от этогоHttp2Stream, как указано в кадрахPRIORITY. Этот параметр был признан устаревшим в RFC 9113, и в будущих версиях Node.js его поддержка будет удалена. -
weight<number> Вес приоритета этогоHttp2Stream. Этот параметр был признан устаревшим в RFC 9113, и в будущих версиях Node.js его поддержка будет удалена.
-
Текущее состояние этого Http2Stream.
http2stream.sendTrailers(headers)
-
headers<HTTP/2 Headers Object>
Отправляет завершающий кадр HEADERS подключенному узлу HTTP/2. Этот метод немедленно закрывает 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> Функция обратного вызова, вызываемая после инициализации потока push.-
err<Error> -
pushStream<ServerHttp2Stream> Возвращённый объектpushStream. -
headers<HTTP/2 Headers Object> Объект заголовков, с которым был инициированpushStream.
-
Инициирует поток push. Функция обратного вызова вызывается с новым экземпляром 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> Функция обратного вызова, вызываемая в случае ошибки до отправки. -
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. Если задана функция обратного вызова 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() указана функция обратного вызова, событие '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' вызывается, когда Http2Server создаёт новый Http2Session.
Событие: '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() и возвращает промис, который выполняется после закрытия сервера.
server.setTimeout([msecs][, callback])
-
msecs<number> По умолчанию: 0 (без ограничения по времени) -
callback<Function> - Возвращает: <Http2Server>
Используется для установки значения времени ожидания запросов к серверу http2 и задания функции обратного вызова, которая вызывается при отсутствии активности на Http2Server в течение 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.
Класс: 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. Это ограничение с учётом уже выделенных ресурсов: существующиеHttp2Streamмогут привести к превышению этого лимита, однако новые экземпляры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. Это ограничение с учётом уже выделенных ресурсов: существующиеHttp2Streamмогут привести к превышению этого лимита, однако новые экземпляры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ли включить «расширенный протокол Connect», определенный в RFC 8441. Эта настройка имеет смысл, только если ее отправляет сервер. После включения настройкиenableConnectProtocolдля данногоHttp2Sessionее нельзя отключить. По умолчанию:false. -
customSettings<Object> Задает дополнительные настройки, которые пока не реализованы в Node.js и базовых библиотеках. Ключ объекта определяет числовое значение типа настройки (как указано в реестре «HTTP/2 SETTINGS», созданном согласно [RFC 7540]), а значение — фактическое числовое значение настройки. Тип настройки должен быть целым числом в диапазоне от 1 до 2^16-1. Это не должен быть тип настройки, уже обрабатываемый Node.js; то есть в настоящее время он должен быть больше 6, хотя это не считается ошибкой. Значения должны быть беззнаковыми целыми числами в диапазоне от 0 до 2^32-1. В настоящее время поддерживается не более 10 пользовательских настроек. Это поддерживается только при отправке SETTINGS или при получении значений настроек, указанных в параметрахremoteCustomSettingsобъекта сервера или клиента. Не смешивайте механизмcustomSettingsдля идентификатора настройки с интерфейсами для настроек, обрабатываемых встроенными средствами, на случай, если эта настройка получит встроенную поддержку в будущей версии Node.js.
Все дополнительные свойства объекта настроек игнорируются.
Обработка ошибок
При использовании модуля 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-заголовка приведет к закрытию потока с сообщением об ошибке протокола.
Значения полей заголовков обрабатываются менее строго, однако, согласно требованиям спецификации HTTP, не должны содержать символы новой строки или возврата каретки и должны состоять только из символов US-ASCII.
Потоки 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 определяет расширение HTTP/2 «Extended CONNECT Protocol», которое можно использовать для установления 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.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, не связанное с кодированием тела в формате multipart более высокого уровня, которое может использоваться.
При первом вызове 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и получением подтверждения для него. Присутствует только в том случае, если дляHttp2Sessionбыл отправлен кадрPING. -
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-v22.x/docs/api/http2.html