Socket
Socket
Sign inDemoInstall

http2-wrapper

Package Overview
Dependencies
Maintainers
2
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http2-wrapper - npm Package Compare versions

Comparing version 2.0.9 to 2.1.0

18

index.d.ts

@@ -23,2 +23,3 @@ // See https://github.com/facebook/jest/issues/2549

};
resolveProtocol?: ResolveProtocolFunction;
}

@@ -112,5 +113,20 @@

export type ResolveProtocolResult = {
alpnProtocol: string;
socket?: tls.TLSSocket;
timeout?: boolean;
};
export type ResolveProtocolFunction = (options: AutoRequestOptions) => Promise<ResolveProtocolResult>;
type Promisable<T> = T | Promise<T>;
export type ResolveProtocolConnectFunction = (options: tls.ConnectionOptions, callback: () => void) => Promisable<tls.TLSSocket>;
export const request: RequestFunction<http.ClientRequest>;
export const get: RequestFunction<http.ClientRequest>;
export const auto: RequestFunction<Promise<http.ClientRequest>, AutoRequestOptions> & {protocolCache: QuickLRU<string, string>};
export const auto: RequestFunction<Promise<http.ClientRequest>, AutoRequestOptions> & {
protocolCache: QuickLRU<string, string>;
resolveProtocol: ResolveProtocolFunction;
createResolveProtocol: (cache: Map<string, string>, queue: Map<string, Promise<ResolveProtocolResult>>, connect?: ResolveProtocolConnectFunction) => ResolveProtocolFunction;
};

@@ -117,0 +133,0 @@ export {

4

package.json
{
"name": "http2-wrapper",
"version": "2.0.9",
"version": "2.1.0",
"description": "HTTP2 client, just with the familiar `https` API",

@@ -35,3 +35,3 @@ "main": "source",

"quick-lru": "^5.1.1",
"resolve-alpn": "^1.1.2"
"resolve-alpn": "^1.2.0"
},

@@ -38,0 +38,0 @@ "devDependencies": {

@@ -165,2 +165,26 @@ # http2-wrapper

### http2.auto.createResolveProtocol(cache, queue, connect)
#### cache
Type: `Map<string, string>`
This is the store where cached ALPN protocols are put into.
#### queue
Type: `Map<string, Promise>`
This is the store that contains pending ALPN negotiation promises.
#### connect
Type: `(options, callback) => TLSSocket | Promise<TLSSocket>`
See https://github.com/szmarczak/resolve-alpn#connect
### http2.auto.resolveProtocol(options)
Returns a `Promise<{alpnProtocol: string}>`.
### http2.request(url, options, callback)

@@ -357,2 +381,60 @@

**Note:** If you use the `http2.auto` function, the real IP address will leak. `http2wrapper` is not aware of the context. It will create a connection to the end server using your real IP address to get the ALPN protocol. Then it will create another connection using proxy. To migitate this, you need to pass a custom `resolveProtocol` function as an option:
```js
const resolveAlpnProxy = new URL('https://username:password@localhost:8000');
const connect = async (options, callback) => new Promise((resolve, reject) => {
const host = `${options.host}:${options.port}`;
(async () => {
try {
const request = await http2.auto(resolveAlpnProxy, {
method: 'CONNECT',
headers: {
host
},
path: host,
// For demo purposes only!
rejectUnauthorized: false,
});
request.end();
request.once('connect', (response, socket, head) => {
if (head.length > 0) {
reject(new Error(`Unexpected data before CONNECT tunnel: ${head.length} bytes`));
socket.destroy();
return;
}
const tlsSocket = tls.connect({
...options,
socket
}, callback);
resolve(tlsSocket);
});
} catch (error) {
reject(error);
}
})();
});
// This is required to prevent leaking real IP address on ALPN negotiation
const resolveProtocol = http2.auto.createResolveProtocol(new Map(), new Map(), connect);
const request = await http2.auto('https://httpbin.org/anything', {
agent: {…},
resolveProtocol
}, response => {
// Read the response here
});
request.end();
```
See [`unknown-over-unknown.js`](examples/proxies/unknown-over-unknown.js) to learn more.
## Mirroring another server

@@ -359,0 +441,0 @@

@@ -57,38 +57,42 @@ 'use strict';

const resolveProtocol = async options => {
const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`;
const createResolveProtocol = (cache, queue = new Map(), connect = undefined) => {
return async options => {
const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`;
if (!cache.has(name)) {
if (queue.has(name)) {
const result = await queue.get(name);
return {alpnProtocol: result.alpnProtocol};
}
if (!cache.has(name)) {
if (queue.has(name)) {
const result = await queue.get(name);
return {alpnProtocol: result.alpnProtocol};
}
const {path} = options;
options.path = options.socketPath;
const {path} = options;
options.path = options.socketPath;
const resultPromise = resolveALPN(options);
queue.set(name, resultPromise);
const resultPromise = resolveALPN(options, connect);
queue.set(name, resultPromise);
try {
const result = await resultPromise;
try {
const result = await resultPromise;
cache.set(name, result.alpnProtocol);
queue.delete(name);
cache.set(name, result.alpnProtocol);
queue.delete(name);
options.path = path;
options.path = path;
return result;
} catch (error) {
queue.delete(name);
return result;
} catch (error) {
queue.delete(name);
options.path = path;
options.path = path;
throw error;
throw error;
}
}
}
return {alpnProtocol: cache.get(name)};
return {alpnProtocol: cache.get(name)};
};
};
const defaultResolveProtocol = createResolveProtocol(cache, queue);
module.exports = async (input, options, callback) => {

@@ -127,2 +131,4 @@ if (typeof input === 'string') {

const resolveProtocol = options.resolveProtocol || defaultResolveProtocol;
// Note: We don't support `h2session` here

@@ -200,2 +206,3 @@

module.exports.protocolCache = cache;
module.exports.resolveProtocol = resolveProtocol;
module.exports.resolveProtocol = defaultResolveProtocol;
module.exports.createResolveProtocol = createResolveProtocol;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc