Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node:http2) Implement HTTP2 server support #14286

Merged
merged 151 commits into from
Oct 15, 2024
Merged

Conversation

cirospaciari
Copy link
Collaborator

@cirospaciari cirospaciari commented Oct 2, 2024

What does this PR do?

Major Client compatibility fixes + Server implementation

Fix: #8823
Fix: #14249
Fix: #8549
Fix: #9228

Notes

Push (not supported in most browsers):

  • ServerHttp2Stream.pushStream (temporary reverted)
  • ServerHttp2Stream.pushAllowed (mocked always return false)

HTTP1 compatibility aka ALPN negotiation (blocked on http module implementation):

  • event 'unknownProtocol'
  • options.allowHTTP1
  • options.unknownProtocolTimeout

WebSocket Proxing using RFC8441 (disable by default on node.js);

ALTSVC using RFC7838:

In-Progress:

  • ServerHttp2Stream.respondWithFile
  • ServerHttp2Stream.respondWithFD
  • Event 'frameError' (temporary reverted)
  • Event order
  • abort behavior
  • Http2ServerResponse.writeEarlyHints (missing validations)
  • Http2Server Event: 'timeout'
  • Http2Server Event: checkContinue
  • Http2Server.updateSettings
  • Http2Stream.bufferSize (must include native backpressure and corked values too)

Progress:

Class: ServerHttp2Session

  • serverhttp2session.altsvc(alt, originOrStream)
  • serverhttp2session.origin(...origins)

Class: ClientHttp2Session

Class: Http2Stream

  • Event: 'aborted'
  • Event: 'close'
  • Event: 'error'
  • Event: 'frameError'
  • Event: 'ready'
  • Event: 'timeout'
  • Event: 'trailers'
  • Event: 'wantTrailers'
  • http2stream.aborted
  • http2stream.bufferSize
  • http2stream.close(code[, callback])
  • http2stream.closed
  • http2stream.destroyed
  • http2stream.endAfterHeaders
  • http2stream.id
  • http2stream.pending
  • http2stream.priority(options)
  • http2stream.rstCode
  • http2stream.sentHeaders
  • http2stream.sentInfoHeaders
  • http2stream.sentTrailers
  • http2stream.session
  • http2stream.setTimeout(msecs, callback)
  • http2stream.state
  • http2stream.sendTrailers(headers)

Class: ClientHttp2Stream

  • Event: 'continue'
  • Event: 'headers'
  • Event: 'push'
  • Event: 'response'

Class: ServerHttp2Stream

  • http2stream.additionalHeaders(headers)
  • http2stream.headersSent
  • http2stream.pushAllowed
  • http2stream.pushStream(headers[, options], callback)
  • http2stream.respond([headers[, options]])
  • http2stream.respondWithFD(fd[, headers[, options]])
  • http2stream.respondWithFile(path[, headers[, options]])

Class: Http2Server

  • Event: 'checkContinue'
  • Event: 'connection'
  • Event: 'request'
  • Event: 'session'
  • Event: 'sessionError'
  • Event: 'stream'
  • Event: 'timeout'
  • server.close([callback])
  • serverSymbol.asyncDispose
  • server.setTimeout([msecs][, callback])
  • server.timeout
  • server.updateSettings([settings])

Class: Http2SecureServer

  • Event: 'checkContinue'
  • Event: 'connection'
  • Event: 'request'
  • Event: 'session'
  • Event: 'sessionError'
  • Event: 'stream'
  • Event: 'timeout'
  • Event: 'unknownProtocol'
  • server.close([callback])
  • server.setTimeout([msecs][, callback])
  • server.timeout
  • server.updateSettings([settings])

Module:

  • http2.createServer([options][, onRequestHandler])
  • http2.createSecureServer(options[, onRequestHandler])
  • http2.connect(authority[, options][, listener])
  • http2.constants
  • http2.getDefaultSettings()
  • http2.getPackedSettings([settings])
  • http2.getUnpackedSettings(buf)
  • http2.sensitiveHeaders

Compatibility API

Class: http2.Http2ServerRequest

  • Event: 'aborted'
  • Event: 'close'
  • request.aborted
  • request.authority
  • request.complete
  • request.connection
  • request.destroy([error])
  • request.headers
  • request.httpVersion
  • request.method
  • request.rawHeaders
  • request.rawTrailers
  • request.scheme
  • request.setTimeout(msecs, callback)
  • request.socket
  • request.stream
  • request.trailers
  • request.url

Class: http2.Http2ServerResponse

  • Event: 'close'
  • Event: 'finish'
  • response.addTrailers(headers)
  • response.connection
  • response.createPushResponse(headers, callback)
  • response.end([data[, encoding]][, callback])
  • response.finished
  • response.getHeader(name)
  • response.getHeaderNames()
  • response.getHeaders()
  • response.hasHeader(name)
  • response.headersSent
  • response.removeHeader(name)
  • response.req
  • response.sendDate
  • response.setHeader(name, value)
  • response.setTimeout(msecs[, callback])
  • response.socket
  • response.statusCode
  • response.statusMessage
  • response.stream
  • response.writableEnded
  • response.write(chunk[, encoding][, callback])
  • response.writeContinue()
  • response.writeEarlyHints(hints)
  • response.writeHead(statusCode[, statusMessage][, headers])
  • Documentation or TypeScript types (it's okay to leave the rest blank in this case)
  • Code changes

How did you verify your code works?

@robobun
Copy link

robobun commented Oct 2, 2024

@cirospaciari, your commit b1582f4 has 9 failures in #4884:

  • test/bundler/bundler_compile.test.ts - 1 failing on 🐧 20.04 x64-baseline
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 22.04 x64
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 20.04 x64
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 20.04 x64-baseline
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 22.04 x64-baseline
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 20.04 aarch64
  • test/cli/install/bun-install.test.ts - 1 failing on 🐧 22.04 aarch64
  • test/cli/run/require-cache.test.ts - 1 failing on 🪟 x64-baseline
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🍎 13 aarch64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🍎 14 aarch64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🪟 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🪟 x64-baseline
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 22.04 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 12 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 20.04 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🍎 14 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🍎 13 x64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 12 x64-baseline
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 20.04 x64-baseline
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 22.04 x64-baseline
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 20.04 aarch64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 22.04 aarch64
  • test/js/node/test/parallel/http2-server-rst-before-respond.test.js - 1 failing on 🐧 12 aarch64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🍎 13 aarch64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🍎 14 aarch64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 20.04 x64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 12 x64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 22.04 x64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 20.04 x64-baseline
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 22.04 x64-baseline
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 12 x64-baseline
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🍎 14 x64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🍎 13 x64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 22.04 aarch64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 12 aarch64
  • test/js/node/test/parallel/http2-large-write-close.test.js - 1 failing on 🐧 20.04 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🍎 13 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🍎 14 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🪟 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🪟 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 22.04 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 12 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 20.04 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🍎 14 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🍎 13 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 12 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 20.04 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 22.04 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 20.04 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 22.04 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints.test.js - timeout on 🐧 12 aarch64
  • test/cli/hot/watch.test.ts - 1 failing on 🪟 x64-baseline
  • test/cli/hot/watch.test.ts - 1 failing on 🪟 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🍎 14 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🪟 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🍎 13 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🪟 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 20.04 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 12 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 22.04 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 20.04 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 22.04 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 12 x64-baseline
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🍎 14 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 22.04 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 12 aarch64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🍎 13 x64
  • test/js/node/test/parallel/http2-compat-write-early-hints-invalid-argument-type.test.js - 1 failing on 🐧 20.04 aarch64
  • test/cli/watch/watch.test.ts - 2 failing on 🪟 x64
  • test/cli/watch/watch.test.ts - 2 failing on 🪟 x64-baseline
  • @cirospaciari cirospaciari force-pushed the ciro/http2-server branch 4 times, most recently from 13d248c to 4f6b936 Compare October 8, 2024 18:45
    @cirospaciari cirospaciari changed the title WIP: feat(node:http2) Implement HTTP2 server support eat(node:http2) Implement HTTP2 server support Oct 11, 2024
    @cirospaciari cirospaciari marked this pull request as ready for review October 11, 2024 21:48
    @cirospaciari cirospaciari changed the title eat(node:http2) Implement HTTP2 server support feat(node:http2) Implement HTTP2 server support Oct 11, 2024
    @yashpurplesectors
    Copy link

    please merge this. waiting with fingers crossed 🤞

    @pablojimpas
    Copy link

    I tested this PR against my demo repository to reproduce #14249 last Friday (oct 11) using the prebuilt binary with bunx bun-pr 14286. The issue seemed to be resolved, but I've tested again right now and the error shows up once again.

    These are the two binaries I've tested:

    -rwxr-xr-x 1  97M oct 14 15:44 bun-b30e238d9be315441a07e3ebab8c9e6f6de55037-pr14286
    -rwxr-xr-x 1  96M oct 11 07:55 bun-e16c1fcc052a188724fb3a019bada915077c4fa3-pr14286

    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    src/js/node/http2.ts Outdated Show resolved Hide resolved
    @aayushpurplesectors
    Copy link

    @cirospaciari: everything seems to be working well when I am using bun run but get the errors as shown in #14133 and #7630 when I run the compiled lib using bun build

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    None yet
    Projects
    None yet
    6 participants