简体   繁体   English

如果客户端关闭会话,nodejs v8.11.3在带有TLS的http2中中止

[英]nodejs v8.11.3 aborts in http2 with TLS if client closes session

I am hitting an issue with nodejs v8.11.3. 我遇到了nodejs v8.11.3的问题。 I am using http2 with TLS (https) and the server aborts when the client has closed the session. 我将HTTP2与TLS(https)一起使用,并且当客户端关闭会话时服务器中止。 Here is the error: 这是错误:

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)

What confuses me is why does the server still emit a GOAWAY frame although the socket already was closed? 令我困惑的是,尽管套接字已经关闭,为什么服务器仍然发出GOAWAY帧?

Does anybody know some quirks to avoid the problem? 有人知道一些怪癖可以避免此问题吗?

Note: the problem does not always happen, but is reproducible as part of a more complex test scenario. 注意:问题并非总是会发生,但可以作为更复杂的测试方案的一部分重现。

QUIRK SOLUTION 查询解决方案

See answer. 查看答案。

I made a quirk to circumvent the problem by monkeypatching "goaway" and introduction an explicit check if the socket has been closed. 我做了一个古怪的事情,通过猴子补丁“ goaway”来解决这个问题,并引入了一个明确的检查套接字是否已关闭的方法。 TypeScript code: 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;
  }
}

Now when handling a new stream, you call monkeyPatch(stream.session) . 现在,当处理新的流时,您可以调用monkeyPatch(stream.session)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM