nodejs v8.11.3 прерывается в http2 с TLS, если клиент закрывает сессию - PullRequest
0 голосов
/ 17 сентября 2018

У меня проблема с nodejs v8.11.3.Я использую http2 с TLS (https), и сервер прерывает работу, когда клиент закрыл сеанс.Вот ошибка:

HTTP2 31334: Http2Session server: socket closed
HTTP2 31334: Http2Session server: marking session closed
HTTP2 31334: Http2Session server: submitting goaway
node[31334]: ../src/tls_wrap.cc:604:virtual int node::TLSWrap::DoWrite(node::WriteWrap*, uv_buf_t*, size_t, uv_stream_t*): Assertion `(ssl_) != (nullptr)' failed.
 1: node::Abort() [node]
 2: 0x8c25db [node]
 3: node::TLSWrap::DoWrite(node::WriteWrap*, uv_buf_t*, unsigned long, uv_stream_s*) [node]
 4: node::http2::Http2Session::SendPendingData() [node]
 5: 0x90e769 [node]
 6: node::Environment::RunAndClearNativeImmediates() [node]
 7: node::Environment::CheckImmediate(uv_check_s*) [node]
 8: 0x141a4ac [node]
 9: uv_run [node]
10: node::Start(uv_loop_s*, int, char const* const*, int, char const* const*) [node]
11: node::Start(int, char**) [node]
12: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
13: 0x89b1b1 [node]
Aborted (core dumped)

Что меня смущает, так это то, почему сервер по-прежнему генерирует кадр GOAWAY, хотя сокет уже был закрыт?

Кто-нибудь знает некоторые причуды, чтобы избежать проблемы?

Примечание: проблема не всегда возникает, но ее можно воспроизвести в рамках более сложного сценария тестирования.

БЫСТРОЕ РЕШЕНИЕ

См. Ответ.

1 Ответ

0 голосов
/ 18 сентября 2018

Я сделал причуду, чтобы обойти проблему, с помощью обезьяньего патча "goaway" и введя явную проверку, был ли сокет закрыт. Код TypeScript:

const GOAWAY = Symbol();

interface ExtServerHttp2Session extends http2.ServerHttp2Session {
  [GOAWAY]?: (code?: number, lastStreamID?: number, opaqueData?: Buffer | DataView /*| TypedArray*/) => void;
}

function patchedGoaway(
  this: ExtServerHttp2Session,
  code?: number,
  lastStreamID?: number,
  opaqueData?: Buffer | DataView /*| TypedArray*/
): void {
  if (!this.closed) {
    this[GOAWAY]!(code, lastStreamID, opaqueData);
  }
}

function monkeyPatch(session: http2.Http2Session) {
  const extSession = session as ExtServerHttp2Session;
  if (!extSession[GOAWAY]) {
    extSession[GOAWAY] = extSession.goaway;
    extSession.goaway = patchedGoaway;
  }
}

Теперь при обработке нового потока вы вызываете monkeyPatch(stream.session).

...