Skip to content

feat(http): add HTTP2 support; (#7150)#1

Open
MitchLewis930 wants to merge 1 commit intopr_021_beforefrom
pr_021_after
Open

feat(http): add HTTP2 support; (#7150)#1
MitchLewis930 wants to merge 1 commit intopr_021_beforefrom
pr_021_after

Conversation

@MitchLewis930
Copy link

PR_021

@MitchLewis930 MitchLewis930 requested a review from Copilot January 31, 2026 00:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds experimental HTTP/2 support to the Axios HTTP adapter. The implementation introduces a httpVersion configuration option (1 or 2) and http2Options for passing additional session parameters, with sessions being reused across requests to the same authority.

Changes:

  • Added HTTP/2 transport layer with session management and connection reuse
  • Refactored test helper utilities to support both HTTP/1 and HTTP/2 server creation
  • Updated adapter error handling to support HTTP/2-specific abort mechanisms

Reviewed changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
lib/adapters/http.js Implements HTTP/2 transport, session management, and protocol version validation
test/helpers/server.js Adds HTTP/2 server creation capability with certificate generation and session tracking
test/unit/adapters/http.js Adds comprehensive HTTP/2 test suite and updates existing tests to use refactored helpers
index.d.cts Adds TypeScript definitions for httpVersion and http2Options configuration
package.json Adds selfsigned package dependency for certificate generation
README.md Documents the new HTTP/2 feature with usage examples

@@ -1,5 +1,4 @@
'use strict';

import { connect, constants } from 'http2';
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'use strict' directive was removed from the beginning of the file. Since this module uses ES6 imports and is likely treated as a module, strict mode is automatically applied. However, the project's coding guidelines explicitly require "'use strict';" at the top of files. Restore the 'use strict' directive at line 1 to maintain consistency with the project's conventions.

Copilot uses AI. Check for mistakes.
options
];

entries ? this.sessions[authority].push(entry) : authoritySessions = this.sessions[authority] = [entry];
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ternary operator combines assignment and mutation in a confusing way with the chained assignment authoritySessions = this.sessions[authority] = [entry]. Split this into two clear statements: one to check if entries exist and push, another to initialize the array if it doesn't exist.

Suggested change
entries ? this.sessions[authority].push(entry) : authoritySessions = this.sessions[authority] = [entry];
if (entries) {
this.sessions[authority].push(entry);
} else {
const newEntries = [entry];
this.sessions[authority] = newEntries;
authoritySessions = newEntries;
}

Copilot uses AI. Check for mistakes.

export const setTimeoutAsync = (ms) => new Promise(resolve=> setTimeout(resolve, ms));

const certificate = selfsigned.generate(null, { keySize: 2048 });
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The certificate is generated at module load time and reused for all tests. While this improves performance, using a single certificate for all test servers on different ports may cause issues if tests run in parallel or need isolated certificates. Consider generating certificates per server instance if test isolation becomes a concern.

Copilot uses AI. Check for mistakes.

const http2Transport = {
request(options, cb) {
const authority = options.protocol + '//' + options.hostname + ':' + (options.port || 80);
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default port is hardcoded to 80, but HTTP/2 is typically used over HTTPS (port 443). For HTTPS requests, this will construct an incorrect authority string. Use options.port || (options.protocol === 'https:' ? 443 : 80) to set the appropriate default port based on the protocol.

Suggested change
const authority = options.protocol + '//' + options.hostname + ':' + (options.port || 80);
const defaultPort = options.port || (options.protocol === 'https:' ? 443 : 80);
const authority = options.protocol + '//' + options.hostname + ':' + defaultPort;

Copilot uses AI. Check for mistakes.
}

utils.forEach(headers, (header, name) => {
name.charAt(0) !== ':' && (http2Headers[name] = header);
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using charAt(0) followed by a side effect in a boolean expression is unclear. Refactor to an explicit if statement: if (name.charAt(0) !== ':') { http2Headers[name] = header; } for better readability.

Suggested change
name.charAt(0) !== ':' && (http2Headers[name] = header);
if (name.charAt(0) !== ':') {
http2Headers[name] = header;
}

Copilot uses AI. Check for mistakes.
@@ -705,7 +846,8 @@ export default isHttpAdapterSupported && function httpAdapter(config) {

data.pipe(req);
} else {
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic splits writing data and ending the request into two separate calls. For HTTP/2, if data is nullish, req.write() is skipped but req.end() is still called. Consider clarifying the intent by adding a comment explaining why this pattern differs from the previous req.end(data) approach, especially since HTTP/2 streams may have different behavior.

Suggested change
} else {
} else {
// For HTTP/1.1 we could call `req.end(data)`, but Node's HTTP/2 `ClientHttp2Stream`
// does not support passing the payload to `end()` in the same way. Keeping the write
// and end calls separate ensures consistent behavior across HTTP/1.x and HTTP/2,
// and still correctly terminates the stream when `data` is null or undefined.

Copilot uses AI. Check for mistakes.
@@ -2075,6 +1997,8 @@ describe('supports http with nodejs', function () {
});

describe('Rate limit', function () {
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout is increased to 30 seconds for the 'Rate limit' test suite, which is significantly higher than typical test timeouts. Consider adding a comment explaining why such a long timeout is necessary for these specific tests (e.g., testing rate limiting over 10 seconds requires additional buffer time).

Suggested change
describe('Rate limit', function () {
describe('Rate limit', function () {
// Increased timeout: these tests enforce ~10s rate limiting and need extra buffer for slow/CI environments

Copilot uses AI. Check for mistakes.

describe('request aborting', function() {
it('should be able to abort the response stream', async function () {
//this.timeout(5000);
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commented-out timeout configuration should either be removed or uncommented with a clear explanation of why it's needed. Leaving commented code without context reduces maintainability.

Suggested change
//this.timeout(5000);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants