HTTP/2
Модуль http2 предоставляет реализацию протокола HTTP/2. К нему можно получить доступ следующим образом:
const http2 = require('http2');
Основной API
Основной API предоставляет низкоуровневый интерфейс, разработанный специально для поддержки функций протокола HTTP/2. Он не предназначен для совместимости с API существующего модуля HTTP/1. Однако API совместимости — http2 API.
Основной API намного симметричнее между клиентом и сервером, чем http API. Например, большинство событий, таких как '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<integer> Тип кадра. -
code<integer> Код ошибки. -
id<integer> Идентификатор потока (или0, если кадр не связан с потоком).
Событие 'frameError' испускается, когда возникает ошибка при попытке отправки кадра в сессии. Если кадр, который не удалось отправить, связан с определённым Http2Stream, предпринимается попытка испустить событие 'frameError' в Http2Stream.
Если событие 'frameError' связано с потоком, поток будет закрыт и уничтожен сразу после события 'frameError' . Если событие не связано с потоком, Http2Session будет остановлен сразу после события 'frameError'.
Событие: 'goaway'
-
errorCode<number> Код ошибки HTTP/2, указанный в кадреGOAWAY. -
lastStreamID<number> Идентификатор последнего потока, успешно обработанного удалённым узлом (или0, если идентификатор не указан). -
opaqueData<Buffer> Если в кадреGOAWAYбыли включены дополнительные данные, то будет передан экземплярBuffer, содержащий эти данные.
Событие 'goaway' испускается при получении кадра GOAWAY.
Экземпляр Http2Session будет автоматически закрыт при испускании события 'goaway'.
Событие: 'localSettings'
-
settings<Объект настроек HTTP/2> Копия кадраSETTINGS.
Событие 'localSettings' испускается при получении подтверждающего кадра SETTINGS.
При использовании http2session.settings() для отправки новых настроек, изменённые настройки не вступят в силу до тех пор, пока не будет испущено событие 'localSettings'.
session.settings({ enablePush: false });
session.on('localSettings', (settings) => {
/* Use the new settings */
});
Событие: 'ping'
-
payload<Buffer> 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<number> Ассоциированные числовые флаги -
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.on('error', (error) => console.error(error));
stream.end('<h1>Hello World</h1>');
});
server.listen(80);
Хотя потоки HTTP/2 и сетевые сокеты не находятся в соответствии 1:1, сетевая ошибка уничтожит каждый отдельный поток, и её необходимо обрабатывать на уровне потока, как показано выше.
Событие: 'timeout'
После использования метода http2session.setTimeout() для установки таймаута для этого Http2Session, событие 'timeout' испускается, если в течение настроенного количества миллисекунд в Http2Session нет активности.
session.setTimeout(2000);
session.on('timeout', () => { /* .. */ });
http2session.alpnProtocol
Значение будет 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
Объект без прототипа, описывающий текущие локальные настройки этого 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 бита (little endian), обозначающая начало интервала PING.
http2session.ref()
Вызывает ref() для базового сокета экземпляра Http2Session по методу net.Socket.
http2session.remoteSettings
Объект без прототипа, описывающий текущие удалённые настройки этого Http2Session. Удалённые настройки устанавливаются подключённым клиентом HTTP/2.
http2session.setTimeout(msecs, callback)
Используется для установки обратного вызова, который вызывается при отсутствии активности на Http2Session после msecs миллисекунд. Указанная callback регистрируется как обработчик события 'timeout'.
http2session.socket
Возвращает объект 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.
-
-
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
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, определяющая источник (илиObjectс свойством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 Protocol ID.
Синтаксис этих значений не проверяется реализацией 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 будет обновлено, чтобы включить полученные origin.
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<boolean>trueесли сторона writable должна быть закрыта изначально, например, при отправке запросаGET, который не должен ожидать тела полезной нагрузки. -
exclusive<boolean> Когдаtrueиparentидентифицируют родительский поток, создаваемый поток становится единственной непосредственной зависимостью родителя, а все другие существующие зависимости становятся зависимыми от вновь созданного потока. По умолчанию:false. -
parent<число> Указывает числовой идентификатор потока, от которого зависит вновь созданный поток. -
weight<число> Указывает относительную зависимость потока по отношению к другим потокам с тем жеparent. Значение — число между1и256(включительно). -
waitForTrailers<boolean> Еслиtrue, тоHttp2Streamбудет генерировать событие'wantTrailers'после отправки последнего кадраDATA.
-
-
Возвращает: <ClientHttp2Stream>
Только для экземпляров HTTP/2 Client 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 writable не была закрыта.
Событие: 'close'
Событие 'close' отправляется, когда Http2Stream уничтожается. После отправки этого события экземпляр Http2Stream больше не пригоден для использования.
Код ошибки HTTP/2, используемый при закрытии потока, можно получить с помощью свойства http2stream.rstCode Если код — любое значение, отличное от 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
Устанавливается в значение true, если экземпляр Http2Stream был прерван аварийно. При установке этого значения, событие 'aborted' будет сгенерировано.
http2stream.bufferSize
Это свойство показывает количество символов, в настоящее время буферизованных для записи. Подробности см. в net.Socket.bufferSize.
http2stream.close(code[, callback])
-
code<number> Беззнаковое целое 32-битное число, определяющее код ошибки. По умолчанию:http2.constants.NGHTTP2_NO_ERROR(0x00). -
callback<Function> Необязательная функция, зарегистрированная для прослушивания события'close'.
Закрывает экземпляр Http2Stream путём отправки кадра RST_STREAM подключённому HTTP/2 узлу.
http2stream.closed
Устанавливается в значение true, если экземпляр Http2Stream был закрыт.
http2stream.destroyed
Устанавливается в значение true, если экземпляр Http2Stream был уничтожен и больше не используется.
http2stream.endAfterHeaders
Устанавливает значение true, если флаг END_STREAM был установлен в кадр заголовков запроса или ответа, что указывает на то, что дополнительные данные не должны быть получены и читаемая часть Http2Stream будет закрыта.
http2stream.pending
Устанавливается в значение true, если экземпляр Http2Stream еще не был назначен числовой идентификатор потока.
http2stream.priority(options)
-
options<Object>-
exclusive<boolean> Еслиtrueиparentидентифицирует родительский поток, этот поток становится единственной прямой зависимостью родителя, а все другие существующие зависимые потоки становятся зависимыми от этого потока. По умолчанию:false. -
parent<number> Указывает числовой идентификатор потока, от которого зависит этот поток. -
weight<number> Указывает относительную зависимость потока по отношению к другим потокам с тем жеparent. Значение является числом от1до256(включительно). -
silent<boolean> Еслиtrue, изменяет приоритет локально без отправки кадраPRIORITYподключённому узлу.
-
Обновляет приоритет для этого экземпляра Http2Stream.
http2stream.rstCode
Устанавливается в код ошибки RST_STREAM код ошибки, который был получен, когда Http2Stream был уничтожен после получения кадра RST_STREAM от подключённого узла, вызова http2stream.close() или http2stream.destroy(). Будет undefined, если Http2Stream не был закрыт.
http2stream.sentHeaders
Объект, содержащий отправленные заголовки для этого Http2Stream.
http2stream.sentInfoHeaders
Массив объектов, содержащих отправленные информационные (дополнительные) заголовки для этого Http2Stream.
http2stream.sentTrailers
Объект, содержащий отправленные прицепы для этого HttpStream.
http2stream.session
Ссылка на экземпляр Http2Session, который владеет этим Http2Stream. Значение будет undefined после уничтожения экземпляра Http2Stream.
http2stream.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function>
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.
-
-
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', и т.д.).
Класс: ClientHttp2Stream
- Расширяет <Http2Stream>
Класс ClientHttp2Stream является расширением Http2Stream, который используется исключительно для HTTP/2 клиентов. Экземпляры Http2Stream на клиенте предоставляют события, такие как 'response' и 'push', которые актуальны только на клиенте.
Событие: 'continue'
Вызывается, когда сервер отправляет статус 100 Continue, обычно потому, что запрос содержал Expect: 100-continue. Это инструкция, что клиент должен отправить тело запроса.
Событие: 'headers'
Событие 'headers' генерируется при получении дополнительного блока заголовков для потока, например, при получении блока 1xx информационных заголовков. Обработчик события получает объект HTTP/2 Headers Object и флаги, связанные с заголовками.
stream.on('headers', (headers, flags) => {
console.log(headers);
});
Событие: 'push'
Событие 'push' генерируется при получении заголовков ответа для потока Server Push. Обработчик события получает объект HTTP/2 Headers Object и флаги, связанные с заголовками.
stream.on('push', (headers, flags) => {
console.log(headers);
});
Событие: 'response'
Событие 'response' генерируется при получении фрейма ответа HEADERS для этого потока от подключенного HTTP/2 сервера. Обработчик вызывается с двумя аргументами: объектом Object, содержащим полученный объект HTTP/2 Headers Object, и флагами, связанными с заголовками.
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.pushStream() и http2stream.respond(), которые релевантны только на сервере.
http2stream.additionalHeaders(headers)
-
headers<Объект заголовков HTTP/2>
Отправляет дополнительный информационный HEADERS фрейм подключенному HTTP/2 узлу.
http2stream.headersSent
Истинно, если заголовки были отправлены, ложно в противном случае (только для чтения).
http2stream.pushAllowed
Только для чтения свойство, сопоставленное с флагом SETTINGS_ENABLE_PUSH последнего фрейма SETTINGS удаленного клиента. Будет true, если удаленный узел принимает потоки push, false в противном случае. Параметры одинаковы для каждого Http2Stream в одном и том же Http2Session.
http2stream.pushStream(headers[, options], callback)
-
headers<Объект заголовков HTTP/2> -
options<Объект>-
exclusive<boolean> Когдаtrueиparentидентифицируют родительский поток, созданный поток становится единственной непосредственной зависимостью родителя, а все другие существующие зависимости становятся зависимыми от вновь созданного потока. По умолчанию:false. -
parent<число> Указывает числовой идентификатор потока, от которого зависит вновь созданный поток.
-
-
callback<Функция> Обработчик события, вызываемый после инициализации потока push.-
err<Ошибка> -
pushStream<ServerHttp2Stream> Возвращённый объектpushStream. -
headers<Объект заголовков HTTP/2> Объект заголовков, с которым была инициированаpushStream.
-
Инициализирует поток 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<Объект>
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<Объект>
Инициализирует ответ, данные которого читаются из указанного дескриптора файла. Никакая валидация не выполняется для предоставленного дескриптора файла. Если при попытке чтения данных с помощью дескриптора файла возникнет ошибка, Http2Stream будет закрыт с использованием фрейма RST_STREAM с кодом INTERNAL_ERROR.
При использовании интерфейс 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<строка> | <Буфер> | <URL> -
headers<Объект заголовков HTTP/2> -
options<Объект>-
statCheck<Функция> -
onError<Функция> Функция обратного вызова, вызываемая в случае ошибки перед отправкой. -
waitForTrailers<логическое> Еслиtrue, тоHttp2Streamбудет излучать событие'wantTrailers'после отправки последней рамкиDATA. -
offset<число> Смещение позиции, с которой начинать чтение. -
length<число> Количество данных из fd для отправки.
-
Отправляет обычный файл в качестве ответа. path должен указывать на обычный файл, иначе будет излучено событие 'error' на объекте Http2Stream.
При использовании интерфейс 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.sendTrailers() может затем быть использован для отправки заголовков последответствия клиенту.
Когда 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.Server>
Экземпляры Http2Server создаются с помощью функции http2.createServer(). Класс Http2Server не экспортируется напрямую модулем http2.
Событие: 'checkContinue'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Если зарегистрирован слушатель 'request' или http2.createServer() содержит функцию обратного вызова, событие 'checkContinue' излучается каждый раз, когда принимается запрос с HTTP-Expect: 100-continue. Если за этим событием не следят, сервер автоматически ответит со статусом 100 Continue соответственно.
Обработка этого события включает вызов response.writeContinue(), если клиент должен продолжить отправку тела запроса, или генерацию соответствующего HTTP-ответа (например, 400 Bad Request), если клиент не должен продолжать отправку тела запроса.
Обратите внимание, что при излучении и обработке этого события событие 'request' не будет излучено.
Событие: 'request'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Излучается каждый раз при поступлении запроса. Обратите внимание, что может быть несколько запросов в сессии. См. Совместимость 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])[src]
-
callback<Функция>
Останавливает сервер от принятия новых подключений. См. net.Server.close().
Обратите внимание, что это не аналогично ограничению новых запросов, поскольку подключения HTTP/2 сохраняются. Для достижения аналогичного поведения плавного завершения работы, рассмотрите также использование http2session.close() на активных сессиях.
server.setTimeout([msecs][, callback])[src]
-
msecs<число> По умолчанию:120000(2 минуты) -
callback<Функция> - Возвращает: <Http2Server>
Используется для установки значения таймаута для запросов http2 сервера и устанавливает функцию обратного вызова, которая вызывается, когда на сервере Http2Server нет активности после msecs миллисекунд.
Указанный обратный вызов регистрируется как слушатель события 'timeout'.
В случае отсутствия функции обратного вызова будет выброшено новое исключение ERR_INVALID_CALLBACK.
Класс: Http2SecureServer
- Расширяет: <tls.Server>
Экземпляры Http2SecureServer создаются с помощью функции http2.createSecureServer(). Класс Http2SecureServer не экспортируется напрямую модулем http2.
Событие: 'checkContinue'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Если зарегистрирован слушатель 'request' или http2.createSecureServer() содержит функцию обратного вызова, событие 'checkContinue' излучается каждый раз, когда принимается запрос с HTTP-Expect: 100-continue. Если за этим событием не следят, сервер автоматически ответит со статусом 100 Continue соответственно.
Обработка этого события включает вызов response.writeContinue(), если клиент должен продолжить отправку тела запроса, или генерацию соответствующего HTTP-ответа (например, 400 Bad Request), если клиент не должен продолжать отправку тела запроса.
Обратите внимание, что при излучении и обработке этого события событие 'request' не будет излучено.
Событие: 'request'
-
request<http2.Http2ServerRequest> -
response<http2.Http2ServerResponse>
Выпускается каждый раз при поступлении запроса. Обратите внимание, что может быть несколько запросов в одной сессии. См. 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). Обработчик события получает сокет для обработки. Если для этого события не зарегистрирован обработчик, соединение прерывается. Таймаут может быть задан с помощью параметра 'unknownProtocolTimeout', переданного в http2.createSecureServer(). См. API совместимости.
server.close([callback])[src]
-
callback<Функция>
Останавливает сервер от принятия новых подключений. См. tls.Server.close().
Обратите внимание, что это не аналогично ограничению новых запросов, так как соединения HTTP/2 являются постоянными. Для достижения аналогичного поведения плавного завершения работы рассмотрите также использование http2session.close() для активных сессий.
server.setTimeout([msecs][, callback])[src]
-
msecs<число> По умолчанию:120000(2 минуты) -
callback<Функция> - Возвращает: <Http2SecureServer>
Используется для установки значения таймаута для запросов http2 secure сервера, и устанавливает функцию обратного вызова, которая вызывается, когда на Http2SecureServer нет активности после msecs миллисекунд.
Указанный обратный вызов регистрируется в качестве слушателя события 'timeout'.
В случае, если функция обратного вызова не была назначена, будет выброшено новое исключение ERR_INVALID_CALLBACK.
http2.createServer(options[, onRequestHandler])
-
options<Объект>-
maxDeflateDynamicTableSize<число> Устанавливает максимальный размер динамической таблицы для сжатия заголовков. По умолчанию:4Kib. -
maxSettings<число> Устанавливает максимальное количество записей настроек на одинSETTINGSкадр. Минимальное разрешённое значение:1. По умолчанию:32. -
maxSessionMemory<число> Устанавливает максимальный объём памяти, который разрешено использоватьHttp2Session. Значение выражается в мегабайтах, например,1равно 1 мегабайту. Минимальное разрешённое значение:1. Это лимит, основанный на квотах; существующиеHttp2Streamмогут превысить этот лимит, но новые экземплярыHttp2Streamбудут отклонены, пока этот лимит превышен. Текущее количествоHttp2Streamсессий, текущее использование памяти таблицами сжатия заголовков, текущие данные, ожидающие отправки, и неподтверждённыеPINGиSETTINGSкадры — всё это учитывается в текущем лимите. По умолчанию:10. -
maxHeaderListPairs<число> Устанавливает максимальное количество открытых, неподтверждённых пингов. По умолчанию:10. -
maxOutstandingPings<число> Устанавливает максимальный разрешённый размер сериализованного, сжатого блока заголовков. Попытки отправки заголовков, превышающих этот лимит, приведут к тому, что будет вызвано событие'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. -
unknownProtocolTimeout<число> Указывает таймаут в миллисекундах, который сервер должен ожидать, когда вызывается'unknownProtocol'. Если сокет не был уничтожен к этому времени, сервер уничтожит его. По умолчанию:10000.
-
-
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. -
maxSettings<число> Устанавливает максимальное количество записей настроек в кадреSETTINGS. Минимальное допустимое значение —1. По умолчанию:32. -
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. -
unknownProtocolTimeout<число> Указывает таймаут в миллисекундах, который сервер должен ожидать при возникновении события'unknownProtocol'. Если сокет не был уничтожен к этому времени, сервер уничтожит его. По умолчанию:10000.
-
-
onRequestHandler<Функция> См. API совместимости - Возвращает: <Сервер Http2Secure>
Возвращает экземпляр 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. -
maxSettings<число> Устанавливает максимальное количество записей настроек на один кадрSETTINGS. Минимальное допустимое значение1. По умолчанию:32. -
maxSessionMemory<число> Устанавливает максимальный объем памяти, который разрешено использоватьHttp2Session. Значение выражается в мегабайтах, например,1равно 1 мегабайту. Минимальное допустимое значение1. Это ограничение по кредиту, существующиеHttp2Streamмогут привести к превышению этого лимита, но новые экземплярыHttp2Streamбудут отклонены, пока этот лимит превышен. Текущее количествоHttp2Streamсессий, текущее использование памяти таблицами сжатия заголовков, текущие данные, ожидающие отправки, а также неподтвержденныеPINGиSETTINGSкадры учитываются в текущем лимите. По умолчанию:10. -
maxHeaderListPairs<число> Устанавливает максимальное количество заголовков. Минимальное значение1. По умолчанию:128. -
maxOutstandingPings<число> Устанавливает максимальное количество открытых, но неподтвержденных пингов. По умолчанию: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()могут быть предоставлены. -
unknownProtocolTimeout<число> Устанавливает тайм-аут в миллисекундах, который сервер должен ждать, когда будет испущено событие'unknownProtocol'. Если сокет не был уничтожен к этому времени, сервер уничтожит его. По умолчанию:10000.
-
-
listener<Функция> - Возвращает: <Клиентская сессия HTTP/2>
Возвращает экземпляр 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,:protocol,age,authorization,access-control-allow-credentials,access-control-max-age,access-control-request-method,content-encoding,content-language,content-length,content-location,content-md5,content-range,content-type,date,dnt,etag,expires,from,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. Нет значения по умолчанию, что подразумевает, по крайней мере теоретически, что вHttp2Sessionодновременно могут быть открыты 231-1 потоков. Минимальное значение — 0. Максимальное разрешённое значение — 231-1. -
maxHeaderListSize<число> Указывает максимальный размер (несжатых октетов) списка заголовков, который будет принят. Минимальное разрешённое значение — 0. Максимальное разрешённое значение — 232-1. По умолчанию:65535. -
enableConnectProtocol<логическое> Указывает,trueследует ли включать «Расширенный протокол подключения», определённый в RFC 8441. Это значение имеет смысл только если отправлено сервером. После включения настройкиenableConnectProtocolдля данногоHttp2Session, её нельзя отключить.
Все дополнительные свойства в объекте настроек игнорируются.
Использование 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 Server, в зависимости от места и времени возникновения ошибки.
Внутренние ошибки возникают, когда сессия HTTP/2 завершается неожиданно. Они будут сообщаться через событие 'error' в объектах Http2Session или HTTP/2 Server.
Ошибки протокола возникают, когда нарушаются различные ограничения протокола HTTP/2. Они будут сообщаться либо с помощью синхронной throw или через событие 'error' в объектах Http2Stream, Http2Session или HTTP/2 Server, в зависимости от места и времени возникновения ошибки.
Обработка недопустимых символов в именах и значениях заголовков
Реализация HTTP/2 применяет более строгую обработку недопустимых символов в именах и значениях заголовков HTTP, чем реализация HTTP/1.
Имена полей заголовков нечувствительны к регистру и передаются по сети строго как строки в нижнем регистре. API Node.js позволяет устанавливать имена заголовков в виде строк смешанного регистра (например, Content-Type), но при передаче они будут преобразовываться в нижний регистр (например, content-type).
Имена полей заголовков должны содержать один или несколько следующих ASCII-символов: a-z, A-Z, 0-9, !, #, $, %, &, ', *, +, -, ., ^, _, ` (обратная ковычка), |, и ~.
Использование недопустимых символов в имени поля заголовка приведёт к закрытию потока с сообщением об ошибке протокола.
Значения полей заголовков обрабатываются более лояльно, но не должны содержать символы перевода строки или возврата каретки и должны быть ограничены символами 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 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');
Расширенный протокол подключения
RFC 8441 определяет расширение «Расширенный протокол подключения» для HTTP/2, которое может использоваться для инициализации использования Http2Stream с использованием метода CONNECT как туннеля для других протоколов связи (таких как WebSockets).
Использование Расширенного протокола подключения активируется серверами HTTP/2 с помощью настройки enableConnectProtocol:
const http2 = require('http2');
const settings = { enableConnectProtocol: true };
const server = http2.createServer({ settings });
После получения клиентом рамки SETTINGS от сервера, указывающей, что расширенное подключение может быть использовано, он может отправлять запросы CONNECT , которые используют псевдозаголовок HTTP/2 ':protocol':
const http2 = require('http2');
const client = http2.connect('http://localhost:8080');
client.on('remoteSettings', (settings) => {
if (settings.enableConnectProtocol) {
const req = client.request({ ':method': 'CONNECT', ':protocol': 'foo' });
// ...
}
});
API совместимости
API совместимости призвано обеспечить аналогичный опыт разработчика при использовании HTTP/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.authority
Псевдополе заголовка запроса authority. Также может быть получено через req.headers[':authority'].
request.destroy([error])
-
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.scheme
Псевдополе заголовка схемы запроса, указывающее схему целевого URL.
request.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function> - Возвращает: <http2.Http2ServerRequest>
Устанавливает значение таймаута для Http2Stream на msecs.
Если указана функция обратного вызова, она добавляется в качестве слушателя события 'timeout' для объекта ответа.
Если к запросу, ответу или серверу не добавлен слушатель 'timeout', то объекты Http2Stream уничтожаются при истечении таймаута. Если обработчик назначен для событий запроса, ответа или сервера 'timeout', тайм-аут сокетов необходимо обрабатывать явно.
request.socket
Возвращает объект Proxy, который действует как net.Socket (или tls.TLSSocket) но применяет геттеры, сеттеры и методы на основе логики HTTP/2.
Свойства destroyed, readable, и writable извлекаются и устанавливаются на request.stream.
Методы destroy, emit, end, on и once вызываются на request.stream.
Метод setTimeout вызывается на request.stream.session.
pause, read, resume, и write выбросят ошибку с кодом ERR_HTTP2_NO_SOCKET_MANIPULATION . См. Http2Session и сокеты для получения дополнительной информации.
Все остальные взаимодействия будут направлены непосредственно в сокет. При поддержке TLS используйте request.socket.getPeerCertificate() для получения данных аутентификации клиента.
request.stream
Объект 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'.
Ответ наследуется от потока Stream и дополнительно реализует следующее:
Событие: '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
Истина, если заголовки были отправлены, ложь в противном случае (только чтение).
response.removeHeader(name)
-
name<строка>
Удаляет заголовок, помещенный в очередь для неявной отправки.
response.removeHeader('Content-Encoding');
response.sendDate
Если значение истинно, заголовок Date будет автоматически сгенерирован и отправлен в ответе, если он еще не присутствует в заголовках. По умолчанию значение истинно.
Это следует отключать только для тестирования; 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])
-
msecs<число> -
callback<Функция> - Возвращает: <http2.Http2СерверныйОтвет>
Устанавливает значение таймаута для Http2Stream на msecs. Если указана функция обратного вызова, она добавляется в качестве обработчика события 'timeout' на объекте ответа.
Если обработчик события 'timeout' не добавлен в запрос, ответ или сервер, сокеты, которые превысили время ожидания, уничтожаются. Если обработчик назначен для запроса, ответа или событий 'timeout' сервера, сокеты, превысившие время ожидания, необходимо обрабатывать явно.
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
Объект 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])
-
statusCode<число> -
statusMessage<строка> -
headers<Объект> - Возвращает: <http2.Http2ServerResponse>
Отправляет заголовок ответа на запрос. Код состояния — это трехзначный код состояния HTTP, например, 404. Последний аргумент, headers, — это заголовки ответа.
Возвращает ссылку на Http2ServerResponse, чтобы вызовы можно было объединить.
Для совместимости с HTTP/1 может быть передан удобочитаемый statusMessage в качестве второго аргумента. Однако, поскольку statusMessage не имеет значения в HTTP/2, этот аргумент не повлияет, и будет выведено предупреждение процесса.
const body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain' });
Обратите внимание, что длина содержимого указывается в байтах, а не в символах. API Buffer.byteLength() можно использовать для определения количества байтов в заданной кодировке. При отправке сообщений Node.js не проверяет, равны ли длина содержимого и длина передаваемого тела или нет. Однако при получении сообщений Node.js будет автоматически отклонять сообщения, когда длина содержимого не совпадает с фактическим размером полезной нагрузки.
Этот метод может быть вызван не более одного раза для сообщения до вызова 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<number> Количество байтов, полученных для этогоHttp2Session. -
bytesWritten<number> Количество байтов, отправленных для этогоHttp2Session. -
framesReceived<number> Количество полученных HTTP/2 кадровHttp2Session. -
framesSent<number> Количество отправленных HTTP/2 кадровHttp2Session. -
maxConcurrentStreams<number> Максимальное количество потоков, одновременно открытых за время жизниHttp2Session. -
pingRTT<number> Количество миллисекунд, прошедших с момента передачи кадраPINGи получения его подтверждения. Присутствует только если кадрPINGбыл отправлен поHttp2Session. -
streamAverageDuration<number> Среднее время (в миллисекундах) для всехHttp2Streamэкземпляров. -
streamCount<number> Количество экземпляровHttp2StreamобработаноHttp2Session. -
type<string> Либо'server'или'client'для идентификации типаHttp2Session.
© 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-v10.x/docs/api/http2.html