HTTP/2
Модуль http2 предоставляет реализацию протокола HTTP/2. К нему можно обратиться, используя:
const http2 = require('http2');
Основной API
Основной API предоставляет низкоуровневый интерфейс, специально разработанный для поддержки функций протокола HTTP/2. Он не предназначен для совместимости с существующим API модуля HTTP/1. Однако API совместимости — да.
API основного модуля http2 намного симметричнее между клиентом и сервером, чем API http. Например, большинство событий, таких как error, connect и stream, могут быть вызваны либо кодом на стороне клиента, либо кодом на стороне сервера.
Пример серверной стороны
Следующий пример демонстрирует простой сервер HTTP/2, использующий основной API. Поскольку нет известных браузеров, поддерживающих незашифрованный HTTP/2, использование http2.createSecureServer() необходимо при общении с клиентами браузера.
const http2 = require('http2');
const fs = require('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',
':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
Пример клиентской стороны
Следующий пример иллюстрирует HTTP/2-клиента:
const http2 = require('http2');
const fs = require('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.type можно использовать для определения режима работы экземпляра Http2Session. На стороне сервера код пользователя редко должен работать с объектом 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<целое число> Тип кадра. -
code<целое число> Код ошибки. -
id<целое число> Идентификатор потока (или0, если кадр не связан с потоком).
Событие 'frameError' генерируется при возникновении ошибки при попытке отправки кадра в сессии. Если кадр, который не удалось отправить, связан с конкретным Http2Stream, будет предпринята попытка сгенерировать событие 'frameError' для Http2Stream.
Если событие 'frameError' связано с потоком, поток будет закрыт и уничтожен сразу после события 'frameError'. Если событие не связано с потоком, Http2Session будет закрыт сразу после события 'frameError'.
Событие: 'goaway'
-
errorCode<число> Код ошибки HTTP/2, указанный в кадреGOAWAY. -
lastStreamID<число> Идентификатор последнего потока, успешно обработанного удалённым узлом (или0, если идентификатор не указан). -
opaqueData<Буфер> Если в кадреGOAWAYбыли включены дополнительные непрозрачные данные, будет передан экземплярBuffer, содержащий эти данные.
Событие 'goaway' генерируется при получении кадра GOAWAY.
Экземпляр Http2Session будет автоматически закрыт при генерации события 'goaway'.
Событие: 'localSettings'
-
settings<Объект настроек HTTP/2> Копия кадраSETTINGS, полученного.
Событие 'localSettings' генерируется при получении кадра подтверждения SETTINGS.
Примечание: При использовании http2session.settings() для отправки новых настроек, изменённые настройки не вступят в силу, пока не будет сгенерировано событие 'localSettings'.
session.settings({ enablePush: false });
session.on('localSettings', (settings) => {
/** use the new settings **/
});
Событие: 'ping'
-
payload<Буфер> 8-байтовая полезная нагрузка кадраPING
Событие 'ping' генерируется всякий раз, когда от соединённого узла поступает кадр PING.
Событие: 'remoteSettings'
-
settings<Объект настроек HTTP/2> Копия кадраSETTINGS, полученного.
Событие 'remoteSettings' генерируется при получении нового кадра SETTINGS от подключенного узла.
session.on('remoteSettings', (settings) => {
/** use the new settings **/
});
Событие: 'stream'
-
stream<Http2Stream> Ссылка на поток -
headers<Объект заголовков HTTP/2> Объект, описывающий заголовки -
flags<число> Соответствующие числовые флаги -
rawHeaders<Массив> Массив, содержащий исходные имена заголовков, за которыми следуют соответствующие значения.
Событие 'stream' генерируется при создании нового Http2Stream.
const http2 = require('http2');
session.on('stream', (stream, headers, flags) => {
const method = headers[':method'];
const path = headers[':path'];
// ...
stream.respond({
':status': 200,
'content-type': 'text/plain'
});
stream.write('hello ');
stream.end('world');
});
На стороне сервера код пользователя обычно не подписывается на это событие напрямую, а вместо этого регистрирует обработчик для события 'stream' , генерируемого экземплярами net.Server или tls.Server , возвращаемыми http2.createServer() и http2.createSecureServer(), соответственно, как в примере ниже:
const http2 = require('http2');
// Create an unencrypted HTTP/2 server
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html',
':status': 200
});
stream.end('<h1>Hello World</h1>');
});
server.listen(80);
Событие: 'timeout'
После использования метода http2session.setTimeout() для установки тайм-аута для этого Http2Session, событие 'timeout' генерируется, если в течение заданного количества миллисекунд нет активности в Http2Session.
session.setTimeout(2000);
session.on('timeout', () => { /** .. **/ });
http2session.alpnProtocol
- Значение: <строка> | <undefined>
Значение будет undefined, если Http2Session еще не подключен к сокету, h2c, если Http2Session не подключен к TLSSocket, или вернёт значение свойства alpnProtocol подключенного TLSSocket.
http2session.close([callback])
-
callback<Функция>
Вежливо закрывает Http2Session, позволяя любым существующим потокам завершиться самостоятельно и предотвращая создание новых экземпляров Http2Stream. После закрытия, http2session.destroy() может быть вызван, если нет открытых экземпляров Http2Stream.
Если указана, функция callback регистрируется как обработчик события 'close'.
http2session.closed
- Значение: <логическое значение>
Будет true, если этот экземпляр Http2Session был закрыт, в противном случае false.
http2session.connecting
Будет true, если этот экземпляр Http2Session всё ещё подключается, будет установлено в значение false перед вызовом события connect и/или вызовом обратного вызова http2.connect.
http2session.destroy([error,][code])
-
error<Ошибка> ОбъектError, еслиHttp2Sessionуничтожается из-за ошибки. -
code<число> Код ошибки HTTP/2 для отправки в последнем кадреGOAWAY. Если не указан иerrorне определён, по умолчаниюINTERNAL_ERROR, иначе по умолчаниюNO_ERROR. - Возвращает: <неопределено>
Немедленно завершает Http2Session и связанные с ним net.Socket или tls.TLSSocket.
После уничтожения Http2Session вызовет событие 'close'. Если error не определён, событие 'error' будет вызвано сразу после события 'close'.
Если есть какие-либо оставшиеся открытые Http2Streams связанные с Http2Session, они также будут уничтожены.
http2session.destroyed
- Значение: <логическое значение>
Будет true, если этот экземпляр Http2Session был уничтожен и больше не должен использоваться, в противном случае false.
http2session.encrypted
- Значение: <логическое значение> | <неопределено>
Значение undefined, если сокет сессии Http2Session ещё не подключен, true, если Http2Session подключен с TLSSocket, и false, если Http2Session подключен к любому другому типу сокета или потоку.
http2session.goaway([code, [lastStreamID, [opaqueData]]])
-
code<число> Код ошибки HTTP/2 -
lastStreamID<число> Численный идентификатор последнего обработанногоHttp2Stream -
opaqueData<Буфер> | <Тип массива> | <DataView> ЭкземплярTypedArrayилиDataView, содержащий дополнительные данные, которые будут переданы в кадреGOAWAY.
Передает кадр GOAWAY подключённому узлу без закрытия Http2Session.
http2session.localSettings
- Значение: <Объект настроек HTTP/2>
Объект без прототипа, описывающий текущие локальные настройки этого Http2Session. Локальные настройки локальны для этого экземпляра Http2Session.
http2session.originSet
- Значение: <массив строк> | <неопределено>
Если Http2Session подключен к TLSSocket, свойство originSet вернёт массив источников, для которых Http2Session может считаться авторитетным.
Свойство originSet доступно только при использовании защищенного TLS-соединения.
http2session.pendingSettingsAck
- Значение: <логическое значение>
Указывает, ждёт ли в настоящее время Http2Session подтверждения для отправленного кадра SETTINGS. Будет true после вызова метода http2session.settings(). Будет false после того, как все отправленные кадры SETTINGS будут подтверждены.
http2session.ping([payload, ]callback)
-
payload<Буфер> | <Тип массива> | <DataView> Необязательная полезная нагрузка для пинга. -
callback<Функция> - Возвращает: <логическое значение>
Отправляет кадр PING подключённому узлу HTTP/2. Должен быть предоставлен обратный вызов callback . Метод вернёт true, если PING был отправлен, false в противном случае.
Максимальное количество ожидающих (неподтверждённых) пингов определяется параметром конфигурации maxOutstandingPings. По умолчанию максимальное значение равно 10.
Если предоставлен, payload должен быть Buffer, TypedArray, или DataView, содержащим 8 байтов данных, которые будут переданы с PING и возвращены с подтверждением пинга.
Обратный вызов будет вызван с тремя аргументами: аргументом ошибки, который будет null, если PING был успешно подтверждён, аргументом duration, который сообщает количество миллисекунд, прошедших с момента отправки пинга и получения подтверждения, и аргументом 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()}`);
}
});
Если аргумент payload не указан, по умолчанию будет использоваться 64-битный отметка времени (маленький порядок байт), обозначающая начало продолжительности PING.
http2session.ref()
Вызывает ref() для базового сокета net.Socket этого экземпляра Http2Session.
http2session.remoteSettings
- Значение: <Объект настроек HTTP/2>
Объект без прототипа, описывающий текущие удалённые настройки этого Http2Session. Удалённые настройки задаются подключённым узлом HTTP/2.
http2session.setTimeout(msecs, callback)
-
msecs<число> -
callback<Функция> - Возвращает: <неопределено>
Используется для установки функции обратного вызова, которая вызывается, когда в течение msecs миллисекунд нет активности на Http2Session. Указанная 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)
-
settings<Объект настроек HTTP/2>
Обновляет текущие локальные настройки для этого 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
serverhttp2session.altsvc(alt, originOrStream)
-
alt<string> Описание конфигурации альтернативной службы, как определено в RFC 7838. -
originOrStream<number> | <string> | <URL> | <Object> Строка URL, указывающая на источник (или объект со свойствомorigin), или числовой идентификатор активногоHttp2Stream, как указано свойствомhttp2stream.id.
Отправляет ALTSVC кадр (как определено в RFC 7838) подключённому клиенту.
const http2 = require('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 и строка origin должны содержать только байты ASCII и строго интерпретируются как последовательность байтов ASCII. Специальное значение 'clear' может быть передано для сброса ранее заданной альтернативной службы для данного домена.
Когда строка передаётся в качестве аргумента originOrStream, она будет обработана как URL, и источник будет выведен. Например, источник HTTP URL 'https://example.org/foo/bar' является строкой ASCII 'https://example.org'. Будет выброшена ошибка, если переданная строка не может быть обработана как URL или если не может быть выведен корректный источник.
Объект URL, или любой объект со свойством origin, может быть передан в качестве originOrStream, в этом случае будет использовано значение свойства 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) подключённому клиенту для объявления набора источников, для которых сервер может предоставлять авторитетные ответы.
const http2 = require('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 или если не может быть выведен корректный источник.
Объект URL, или любой объект со свойством origin, может быть передан как origin, в этом случае будет использовано значение свойства origin . Значение свойства origin должно быть правильно сериализованным ASCII источником.
В качестве альтернативы, опция origins может быть использована при создании нового HTTP/2 сервера, используя метод http2.createSecureServer():
const http2 = require('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
Событие: 'altsvc'
Событие 'altsvc' срабатывает всякий раз, когда клиент получает ALTSVC кадр. Событие срабатывает со значениями ALTSVC, origin и идентификатором потока. Если в ALTSVC кадре не указан origin, origin будет пустой строкой.
const http2 = require('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<строковый массив>
Событие 'origin' генерируется всякий раз, когда ORIGIN кадр получен клиентом. Событие генерируется с массивом origin строк. http2session.originSet будет обновлён, чтобы включить полученные источники.
const http2 = require('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 заголовков> -
options<Объект>-
endStream<логическое значение>trueеслиHttp2Streamсторона writable должна быть закрыта изначально, например, при отправкеGETзапроса, который не должен ожидать тела полезной нагрузки. -
exclusive<логическое значение> Когдаtrueиparentидентифицируют родительский поток, созданный поток становится единственной прямой зависимостью родителя, а все другие существующие зависимости становятся зависимыми от вновь созданного потока. По умолчанию:false. -
parent<число> Указывает числовой идентификатор потока, от которого зависит вновь созданный поток. -
weight<число> Указывает относительную зависимость потока по отношению к другим потокам с тем жеparent. Значение является числом от1до256(включительно). -
waitForTrailers<логическое значение> Еслиtrue,Http2Streamбудет генерировать событие'wantTrailers'после отправки последнегоDATAкадра.
-
-
Возвращает: <ClientHttp2Stream>
Только для экземпляров HTTP/2 Клиента Http2Session метод http2session.request() создаёт и возвращает экземпляр Http2Stream, который можно использовать для отправки запроса HTTP/2 на подключённый сервер.
Этот метод доступен только если http2session.type равно http2.constants.NGHTTP2_SESSION_CLIENT.
const http2 = require('http2');
const clientSession = http2.connect('https://localhost:1234');
const {
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS
} = http2.constants;
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
req.on('response', (headers) => {
console.log(headers[HTTP2_HEADER_STATUS]);
req.on('data', (chunk) => { /** .. **/ });
req.on('end', () => { /** .. **/ });
});
Когда параметр options.waitForTrailers установлен, событие 'wantTrailers' генерируется сразу после помещения последнего фрагмента данных полезной нагрузки в очередь для отправки. Затем можно вызвать метод http2stream.sendTrailers() для отправки завершающих заголовков партнёру.
Когда options.waitForTrailers установлено, Http2Stream не будет автоматически закрываться при передаче последнего DATA кадра. Код пользователя должен вызвать либо http2stream.sendTrailers(), либо http2stream.close(), чтобы закрыть Http2Stream.
Псевдозаголовки :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
Создание
На стороне сервера экземпляры ServerHttp2Stream создаются либо когда:
- Получен новый HTTP/2
HEADERSкадр с ранее неиспользованным идентификатором потока; - Вызван метод
http2stream.pushStream().
На стороне клиента экземпляры ClientHttp2Stream создаются при вызове метода http2session.request().
Примечание: На клиенте экземпляр Http2Stream , возвращённый методом http2session.request(), может не быть сразу готов к использованию, если родительский Http2Session ещё не полностью установлен. В таких случаях операции, вызываемые на Http2Stream , будут буферизированы до тех пор, пока не будет генерировано событие 'ready' . Коду пользователя редко, если вообще, нужно обрабатывать событие 'ready' напрямую. Готовность экземпляра Http2Stream можно определить, проверив значение http2stream.id . Если значение undefined, поток ещё не готов к использованию.
Уничтожение
Все экземпляры Http2Stream уничтожаются либо когда:
- Подключённый партнёр получает
RST_STREAMкадр для потока. - Вызван метод
http2stream.close(). - Вызваны методы
http2stream.destroy()илиhttp2session.destroy().
При уничтожении экземпляра Http2Stream будет предпринята попытка отправить RST_STREAM кадр подключённому партнёру.
При уничтожении экземпляра Http2Stream будет генерироваться событие 'close' . Поскольку Http2Stream является экземпляром stream.Duplex, событие 'end' также будет генерироваться, если данные потока текущий момент передаются. Событие 'error' также может быть сгенерировано, если был вызван http2stream.destroy() с Error в качестве первого аргумента.
После уничтожения Http2Stream, свойство http2stream.destroyed будет true, а свойство http2stream.rstCode будет указывать код ошибки RST_STREAM. Экземпляр Http2Stream больше не может быть использован после уничтожения.
Событие: 'aborted'
Событие 'aborted' генерируется всякий раз, когда экземпляр Http2Stream прерывается во время связи.
Примечание: Событие 'aborted' будет генерироваться только если сторона Http2Stream не завершена.
Событие: 'close'
Событие 'close' генерируется, когда Http2Stream уничтожается. После генерации этого события экземпляр Http2Stream больше не может использоваться.
Обработчик событий получает единственный аргумент, представляющий код HTTP/2 ошибки, указанный при закрытии потока. Если код имеет значение отличное от NGHTTP2_NO_ERROR (0), также будет генерироваться событие 'error'.
Событие: 'error'
-
error<Ошибка>
Событие 'error' генерируется, когда возникает ошибка при обработке Http2Stream.
Событие: 'frameError'
Событие 'frameError' генерируется, когда возникает ошибка при попытке отправки кадра. При вызове обработчик получит целочисленный аргумент, идентифицирующий тип кадра, и целочисленный аргумент, идентифицирующий код ошибки. Экземпляр Http2Stream будет уничтожен сразу после генерации события 'frameError'.
Событие: 'timeout'
Событие 'timeout' генерируется после того, как для этого 'Http2Stream' не поступает активности в течение заданного числа миллисекунд, используя http2stream.setTimeout().
Событие: 'trailers'
Событие 'trailers' генерируется, когда получен блок заголовков, связанных с полями заголовков завершения. Обработчик событий получает объект HTTP/2 заголовков и флаги, связанные с заголовками.
Обратите внимание, что это событие может не быть сгенерировано, если http2stream.end() вызван до получения трейлеров и входящие данные не читаются или не прослушиваются.
stream.on('trailers', (headers, flags) => {
console.log(headers);
});
Событие: 'wantTrailers'
Событие 'wantTrailers' генерируется, когда Http2Stream поместил в очередь последний DATA кадр для отправки по кадру, и Http2Stream готов отправить заключительные заголовки. При инициализации запроса или ответа необходимо установить опцию waitForTrailers для генерации этого события.
http2stream.aborted
- Значение: <boolean>
Устанавливается в true, если экземпляр Http2Stream был прерван аномально. При установлении этого значения, будет сгенерировано событие 'aborted'.
http2stream.close(code[, callback])
- code <number> Беззнаковое 32-битное целое число, определяющее код ошибки. По умолчанию:
http2.constants.NGHTTP2_NO_ERROR(0x00). -
callback<Function> Необязательная функция, зарегистрированная для прослушивания события'close'. - Возвращает: <undefined>
Закрывает экземпляр Http2Stream, отправив кадр RST_STREAM подключённому узлу HTTP/2.
http2stream.closed
- Значение: <boolean>
Устанавливается в true, если экземпляр Http2Stream был закрыт.
http2stream.destroyed
- Значение: <boolean>
Устанавливается в true, если экземпляр Http2Stream был уничтожен и больше не может быть использован.
http2stream.endAfterHeaders
Устанавливает true, если флаг END_STREAM был установлен в полученном кадре HEADERS запроса или ответа, что указывает на то, что дополнительные данные не должны приниматься и сторона чтения Http2Stream будет закрыта.
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подключённому узлу.
-
- Возвращает: <undefined>
Обновляет приоритет для данного экземпляра Http2Stream.
http2stream.rstCode
- Значение: <number>
Устанавливается в RST_STREAM код ошибки, сообщаемый, когда Http2Stream уничтожается после получения кадра RST_STREAM от подключённого узла, вызова http2stream.close(), или http2stream.destroy(). Будет undefined, если Http2Stream не был закрыт.
http2stream.sentHeaders
- Значение: <HTTP/2 Headers Object>
Объект, содержащий исходящие заголовки, отправленные для данного Http2Stream.
http2stream.sentInfoHeaders
- Значение: <HTTP/2 Headers Object[]>
Массив объектов, содержащих исходящие информационные (дополнительные) заголовки, отправленные для данного Http2Stream.
http2stream.sentTrailers
- Значение: <HTTP/2 Headers Object>
Объект, содержащий исходящие трейлеры, отправленные для данного HttpStream.
http2stream.session
- Значение: <Http2Session>
Ссылка на экземпляр Http2Session, который владеет этим Http2Stream. Значение будет undefined после уничтожения экземпляра Http2Stream.
http2stream.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function> - Возвращает: <undefined>
const http2 = require('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>trueесли этотHttp2Streamбыл закрыт локально. -
remoteClose<number>trueесли этотHttp2Streamбыл закрыт удалённо. -
sumDependencyWeight<number> Суммарный вес всех экземпляровHttp2Stream, которые зависят от этогоHttp2Stream, как указано в кадрахPRIORITY. -
weight<number> Вес приоритета данногоHttp2Stream.
-
Текущее состояние Http2Stream.
http2stream.sendTrailers(headers)
-
headers<HTTP/2 Headers Object>
Отправляет кадр HEADERS с заключительными заголовками подключённому узлу HTTP/2. Этот метод закроет Http2Stream немедленно и должен вызываться только после генерации события 'wantTrailers'. При отправке запроса или ответа необходимо установить опцию options.waitForTrailers для поддержания Http2Stream открытым после отправки последнего кадра DATA, чтобы можно было отправить трейлеры.
const http2 = require('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', и т.д.).
Class: ClientHttp2Stream
- Extends <Http2Stream>
Класс ClientHttp2Stream — это расширение Http2Stream, используемое исключительно в клиентах HTTP/2. Экземпляры Http2Stream клиента предоставляют события, такие как 'response' и 'push', которые актуальны только для клиента.
Event: 'continue'
Выводится, когда сервер отправляет статус 100 Continue, обычно потому, что запрос содержал Expect: 100-continue. Это инструкция, что клиент должен отправить тело запроса.
Событие: 'headers'
Событие 'headers' генерируется, когда для потока принимается дополнительный блок заголовков, например, при получении блока 1xx информационных заголовков. Обработчик события получает в качестве аргумента объект Объект заголовков HTTP/2 и флаги, связанные с заголовками.
stream.on('headers', (headers, flags) => {
console.log(headers);
});
Событие: 'push'
Событие 'push' генерируется, когда принимаются заголовки ответа для потока Server Push. Обработчик события получает в качестве аргумента объект Объект заголовков HTTP/2 и флаги, связанные с заголовками.
stream.on('push', (headers, flags) => {
console.log(headers);
});
Событие: 'response'
Событие 'response' генерируется, когда для этого потока получена рамка ответа HEADERS от подключенного HTTP/2 сервера. Обработчик вызывается с двумя аргументами: объектом, содержащим полученный объект Объект заголовков HTTP/2, и флагами, связанными с заголовками.
Например:
const http2 = require('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 рамку подключенному HTTP/2 узлу.
http2stream.headersSent
- Значение: <логическое значение>
Логическое значение (только для чтения). True, если заголовки были отправлены, иначе false.
http2stream.pushAllowed
- Значение: <логическое значение>
Только для чтения свойство, сопоставленное с флагом SETTINGS_ENABLE_PUSH последней SETTINGS рамки удаленного клиента. Будет true, если удалённый узел принимает потоки push, false в противном случае. Параметры одинаковы для каждого Http2Stream в одном и том же Http2Session.
http2stream.pushStream(headers[, options], callback)
-
headers<Объект заголовков HTTP/2> -
options<Объект>-
exclusive<логическое значение> Когдаtrueиparentидентифицируют родительский поток, созданный поток становится единственной непосредственной зависимостью родителя, а все другие существующие зависимости становятся зависимыми от вновь созданного потока. По умолчанию:false. -
parent<число> Указывает числовой идентификатор потока, от которого зависит вновь созданный поток.
-
-
callback<Функция> Обработчик, вызываемый после инициирования потока push.-
err<Ошибка> -
pushStream<ServerHttp2Stream> Возвращаемый объект pushStream. -
headers<Объект заголовков HTTP/2> Объект заголовков, с которым был инициирован pushStream.
-
- Возвращает: <undefined>
Инициализирует поток push. Обработчик вызывается с новым экземпляром Http2Stream созданного для потока push в качестве второго аргумента или с Error в качестве первого аргумента.
const http2 = require('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> -
options<Объект>-
endStream<логическое значение> Установлено вtrueдля указания, что ответ не будет содержать данных полезной нагрузки. -
waitForTrailers<логическое значение> Еслиtrue,Http2Streamбудет излучать событие'wantTrailers'после отправки последнейDATAрамки.
-
const http2 = require('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.
const http2 = require('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<число> Дескриптор читаемого файла. -
headers<Объект заголовков HTTP/2> -
options<Объект>-
statCheck<Функция> -
waitForTrailers<логическое значение> Еслиtrue,Http2Streamбудет излучать событие'wantTrailers'после отправки последнейDATAрамки. -
offset<число> Смещение начала чтения. -
length<число> Количество данных для отправки из fd.
-
Инициализирует ответ, данные которого считываются из данного дескриптора файла. Никакая валидация не выполняется для данного дескриптора файла. Если при попытке чтения данных с помощью дескриптора файла возникнет ошибка, Http2Stream будет закрыт с помощью RST_STREAM рамки с стандартным кодом INTERNAL_ERROR.
При использовании интерфейс Duplex объекта Http2Stream будет закрыт автоматически.
const http2 = require('http2');
const fs = require('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'
};
stream.respondWithFD(fd, headers);
stream.on('close', () => fs.closeSync(fd));
});
Необязательная функция options.statCheck может быть указана, чтобы дать коду пользователя возможность установить дополнительные заголовки контента, основанные на fs.Stat деталях данного fd. Если функция statCheck предоставлена, метод http2stream.respondWithFD() выполнит вызов fs.fstat() для сбора данных о предоставленном дескрипторе файла.
Параметры offset и length могут использоваться для ограничения ответа определённым подмножеством диапазонов. Это может быть использовано, например, для поддержки запросов HTTP Range.
Дескриптор файла не закрывается при закрытии потока, поэтому его необходимо закрыть вручную, когда он больше не нужен. Обратите внимание, что одновременное использование одного и того же дескриптора файла для нескольких потоков не поддерживается и может привести к потере данных. Повторное использование дескриптора файла после завершения потока поддерживается.
Если опция options.waitForTrailers установлена, событие 'wantTrailers' будет излучаться сразу после помещения в очередь последней части данных полезной нагрузки для отправки. Метод http2stream.sendTrailers() может затем использоваться для отправки конечных полей заголовков в узел.
Если options.waitForTrailers установлено, Http2Stream не будет автоматически закрываться при передаче последней DATA рамки. Код пользователя должен вызвать либо http2stream.sendTrailers(), либо http2stream.close(), чтобы закрыть Http2Stream.
const http2 = require('http2');
const fs = require('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'
};
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> -
options<Объект>-
statCheck<Функция> -
onError<Функция> Обратная функция, вызываемая в случае ошибки до отправки. -
waitForTrailers<boolean> Еслиtrue,Http2Streamбудет издавать событие'wantTrailers'после отправки последнейDATAрамки. -
offset<number> Смещение позиции, с которой следует начать чтение. -
length<number> Объём данных из fd для отправки.
-
Отправляет обычный файл в качестве ответа. path должен указывать на обычный файл, иначе будет издано событие 'error' в объекте Http2Stream.
При использовании интерфейс Duplex объекта Http2Stream будет закрыт автоматически.
Можно указать необязательную функцию options.statCheck, чтобы предоставить коду пользователя возможность задать дополнительные заголовки содержимого на основе fs.Stat деталей данного файла:
Если при попытке чтения данных файла произойдёт ошибка, Http2Stream будет закрыт с помощью RST_STREAM рамки, используя стандартный INTERNAL_ERROR код. Если функция обратного вызова onError определена, то она будет вызвана. В противном случае поток будет уничтожен.
Пример с использованием пути к файлу:
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
headers['last-modified'] = stat.mtime.toUTCString();
}
function onError(err) {
if (err.code === 'ENOENT') {
stream.respond({ ':status': 404 });
} else {
stream.respond({ ':status': 500 });
}
stream.end();
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain' },
{ statCheck, onError });
});
Функция options.statCheck также может использоваться для отмены операции отправки, вернув false. Например, условный запрос может проверить результаты stat, чтобы определить, был ли файл изменён, чтобы вернуть соответствующий 304 ответ:
const http2 = require('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' },
{ statCheck });
});
Поле заголовка content-length будет автоматически задано.
Опции offset и length могут использоваться для ограничения ответа определённым подмножеством диапазонов. Это может быть использовано, например, для поддержки запросов HTTP Range.
Функция options.onError также может использоваться для обработки всех ошибок, которые могут произойти до начала доставки файла. По умолчанию поведение заключается в уничтожении потока.
Когда опция options.waitForTrailers установлена, событие 'wantTrailers' будет издано сразу после очереди последнего фрагмента данных полезной нагрузки для отправки. Затем метод http2stream.sendTrilers() может быть использован для отправки заголовков-прицепов к пиру.
Когда options.waitForTrailers установлено, Http2Stream не будет автоматически закрываться при передаче последней DATA рамки. Код пользователя должен вызвать либо http2stream.sendTrailers(), либо http2stream.close(), чтобы закрыть Http2Stream.
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain' },
{ waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
});
Класс: Http2Server
- Расширяет: <net.Сервер>
Экземпляры Http2Server создаются с помощью функции http2.createServer(). Класс Http2Server не экспортируется напрямую модулем http2.
Событие: 'checkContinue'
-
request<http2.ЗапросHttp2Сервера> -
response<http2.ОтветHttp2Сервера>
Если зарегистрирован обработчик 'request' или http2.createServer() предоставляет функцию обратного вызова, событие 'checkContinue' издаётся каждый раз при получении запроса с HTTP Expect: 100-continue. Если за этим событием не следят, сервер автоматически ответит статусом 100 Continue как требуется.
Обработка данного события включает в себя вызов response.writeContinue(), если клиент должен продолжить отправку тела запроса, или создание соответствующего HTTP ответа (например, 400 Bad Request), если клиент не должен продолжать отправку тела запроса.
Обратите внимание, что при издании и обработке этого события событие 'request' не будет издано.
Событие: 'request'
-
request<http2.ЗапросHttp2Сервера> -
response<http2.ОтветHttp2Сервера>
Издаётся каждый раз при наличии запроса. Обратите внимание, что может быть несколько запросов на сессию. Смотрите API совместимости.
Событие: 'session'
Событие 'session' издаётся при создании новой Http2Session объектом Http2Server.
Событие: 'sessionError'
Событие 'sessionError' издаётся при издании события 'error' объектом Http2Session, связанным с Http2Server.
Событие: 'stream'
Событие 'stream' издаётся при издании события 'stream' объектом Http2Session, связанным с сервером.
const http2 = require('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'
});
stream.write('hello ');
stream.end('world');
});
Событие: 'timeout'
Событие 'timeout' издаётся при отсутствии активности на сервере в течение заданного количества миллисекунд, заданного с помощью http2server.setTimeout(). По умолчанию: 2 минуты.
server.close([callback])
-
callback<Функция>
Останавливает сервер от принятия новых подключений. Смотрите net.Server.close().
Обратите внимание, что это не аналогично ограничению новых запросов, так как соединения HTTP/2 сохраняются. Для достижения аналогичного поведения плавного завершения работы рассмотрите также использование http2session.close() для активных сессий.
server.setTimeout([msecs][, callback])
-
msecs<число> По умолчанию:120000(2 минуты) -
callback<Функция> - Возвращает: <Http2Сервер>
Используется для установки значения таймаута для запросов http2 сервера и устанавливает функцию обратного вызова, которая вызывается, когда нет активности на Http2Server после msecs миллисекунд.
Указанный обратный вызов регистрируется как обработчик события 'timeout'.
В случае, если функция обратного вызова не была назначена, будет выброшено новое исключение ERR_INVALID_CALLBACK ошибки.
Класс: Http2SecureServer
- Расширяет: <tls.Сервер>
Экземпляры Http2SecureServer создаются с помощью функции http2.createSecureServer(). Класс Http2SecureServer не экспортируется напрямую модулем http2.
Событие: 'checkContinue'
-
request<http2.ЗапросHttp2Сервера> -
response<http2.ОтветHttp2Сервера>
Если зарегистрирован обработчик 'request' или http2.createSecureServer() предоставляет функцию обратного вызова, событие 'checkContinue' издаётся каждый раз при получении запроса с HTTP Expect: 100-continue. Если за этим событием не следят, сервер автоматически ответит статусом 100 Continue как требуется.
Обработка данного события включает в себя вызов response.writeContinue(), если клиент должен продолжить отправку тела запроса, или создание соответствующего HTTP ответа (например, 400 Bad Request), если клиент не должен продолжать отправку тела запроса.
Обратите внимание, что при издании и обработке этого события событие 'request' не будет издано.
Событие: 'request'
-
request<http2.ЗапросHttp2Сервера> -
response<http2.ОтветHttp2Сервера>
Издаётся каждый раз при наличии запроса. Обратите внимание, что может быть несколько запросов на сессию. Смотрите API совместимости.
Событие: 'session'
Событие 'session' генерируется при создании нового Http2Session объектом Http2SecureServer.
Событие: 'sessionError'
Событие 'sessionError' генерируется при возникновении события 'error' объектом Http2Session , связанным с Http2SecureServer.
Событие: 'stream'
Событие 'stream' генерируется при возникновении события 'stream' объектом Http2Session, связанным с сервером.
const http2 = require('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'
});
stream.write('hello ');
stream.end('world');
});
Событие: 'timeout'
Событие 'timeout' генерируется, когда на сервере отсутствует активность в течение заданного количества миллисекунд, установленного с помощью http2secureServer.setTimeout(). По умолчанию: 2 минуты.
Событие: 'unknownProtocol'
Событие 'unknownProtocol' генерируется, когда подключаемый клиент не может договориться об разрешенном протоколе (т.е. HTTP/2 или HTTP/1.1). Обработчик события получает сокет для обработки. Если слушатель для этого события не зарегистрирован, соединение закрывается. См. API совместимости.
server.close([callback])
-
callback<Функция>
Останавливает сервер от приема новых подключений. См. tls.Server.close().
Обратите внимание, что это не аналогично ограничению новых запросов, так как HTTP/2 соединения сохраняются. Для достижения аналогичного поведения плавного завершения работы, рассмотрите также использование http2session.close() для активных сеансов.
server.setTimeout([msecs][, callback])
Используется для установки значения таймаута для запросов http2 защищенного сервера и устанавливает функцию обратного вызова, которая вызывается, когда на Http2SecureServer отсутствует активность после msecs миллисекунд.
Указанная функция обратного вызова регистрируется как слушатель события 'timeout'.
В случае, если функция обратного вызова не была назначена, будет брошено новое исключение ERR_INVALID_CALLBACK.
http2.createServer(options[, onRequestHandler])
-
options<Объект>-
maxDeflateDynamicTableSize<число> Устанавливает максимальный размер динамической таблицы для сжатия заголовков. По умолчанию:4Kib. -
maxSessionMemory<число> Устанавливает максимальный объем памяти, который разрешено использоватьHttp2Session. Значение выражается в мегабайтах, например,1равно 1 мегабайту. Минимальное разрешенное значение1. Это ограничение на основе кредитов, существующиеHttp2Streamмогут привести к превышению этого ограничения, но новые экземплярыHttp2Streamбудут отклонены, пока это ограничение не будет превышено. Текущее количествоHttp2Streamсеансов, текущее использование памяти таблицами сжатия заголовков, текущие данные, ожидаемые для отправки, и незавершенныеPINGиSETTINGSкадр учитываются в текущем пределе. По умолчанию:10. -
maxHeaderListPairs<число> Устанавливает максимальное количество записей заголовков. Минимальное значение4. По умолчанию:128. -
maxOutstandingPings<число> Устанавливает максимальное количество незавершенных, не подтвержденных пингов. По умолчанию:10. -
maxSendHeaderBlockLength<число> Устанавливает максимальный допустимый размер сериализованного, сжатого блока заголовков. Попытки отправить заголовки, которые превышают этот предел, приведут к генерации события'frameError'и закрытию и уничтожению потока. -
paddingStrategy<число> Определяет стратегию для определения количества заполнения дляHEADERSиDATAкадров. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Значение может быть одним из:-
http2.constants.PADDING_STRATEGY_NONE- Указывает, что заполнение не должно применяться. -
http2.constants.PADDING_STRATEGY_MAX- Указывает, что должно быть применено максимальное количество заполнения, как определено внутренней реализацией. -
http2.constants.PADDING_STRATEGY_CALLBACK- Указывает, что функция обратного вызова, предоставленная пользователемoptions.selectPadding, должна использоваться для определения количества заполнения. -
http2.constants.PADDING_STRATEGY_ALIGNED- Попытается применить достаточно заполнения, чтобы гарантировать, что общая длина кадра, включая 9-байтовый заголовок, является кратной 8. Однако для каждого кадра существует максимальное допустимое количество байтов заполнения, которое определяется текущим состоянием и настройками управления потоком. Если это максимальное значение меньше рассчитанного значения, необходимого для обеспечения выравнивания, будет использовано максимальное значение, и общая длина кадра не будет обязательно выровнена по 8 байтам.
-
-
peerMaxConcurrentStreams<число> Устанавливает максимальное количество одновременных потоков для удаленного узла, как если бы был получен кадрSETTINGS. Будет перезаписано, если удаленный узел установит собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
selectPadding<Функция> Когдаoptions.paddingStrategyравноhttp2.constants.PADDING_STRATEGY_CALLBACK, предоставляет функцию обратного вызова, используемую для определения заполнения. См. Использование options.selectPadding. -
settings<Объект настроек HTTP/2> Начальные настройки, которые отправляются удаленному узлу при подключении. -
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.
-
-
onRequestHandler<Функция> См. API совместимости - Возвращает: <Http2Server>
Возвращает экземпляр net.Server, который создает и управляет экземплярами Http2Session.
Поскольку нет известных браузеров, поддерживающих незашифрованный HTTP/2, использование http2.createSecureServer() необходимо при общении с клиентскими браузерами.
const http2 = require('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',
':status': 200
});
stream.end('<h1>Hello World</h1>');
});
server.listen(80);
http2.createSecureServer(options[, onRequestHandler])
-
options<Объект>-
allowHTTP1<boolean> Входящие клиентские подключения, не поддерживающие HTTP/2, будут понижены до HTTP/1.x, если установлено значениеtrue. См. событие'unknownProtocol'. См. переговоры ALPN. По умолчанию:false. -
maxDeflateDynamicTableSize<число> Устанавливает максимальный размер динамической таблицы для сжатия заголовков. По умолчанию:4Kib. -
maxSessionMemory<число> Устанавливает максимальный объем памяти, который может использоватьHttp2Session. Значение выражается в мегабайтах, например,1равно 1 мегабайту. Минимальное разрешенное значение —1. Это ограничение на основе квоты; существующиеHttp2Streamмогут привести к превышению этого предела, но новые экземплярыHttp2Streamбудут отклонены, пока этот предел не будет превышен. Текущее числоHttp2Streamсессий, текущее использование памяти таблицами сжатия заголовков, текущие данные, ожидающие отправки, а также неподтвержденныеPINGиSETTINGSкадры учитываются в текущем лимите. По умолчанию:10. -
maxHeaderListPairs<число> Устанавливает максимальное число записей заголовков. Минимальное значение —4. По умолчанию:128. -
maxOutstandingPings<число> Устанавливает максимальное количество неподтвержденных пингов. По умолчанию:10. -
maxSendHeaderBlockLength<число> Устанавливает максимальный разрешенный размер сериализованного, сжатого блока заголовков. Попытки отправить заголовки, превышающие этот предел, приведут к тому, что будет отправлено событие'frameError'и поток будет закрыт и уничтожен. -
paddingStrategy<число> Идентифицирует стратегию, используемую для определения количества заполнения дляHEADERSиDATAкадров. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Значение может быть одним из:-
http2.constants.PADDING_STRATEGY_NONE— Указывает, что заполнение применять не нужно. -
http2.constants.PADDING_STRATEGY_MAX— Указывает, что должно быть применено максимальное количество заполнения, определяемое внутренней реализацией. -
http2.constants.PADDING_STRATEGY_CALLBACK— Указывает, что должен использоваться предоставленный пользователем обратный вызовoptions.selectPaddingдля определения количества заполнения. -
http2.constants.PADDING_STRATEGY_ALIGNED— Попытается применить достаточное количество заполнения, чтобы обеспечить, что общая длина кадра, включая 9-байтовый заголовок, является кратной 8. Однако для каждого кадра существует максимальное разрешенное количество байтов заполнения, которое определяется текущим состоянием и настройками управления потоком. Если это максимальное значение меньше рассчитанного количества, необходимого для выравнивания, будет использоваться максимальное значение, и общая длина кадра не обязательно будет выровнена по 8 байтам.
-
-
peerMaxConcurrentStreams<число> Устанавливает максимальное количество одновременных потоков для удаленного узла, как если бы был получен кадрSETTINGS. Будет перезаписано, если удаленный узел установит собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
selectPadding<Функция> Когдаoptions.paddingStrategyравноhttp2.constants.PADDING_STRATEGY_CALLBACK, предоставляет функцию обратного вызова, используемую для определения заполнения. См. Использование options.selectPadding. -
settings<Объект настроек HTTP/2> Начальные настройки, которые необходимо отправить удаленному узлу при подключении. - ...: Любые параметры
tls.createServer()могут быть предоставлены. Для серверов обычно требуются параметры идентификации (pfxилиkey/cert). -
origins<массив строк> Массив строк происхождения, которые необходимо отправить в кадреORIGINнепосредственно после создания нового серверногоHttp2Session.
-
-
onRequestHandler<Функция> См. API совместимости - Возвращает: <Http2SecureServer>
Возвращает экземпляр tls.Server, который создает и управляет экземплярами Http2Session.
const http2 = require('http2');
const fs = require('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',
':status': 200
});
stream.end('<h1>Hello World</h1>');
});
server.listen(80);
http2.connect(authority[, options][, listener])
-
authority<строка> | <URL> -
options<Объект>-
maxDeflateDynamicTableSize<число> Устанавливает максимальный размер динамической таблицы для сжатия заголовков. По умолчанию:4Kib. -
maxSessionMemory<число> Устанавливает максимальный объём памяти, который разрешено использоватьHttp2Session. Значение выражается в мегабайтах, например,1равно 1 мегабайту. Минимально допустимое значение1. Это ограничение на основе квоты, существующиеHttp2Streamмогут привести к превышению этого лимита, но новые экземплярыHttp2Streamбудут отклоняться, пока этот лимит превышен. Текущее количествоHttp2Streamсессий, текущее использование памяти таблицами сжатия заголовков, текущие данные, ожидающие отправки, и неподтверждённыеPINGиSETTINGSкадры учитываются в текущем лимите. По умолчанию:10. -
maxHeaderListPairs<число> Устанавливает максимальное количество записей в заголовках. Минимальное значение1. По умолчанию:128. -
maxOutstandingPings<число> Устанавливает максимальное количество открытых, неподтверждённых запросов ping. По умолчанию:10. -
maxReservedRemoteStreams<число> Устанавливает максимальное количество зарезервированных push-потоков, которые клиент будет принимать в любой момент времени. Как только текущее количество зарезервированных push-потоков превысит этот лимит, новые push-потоки, отправленные сервером, будут автоматически отклоняться. -
maxSendHeaderBlockLength<число> Устанавливает максимальный разрешённый размер сериализованного, сжатого блока заголовков. Попытки отправить заголовки, превышающие этот лимит, приведут к тому, что будет выброшено событие'frameError', и поток будет закрыт и уничтожен. -
paddingStrategy<число> Определяет стратегию определения количества заполнения дляHEADERSиDATAкадров. По умолчанию:http2.constants.PADDING_STRATEGY_NONE. Значение может быть одним из:-
http2.constants.PADDING_STRATEGY_NONE- Указывает, что заполнение не применяется. -
http2.constants.PADDING_STRATEGY_MAX- Указывает, что применяется максимальное количество заполнения, определяемое внутренней реализацией. -
http2.constants.PADDING_STRATEGY_CALLBACK- Указывает, что для определения количества заполнения используется пользовательская функция обратного вызоваoptions.selectPadding. -
http2.constants.PADDING_STRATEGY_ALIGNED- Попытается применить достаточное количество заполнения, чтобы гарантировать, что общая длина кадра, включая 9-байтовый заголовок, является кратной 8. Однако для каждого кадра существует максимальное количество байтов заполнения, определяемое текущим состоянием и параметрами управления потоком. Если это максимальное значение меньше рассчитанного значения, необходимого для выравнивания, будет использоваться максимальное значение, и общая длина кадра не обязательно будет выровнена по 8 байтам.
-
-
peerMaxConcurrentStreams<число> Устанавливает максимальное количество одновременных потоков для удалённого узла, как если бы был получен кадрSETTINGS. Будет перезаписано, если удалённый узел установит собственное значение дляmaxConcurrentStreams. По умолчанию:100. -
selectPadding<Функция> Когдаoptions.paddingStrategyравноhttp2.constants.PADDING_STRATEGY_CALLBACK, предоставляет функцию обратного вызова, используемую для определения заполнения. См. Использование options.selectPadding. -
settings<Объект настроек HTTP/2> Начальные настройки для отправки удалённому узлу при подключении. -
createConnection<Функция> Необязательный обратный вызов, который получает экземплярURL, переданный вconnect, и объектoptions, и возвращает любойDuplexпоток, который должен использоваться в качестве подключения для этой сессии. - ...: Любые параметры
net.connect()илиtls.connect()могут быть предоставлены.
-
-
listener<Функция> - Возвращает <ClientHttp2Session>
Возвращает экземпляр ClientHttp2Session.
const http2 = require('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>
Возвращает объект, содержащий значения по умолчанию для экземпляра Http2Session. Этот метод каждый раз возвращает новый экземпляр объекта, поэтому возвращаемые экземпляры могут быть безопасно изменены для использования.
http2.getPackedSettings(settings)
-
settings<Объект настроек HTTP/2> - Возвращает: <Буфер>
Возвращает экземпляр Buffer, содержащий сериализованное представление заданных настроек HTTP/2, как указано в спецификации HTTP/2. Предназначен для использования с полем заголовка HTTP2-Settings.
const http2 = require('http2');
const packed = http2.getPackedSettings({ enablePush: false });
console.log(packed.toString('base64'));
// Prints: AAIAAAAA
http2.getUnpackedSettings(buf)
-
buf<Буфер> | <Uint8 массив> Упакованные настройки. - Возвращает: <Объект настроек HTTP/2>
Возвращает объект настроек HTTP/2, содержащий десериализованные настройки из заданного Buffer, сгенерированные методом http2.getPackedSettings().
Объект заголовков
Заголовки представлены как собственные свойства в объектах JavaScript. Ключи свойств будут сериализованы в нижнем регистре. Значения свойств должны быть строками (если они таковыми не являются, они будут преобразованы в строки) или массивом строк (чтобы отправить более одного значения на поле заголовка).
Например:
const headers = {
':status': '200',
'content-type': 'text-plain',
'ABC': ['has', 'more', 'than', 'one', 'value']
};
stream.respond(headers);
Примечание: Объекты заголовков, переданные в функции обратного вызова, будут иметь прототип null. Это означает, что обычные методы объектов JavaScript, такие как Object.prototype.toString() и Object.prototype.hasOwnProperty() работать не будут.
Для входящих заголовков:
- Заголовок
:statusпреобразуется вnumber. - Дубликаты
:status,:method,:authority,:scheme,:path,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,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: значения объединяются с помощью '; '. - Для всех остальных заголовков значения объединяются с помощью ', '.
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});
Объект настроек
API http2.getDefaultSettings(), http2.getPackedSettings(), http2.createServer(), http2.createSecureServer(), http2session.settings(), http2session.localSettings, и http2session.remoteSettings либо возвращают, либо принимают в качестве входных данных объект, определяющий параметры конфигурации для объекта Http2Session. Эти объекты являются обычными JavaScript-объектами, содержащими следующие свойства.
-
headerTableSize<число> Указывает максимальное количество байтов, используемых для сжатия заголовков. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:4,096 octets. -
enablePush<логическое значение> Указывает,trueразрешены ли потоки HTTP/2 Push на экземплярахHttp2Session. -
initialWindowSize<число> Указывает начальный размер окна отправителя для управления потоком на уровне потоков. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:65,535 bytes. -
maxFrameSize<число> Указывает размер полезной нагрузки самого большого кадра. Минимальное допустимое значение — 16 384. Максимальное допустимое значение — 224-1. По умолчанию:16,384 bytes. -
maxConcurrentStreams<число> Указывает максимальное количество одновременных потоков, разрешенных дляHttp2Session. Нет значения по умолчанию, что подразумевает, по крайней мере теоретически, 231-1 потоков могут быть открыты одновременно в любой момент времени вHttp2Session. Минимальное значение — 0. Максимальное допустимое значение — 231-1. -
maxHeaderListSize<число> Указывает максимальный размер (нескомпрессированные октеты) списка заголовков, который будет принят. Минимальное допустимое значение — 0. Максимальное допустимое значение — 232-1. По умолчанию:65535.
Все дополнительные свойства в объекте настроек игнорируются.
Использование options.selectPadding
Когда options.paddingStrategy равно http2.constants.PADDING_STRATEGY_CALLBACK, реализация HTTP/2 обратится к функции обратного вызова options.selectPadding, если она предоставлена, чтобы определить конкретное количество заполнения, используемого для каждого кадра HEADERS и DATA.
Функция options.selectPadding получает два числовых аргумента, frameLen и maxFrameLen, и должна вернуть число N, такое что frameLen <= N <= maxFrameLen.
const http2 = require('http2');
const server = http2.createServer({
paddingStrategy: http2.constants.PADDING_STRATEGY_CALLBACK,
selectPadding(frameLen, maxFrameLen) {
return maxFrameLen;
}
});
Примечание: Функция options.selectPadding вызывается один раз для каждого кадра HEADERS и DATA. Это оказывает заметное влияние на производительность.
Обработка ошибок
Существуют несколько типов условий ошибок, которые могут возникнуть при использовании модуля http2:
Ошибки валидации возникают, когда передается неправильное значение аргумента, параметра или настройки. Эти ошибки всегда будут сообщаться с помощью синхронной функции throw.
Ошибки состояния возникают, когда действие выполняется в неподходящее время (например, попытка отправки данных по потоку после его закрытия). Эти ошибки будут сообщаться либо с помощью синхронной функции throw, либо через событие 'error' в объектах Http2Stream, Http2Session или сервера HTTP/2, в зависимости от места и времени возникновения ошибки.
Внутренние ошибки возникают, когда сеанс HTTP/2 неожиданно завершается сбоем. Эти ошибки будут сообщаться через событие 'error' в объектах Http2Session или сервера HTTP/2.
Ошибки протокола возникают, когда нарушаются различные ограничения протокола HTTP/2. Эти ошибки будут сообщаться либо с помощью синхронной функции throw, либо через событие 'error' в объектах Http2Stream, Http2Session или сервера HTTP/2, в зависимости от места и времени возникновения ошибки.
Обработка недопустимых символов в именах и значениях заголовков
Реализация HTTP/2 применяет более строгую обработку недопустимых символов в именах и значениях заголовков HTTP по сравнению с реализацией HTTP/1.
Имена полей заголовков нечувствительны к регистру и передаются по сети строго как строки в нижнем регистре. API Node.js позволяет устанавливать имена заголовков как строки с разным регистром (например, Content-Type), но преобразование в нижний регистр (например, content-type) происходит при передаче.
Имена полей заголовков должны содержать только один или несколько из следующих символов ASCII: a-z, A-Z, 0-9, !, #, $, %, &, ', *, +, -, ., ^, _, ` (обратная косая черта), |, и ~.
Использование недопустимых символов в имени поля заголовка приведет к закрытию потока с сообщением об ошибке протокола.
Значения полей заголовков обрабатываются более лояльно, но не должны содержать символы новой строки или возврата каретки, и должны ограничиваться символами US-ASCII в соответствии с требованиями спецификации HTTP.
Потоки push на клиенте
Для получения потоков push на клиенте установите обработчик события 'stream' на объекте ClientHttp2Session:
const http2 = require('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-сервер:
const net = require('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:
const http2 = require('http2');
const { NGHTTP2_REFUSED_STREAM } = http2.constants;
const net = require('net');
const { URL } = require('url');
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:
const http2 = require('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:${port}`
});
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');
API совместимости
API совместимости направлено на предоставление похожего пользовательского опыта HTTP/1 при использовании HTTP/2, позволяя разрабатывать приложения, поддерживающие как HTTP/1, так и HTTP/2. Этот API затрагивает только публичный API HTTP/1. Однако многие модули используют внутренние методы или состояние, и они не поддерживаются, так как это совершенно другая реализация.
В следующем примере создается сервер HTTP/2 с использованием API совместимости:
const http2 = require('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' });
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.
Следующий пример создает сервер, который поддерживает оба протокола:
const { createSecureServer } = require('http2');
const { readFileSync } = require('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
Объект Http2ServerRequest создается с помощью http2.Server или http2.SecureServer и передается в качестве первого аргумента в событие 'request'. Он может использоваться для доступа к статусу запроса, заголовкам и данным.
Он реализует интерфейс потока Readable Stream, а также следующие дополнительные события, методы и свойства.
Событие: 'aborted'
Событие 'aborted' генерируется всякий раз, когда экземпляр Http2ServerRequest аномально прерывается во время коммуникации.
Примечание: Событие 'aborted' будет сгенерировано только в том случае, если записывающая сторона Http2ServerRequest не была завершена.
Событие: 'close'
Указывает, что основной поток Http2Stream был закрыт. Подобно событию 'end', это событие происходит только один раз на каждый ответ.
request.aborted
Свойство request.aborted будет true , если запрос был прерван.
request.destroy([error])
-
error<Ошибка>
Вызывает destroy() у потока Http2Stream, который получил запрос Http2ServerRequest. Если error предоставлено, генерируется событие 'error', и error передается в качестве аргумента всем обработчикам события.
Не делает ничего, если поток уже был уничтожен.
request.headers
Объект заголовков запроса/ответа.
Пара ключ-значение имён и значений заголовков. Имена заголовков находятся в нижнем регистре. Пример:
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers);
Примечание: В HTTP/2 путь запроса, имя хоста, протокол и метод представлены как специальные заголовки с префиксом символом : (например, ':path'). Эти специальные заголовки будут включены в объект request.headers. Необходимо быть внимательным, чтобы случайно не изменить эти специальные заголовки, иначе могут возникнуть ошибки. Например, удаление всех заголовков из запроса приведёт к ошибкам:
removeAllHeaders(request.headers); assert(request.url); // Fails because the :path header has been removed
request.httpVersion
В случае запроса сервера — HTTP-версия, отправленная клиентом. В случае ответа клиента — HTTP-версия подключённого сервера. Возвращает '2.0'.
Также message.httpVersionMajor — первое целое число, а message.httpVersionMinor — второе.
request.method
Метод запроса в виде строки. Только для чтения. Пример: 'GET', 'DELETE'.
request.rawHeaders
Список необработанных заголовков запроса/ответа в точном соответствии с их получением.
Обратите внимание, что ключи и значения находятся в одном списке. Это не список кортежей. Таким образом, чётные индексы — значения ключей, а нечётные — соответствующие значения.
Имена заголовков не приводятся к нижнему регистру, и дубликаты не объединяются.
// 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);
request.rawTrailers
Необработанные ключи и значения трейлеров запроса/ответа в точном соответствии с их получением. Заполняется только в событии 'end'.
request.setTimeout(msecs, callback)
Устанавливает значение таймаута для Http2Stream на msecs. Если указана функция обратного вызова, она добавляется в качестве обработчика события 'timeout' объекта ответа.
Если обработчик события 'timeout' не добавлен к запросу, ответу или серверу, то Http2Stream уничтожаются при истечении времени ожидания. Если обработчик назначен для событий 'timeout' запроса, ответа или сервера, отработавшие по таймауту сокеты необходимо обработать явно.
Возвращает request.
request.socket
Возвращает объект-прокси, который действует как 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. См. Сессии и сокеты Http2 для получения дополнительной информации.
Все остальные взаимодействия будут направлены непосредственно в сокет. При поддержке TLS используйте request.socket.getPeerCertificate() для получения данных аутентификации клиента.
request.stream
- <http2.Http2Поток>
Объект Http2Stream, поддерживающий запрос.
request.trailers
Объект трейлеров запроса/ответа. Заполняется только в событии 'end'.
request.url
Строка URL запроса. Содержит только URL, присутствующий в фактическом HTTP-запросе. Если запрос:
GET /status?name=ryan HTTP/1.1\r\n Accept: text/plain\r\n \r\n
Тогда request.url будет:
'/status?name=ryan'
Для разбора URL на части можно использовать require('url').parse(request.url). Пример:
$ node
> require('url').parse('/status?name=ryan')
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=ryan',
query: 'name=ryan',
pathname: '/status',
path: '/status?name=ryan',
href: '/status?name=ryan' }
Для извлечения параметров из строки запроса можно использовать функцию require('querystring').parse, или true может быть передано как второй аргумент в require('url').parse . Пример:
$ node
> require('url').parse('/status?name=ryan', true)
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=ryan',
query: { name: 'ryan' },
pathname: '/status',
path: '/status?name=ryan',
href: '/status?name=ryan' }
Класс: http2.Http2ServerResponse
Этот объект создаётся внутренне сервером HTTP — не пользователем. Он передаётся как второй параметр в событие 'request'.
Ответ реализует, но не наследуется от, интерфейса Потокового потока записи. Это EventEmitter со следующими событиями:
Событие: 'close'
Указывает, что лежащий в основе Http2Stream был завершён до вызова response.end() или возможности сброса.
Событие: 'finish'
Срабатывает, когда ответ отправлен. Более конкретно, это событие срабатывает, когда последняя часть заголовков ответа и тела передана в HTTP/2 для передачи по сети. Это не подразумевает, что клиент что-то получил.
После этого события больше событий на объекте ответа не будет.
response.addTrailers(headers)
-
headers<Объект>
Этот метод добавляет HTTP-трейлеры заголовков (заголовок в конце сообщения) к ответу.
Попытка установить имя или значение поля заголовка, содержащее недопустимые символы, приведёт к выбрасыванию TypeError.
response.connection
См. response.socket.
response.end([data][, encoding][, callback])
Этот метод сигнализирует серверу, что все заголовки ответа и тело отправлены; сервер должен рассматривать это сообщение как полное. Метод response.end() ДОЛЖЕН быть вызван для каждого ответа.
Если data указан, это эквивалентно вызову response.write(data, encoding), после чего следует response.end(callback).
Если callback указан, он будет вызван, когда поток ответа завершится.
response.finished
Булево значение, указывающее, завершён ли ответ. Начинается как false. После выполнения response.end(), значение станет true.
response.getHeader(name)
Считывает заголовок, который уже был помещён в очередь, но ещё не отправлен клиенту. Обратите внимание, что имя регистронезависимо.
Пример:
const contentType = response.getHeader('content-type');
response.getHeaderNames()
- Возвращает: <Массив>
Возвращает массив, содержащий уникальные имена текущих исходящих заголовков. Все имена заголовков находятся в нижнем регистре.
Пример:
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']
response.getHeaders()
- Возвращает: <Объект>
Возвращает поверхностную копию текущих исходящих заголовков. Поскольку используется поверхностная копия, значения массивов могут быть изменены без дополнительных вызовов различных методов модуля 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'] }
response.hasHeader(name)
-
name<строка> - Возвращает: <логическое значение>
Возвращает true, если заголовок, идентифицируемый по name, в данный момент установлен в исходящих заголовках. Обратите внимание, что соответствие имени заголовка не учитывает регистр.
Пример:
const hasContentType = response.hasHeader('content-type');
response.headersSent
Логическое значение (только для чтения). True, если заголовки были отправлены, иначе false.
response.removeHeader(name)
-
name<строка>
Удаляет заголовок, который был помещен в очередь для неявной отправки.
Пример:
response.removeHeader('Content-Encoding');
response.sendDate
Если значение true, заголовок Date будет автоматически сгенерирован и отправлен в ответе, если он еще не присутствует в заголовках. По умолчанию значение true.
Это следует отключать только для тестирования; HTTP требует заголовок Date в ответах.
response.setHeader(name, value)
-
name<строка> -
value<строка> | <массив строк>
Устанавливает единственное значение заголовка для неявных заголовков. Если этот заголовок уже существует в заголовках, которые будут отправлены, его значение будет заменено. Используйте массив строк для отправки нескольких заголовков с одним и тем же именем.
Пример:
response.setHeader('Content-Type', 'text/html');
или
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
Попытка установить имя поля заголовка или значение, содержащее недопустимые символы, приведет к тому, что будет выброшено исключение TypeError.
Когда заголовки были установлены с помощью response.setHeader(), они будут объединены с любыми заголовками, переданными в response.writeHead(), при этом заголовки, переданные в response.writeHead(), будут иметь приоритет.
// returns content-type = text/plain
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
response.setTimeout(msecs[, callback])
Устанавливает значение таймаута Http2Stream на msecs. Если callback указан, он добавляется как слушатель события 'timeout' объекта ответа.
Если к запросу, ответу или серверу не добавлен слушатель события 'timeout', сокеты, превысившие время ожидания, будут уничтожены. Если обработчик назначен для запроса, ответа или событий 'timeout' сервера, время ожидания сокетов необходимо обрабатывать явно.
Возвращает response.
response.socket
Возвращает объект 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 и сокеты.
Все остальные взаимодействия будут перенаправлены непосредственно на сокет.
Пример:
const http2 = require('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
При использовании неявных заголовков (если явно не вызывается response.writeHead()), это свойство контролирует код состояния, который будет отправлен клиенту, когда заголовки будут отправлены.
Пример:
response.statusCode = 404;
После отправки заголовка ответа клиенту это свойство указывает код состояния, который был отправлен.
response.statusMessage
Сообщение состояния не поддерживается HTTP/2 (RFC7540 8.1.2.4). Возвращает пустую строку.
response.stream
- <http2.Http2Stream>
Объект Http2Stream, поддерживающий ответ.
response.write(chunk[, encoding][, callback])
-
chunk<строка> | <Буфер> -
encoding<строка> -
callback<Функция> - Возвращает: <логическое значение>
Если этот метод вызван, а response.writeHead() не был вызван, он переключится на режим неявных заголовков и отправит неявные заголовки.
Отправляет часть тела ответа. Этот метод можно вызывать несколько раз для предоставления последовательных частей тела.
Обратите внимание, что в модуле http, тело ответа опущено, когда запрос является запросом HEAD. Аналогично, ответы 204 и 304 не должны содержать тело сообщения.
chunk может быть строкой или буфером. Если chunk является строкой, второй параметр определяет, как её закодировать в байтовый поток. По умолчанию кодировка encoding — 'utf8'. callback будет вызван, когда этот фрагмент данных будет отправлен.
Примечание: Это необработанное тело HTTP и не имеет отношения к кодировкам тела более высокого уровня, которые могут использоваться.
В первый раз, когда вызывается response.write(), он отправит буферизованную информацию заголовка и первый фрагмент тела клиенту. Во второй раз, когда вызывается response.write(), Node.js предполагает, что данные будут передаваться потоком, и отправляет новые данные отдельно. То есть, ответ буферизуется до первого фрагмента тела.
Возвращает true если все данные были успешно отправлены в ядро. Возвращает false если все или часть данных были помещены в пользовательскую память. 'drain' будет испущен, когда буфер снова будет свободен.
response.writeContinue()
Отправляет клиенту код состояния 100 Continue, указывающий, что тело запроса должно быть отправлено. См. событие 'checkContinue' на Http2Server и Http2SecureServer.
response.writeHead(statusCode[, statusMessage][, headers])
Отправляет заголовок ответа на запрос. Код состояния — это трёхзначный код состояния HTTP, например, 404. Последний аргумент, headers, — это заголовки ответа.
Для совместимости с HTTP/1 в качестве второго аргумента может передаваться удобочитаемый statusMessage. Однако, поскольку statusMessage не имеет значения в HTTP/2, этот аргумент не окажет никакого влияния, и будет выведено предупреждение.
Пример:
const body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain' });
Обратите внимание, что 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');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
Попытка установить имя или значение поля заголовка, содержащее недопустимые символы, приведёт к тому, что будет брошено исключение TypeError.
response.createPushResponse(headers, callback)
-
headers<Объект заголовков HTTP/2> Объект, описывающий заголовки -
callback<Функция> Вызывается, когдаhttp2stream.pushStream()завершен, или когда попытка создать нажатыйHttp2Streamзавершилась неудачно или была отклонена, или состояниеHttp2ServerRequestзакрыто до вызова методаhttp2stream.pushStream().-
err<Ошибка> -
stream<ServerHttp2Stream> Новый созданный объектServerHttp2Stream
-
Вызов http2stream.pushStream() с заданными заголовками и обертыванием переданного Http2Stream в вновь созданном Http2ServerResponse в качестве параметра обратного вызова, если операция выполнена успешно. При закрытии Http2ServerRequest обратный вызов вызывается с ошибкой ERR_HTTP2_INVALID_STREAM.
Сбор метрик производительности HTTP/2
API Performance Observer можно использовать для сбора основных метрик производительности для каждого экземпляра Http2Session и Http2Stream.
const { PerformanceObserver } = require('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<число> Количество полученных байт фреймаDATAдля этого экземпляраHttp2Stream. -
bytesWritten<число> Количество отправленных байт фреймаDATAдля этого экземпляраHttp2Stream. -
id<число> Идентификатор связанного экземпляраHttp2Stream -
timeToFirstByte<число> Количество миллисекунд, прошедших междуPerformanceEntrystartTimeи получением первого фреймаDATA. -
timeToFirstByteSent<число> Количество миллисекунд, прошедших междуPerformanceEntrystartTimeи отправкой первого фреймаDATA. -
timeToFirstHeader<число> Количество миллисекунд, прошедших междуPerformanceEntrystartTimeи получением первого заголовка.
Если name равно Http2Session, объект PerformanceEntry будет содержать следующие дополнительные свойства:
-
bytesRead<число> Количество полученных байтов для этого экземпляраHttp2Session. -
bytesWritten<число> Количество отправленных байтов для этого экземпляраHttp2Session. -
framesReceived<число> Количество полученных фреймов HTTP/2 экземпляромHttp2Session. -
framesSent<число> Количество отправленных фреймов HTTP/2 экземпляромHttp2Session. -
maxConcurrentStreams<число> Максимальное количество одновременно открытых потоков за время существования экземпляраHttp2Session. -
pingRTT<число> Количество миллисекунд, прошедших с момента отправки фреймаPINGи получения его подтверждения. Присутствует только если фреймPINGбыл отправлен по потокуHttp2Session. -
streamAverageDuration<число> Средняя продолжительность (в миллисекундах) для всех экземпляровHttp2Stream. -
streamCount<число> Количество обработанных экземпляровHttp2StreamэкземпляромHttp2Session. -
type<строка> Либо'server', либо'client'для идентификации типа экземпляраHttp2Session.
© 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-v8.x/docs/api/http2.html