feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

22
api.hyungi.net/node_modules/pac-proxy-agent/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

27
api.hyungi.net/node_modules/pac-proxy-agent/README.md generated vendored Normal file
View File

@@ -0,0 +1,27 @@
pac-proxy-agent
===============
### A [PAC file][pac-wikipedia] proxy `http.Agent` implementation for HTTP and HTTPS
This module provides an `http.Agent` implementation that retreives the specified
[PAC proxy file][pac-wikipedia] and uses it to resolve which HTTP, HTTPS, or
SOCKS proxy, or if a direct connection should be used to connect to the
HTTP endpoint.
It is designed to be be used with the built-in `http` and `https` modules.
Example
-------
```ts
import * as http from 'http';
import { PacProxyAgent } from 'pac-proxy-agent';
const agent = new PacProxyAgent('pac+https://cloudup.com/ceGH2yZ0Bjp+');
http.get('http://nodejs.org/api/', { agent }, (res) => {
console.log('"response" event!', res.headers);
res.pipe(process.stdout);
});
```
[pac-wikipedia]: http://wikipedia.org/wiki/Proxy_auto-config

View File

@@ -0,0 +1,60 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as net from 'net';
import * as http from 'http';
import { Readable } from 'stream';
import { URL } from 'url';
import { Agent, AgentConnectOpts } from 'agent-base';
import type { HttpProxyAgentOptions } from 'http-proxy-agent';
import type { HttpsProxyAgentOptions } from 'https-proxy-agent';
import type { SocksProxyAgentOptions } from 'socks-proxy-agent';
import { protocols as gProtocols, ProtocolOpts as GetUriOptions } from 'get-uri';
import { FindProxyForURL, PacResolverOptions } from 'pac-resolver';
type Protocols = keyof typeof gProtocols;
type Protocol<T> = T extends `pac+${infer P}:${infer _}` ? P : T extends `${infer P}:${infer _}` ? P : never;
export type PacProxyAgentOptions<T> = http.AgentOptions & PacResolverOptions & GetUriOptions<`${Protocol<T>}:`> & HttpProxyAgentOptions<''> & HttpsProxyAgentOptions<''> & SocksProxyAgentOptions & {
fallbackToDirect?: boolean;
};
/**
* The `PacProxyAgent` class.
*
* A few different "protocol" modes are supported (supported protocols are
* backed by the `get-uri` module):
*
* - "pac+data", "data" - refers to an embedded "data:" URI
* - "pac+file", "file" - refers to a local file
* - "pac+ftp", "ftp" - refers to a file located on an FTP server
* - "pac+http", "http" - refers to an HTTP endpoint
* - "pac+https", "https" - refers to an HTTPS endpoint
*/
export declare class PacProxyAgent<Uri extends string> extends Agent {
static readonly protocols: `pac+${Protocols}`[];
uri: URL;
opts: PacProxyAgentOptions<Uri>;
cache?: Readable;
resolver?: FindProxyForURL;
resolverHash: string;
resolverPromise?: Promise<FindProxyForURL>;
constructor(uri: Uri | URL, opts?: PacProxyAgentOptions<Uri>);
private clearResolverPromise;
/**
* Loads the PAC proxy file from the source if necessary, and returns
* a generated `FindProxyForURL()` resolver function to use.
*/
getResolver(): Promise<FindProxyForURL>;
private loadResolver;
/**
* Loads the contents of the PAC proxy file.
*
* @api private
*/
private loadPacFile;
/**
* Called when the node-core HTTP client library is creating a new HTTP request.
*/
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<http.Agent | net.Socket>;
}
export {};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAY,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAEN,SAAS,IAAI,UAAU,EACvB,YAAY,IAAI,aAAa,EAC7B,MAAM,SAAS,CAAC;AACjB,OAAO,EAEN,eAAe,EACf,kBAAkB,EAClB,MAAM,cAAc,CAAC;AAuBtB,KAAK,SAAS,GAAG,MAAM,OAAO,UAAU,CAAC;AAGzC,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GACrD,CAAC,GAEH,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GAC/B,CAAC,GACD,KAAK,CAAC;AAET,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,GACtD,kBAAkB,GAClB,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAChC,qBAAqB,CAAC,EAAE,CAAC,GACzB,sBAAsB,CAAC,EAAE,CAAC,GAC1B,sBAAsB,GAAG;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa,CAAC,GAAG,SAAS,MAAM,CAAE,SAAQ,KAAK;IAC3D,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,SAAS,EAAE,EAAE,CAM7C;IAEF,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;gBAE/B,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC;IAsB5D,OAAO,CAAC,oBAAoB,CAE1B;IAEF;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;YAWzB,YAAY;IAwC1B;;;;OAIG;YACW,WAAW;IAazB;;OAEG;IACG,OAAO,CACZ,GAAG,EAAE,IAAI,CAAC,aAAa,EACvB,IAAI,EAAE,gBAAgB,GACpB,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;CA2GnC"}

View File

@@ -0,0 +1,238 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PacProxyAgent = void 0;
const net = __importStar(require("net"));
const tls = __importStar(require("tls"));
const crypto = __importStar(require("crypto"));
const events_1 = require("events");
const debug_1 = __importDefault(require("debug"));
const url_1 = require("url");
const agent_base_1 = require("agent-base");
const get_uri_1 = require("get-uri");
const pac_resolver_1 = require("pac-resolver");
const quickjs_emscripten_1 = require("@tootallnate/quickjs-emscripten");
const debug = (0, debug_1.default)('pac-proxy-agent');
const setServernameFromNonIpHost = (options) => {
if (options.servername === undefined &&
options.host &&
!net.isIP(options.host)) {
return {
...options,
servername: options.host,
};
}
return options;
};
/**
* The `PacProxyAgent` class.
*
* A few different "protocol" modes are supported (supported protocols are
* backed by the `get-uri` module):
*
* - "pac+data", "data" - refers to an embedded "data:" URI
* - "pac+file", "file" - refers to a local file
* - "pac+ftp", "ftp" - refers to a file located on an FTP server
* - "pac+http", "http" - refers to an HTTP endpoint
* - "pac+https", "https" - refers to an HTTPS endpoint
*/
class PacProxyAgent extends agent_base_1.Agent {
constructor(uri, opts) {
super(opts);
this.clearResolverPromise = () => {
this.resolverPromise = undefined;
};
// Strip the "pac+" prefix
const uriStr = typeof uri === 'string' ? uri : uri.href;
this.uri = new url_1.URL(uriStr.replace(/^pac\+/i, ''));
debug('Creating PacProxyAgent with URI %o', this.uri.href);
// @ts-expect-error Not sure why TS is complaining here…
this.opts = { ...opts };
this.cache = undefined;
this.resolver = undefined;
this.resolverHash = '';
this.resolverPromise = undefined;
// For `PacResolver`
if (!this.opts.filename) {
this.opts.filename = this.uri.href;
}
}
/**
* Loads the PAC proxy file from the source if necessary, and returns
* a generated `FindProxyForURL()` resolver function to use.
*/
getResolver() {
if (!this.resolverPromise) {
this.resolverPromise = this.loadResolver();
this.resolverPromise.then(this.clearResolverPromise, this.clearResolverPromise);
}
return this.resolverPromise;
}
async loadResolver() {
try {
// (Re)load the contents of the PAC file URI
const [qjs, code] = await Promise.all([
(0, quickjs_emscripten_1.getQuickJS)(),
this.loadPacFile(),
]);
// Create a sha1 hash of the JS code
const hash = crypto.createHash('sha1').update(code).digest('hex');
if (this.resolver && this.resolverHash === hash) {
debug('Same sha1 hash for code - contents have not changed, reusing previous proxy resolver');
return this.resolver;
}
// Cache the resolver
debug('Creating new proxy resolver instance');
this.resolver = (0, pac_resolver_1.createPacResolver)(qjs, code, this.opts);
// Store that sha1 hash for future comparison purposes
this.resolverHash = hash;
return this.resolver;
}
catch (err) {
if (this.resolver &&
err.code === 'ENOTMODIFIED') {
debug('Got ENOTMODIFIED response, reusing previous proxy resolver');
return this.resolver;
}
throw err;
}
}
/**
* Loads the contents of the PAC proxy file.
*
* @api private
*/
async loadPacFile() {
debug('Loading PAC file: %o', this.uri);
const rs = await (0, get_uri_1.getUri)(this.uri, { ...this.opts, cache: this.cache });
debug('Got `Readable` instance for URI');
this.cache = rs;
const buf = await (0, agent_base_1.toBuffer)(rs);
debug('Read %o byte PAC file from URI', buf.length);
return buf.toString('utf8');
}
/**
* Called when the node-core HTTP client library is creating a new HTTP request.
*/
async connect(req, opts) {
const { secureEndpoint } = opts;
const isWebSocket = req.getHeader('upgrade') === 'websocket';
// First, get a generated `FindProxyForURL()` function,
// either cached or retrieved from the source
const resolver = await this.getResolver();
// Calculate the `url` parameter
const protocol = secureEndpoint ? 'https:' : 'http:';
const host = opts.host && net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
const defaultPort = secureEndpoint ? 443 : 80;
const url = Object.assign(new url_1.URL(req.path, `${protocol}//${host}`), defaultPort ? undefined : { port: opts.port });
debug('url: %s', url);
let result = await resolver(url);
// Default to "DIRECT" if a falsey value was returned (or nothing)
if (!result) {
result = 'DIRECT';
}
const proxies = String(result)
.trim()
.split(/\s*;\s*/g)
.filter(Boolean);
if (this.opts.fallbackToDirect && !proxies.includes('DIRECT')) {
proxies.push('DIRECT');
}
for (const proxy of proxies) {
let agent = null;
let socket = null;
const [type, target] = proxy.split(/\s+/);
debug('Attempting to use proxy: %o', proxy);
if (type === 'DIRECT') {
// Direct connection to the destination endpoint
if (secureEndpoint) {
socket = tls.connect(setServernameFromNonIpHost(opts));
}
else {
socket = net.connect(opts);
}
}
else if (type === 'SOCKS' || type === 'SOCKS5') {
// Use a SOCKSv5h proxy
const { SocksProxyAgent } = await Promise.resolve().then(() => __importStar(require('socks-proxy-agent')));
agent = new SocksProxyAgent(`socks://${target}`, this.opts);
}
else if (type === 'SOCKS4') {
// Use a SOCKSv4a proxy
const { SocksProxyAgent } = await Promise.resolve().then(() => __importStar(require('socks-proxy-agent')));
agent = new SocksProxyAgent(`socks4a://${target}`, this.opts);
}
else if (type === 'PROXY' ||
type === 'HTTP' ||
type === 'HTTPS') {
// Use an HTTP or HTTPS proxy
// http://dev.chromium.org/developers/design-documents/secure-web-proxy
const proxyURL = `${type === 'HTTPS' ? 'https' : 'http'}://${target}`;
if (secureEndpoint || isWebSocket) {
const { HttpsProxyAgent } = await Promise.resolve().then(() => __importStar(require('https-proxy-agent')));
agent = new HttpsProxyAgent(proxyURL, this.opts);
}
else {
const { HttpProxyAgent } = await Promise.resolve().then(() => __importStar(require('http-proxy-agent')));
agent = new HttpProxyAgent(proxyURL, this.opts);
}
}
try {
if (socket) {
// "DIRECT" connection, wait for connection confirmation
await (0, events_1.once)(socket, 'connect');
req.emit('proxy', { proxy, socket });
return socket;
}
if (agent) {
const s = await agent.connect(req, opts);
if (!(s instanceof net.Socket)) {
throw new Error('Expected a `net.Socket` to be returned from agent');
}
req.emit('proxy', { proxy, socket: s });
return s;
}
throw new Error(`Could not determine proxy type for: ${proxy}`);
}
catch (err) {
debug('Got error for proxy %o: %o', proxy, err);
req.emit('proxy', { proxy, error: err });
}
}
throw new Error(`Failed to establish a socket connection to proxies: ${JSON.stringify(proxies)}`);
}
}
PacProxyAgent.protocols = [
'pac+data',
'pac+file',
'pac+ftp',
'pac+http',
'pac+https',
];
exports.PacProxyAgent = PacProxyAgent;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,69 @@
agent-base
==========
### Turn a function into an [`http.Agent`][http.Agent] instance
This module is a thin wrapper around the base `http.Agent` class.
It provides an abstract class that must define a `connect()` function,
which is responsible for creating the underlying socket that the HTTP
client requests will use.
The `connect()` function may return an arbitrary `Duplex` stream, or
another `http.Agent` instance to delegate the request to, and may be
asynchronous (by defining an `async` function).
Instances of this agent can be used with the `http` and `https`
modules. To differentiate, the options parameter in the `connect()`
function includes a `secureEndpoint` property, which can be checked
to determine what type of socket should be returned.
#### Some subclasses:
Here are some more interesting uses of `agent-base`.
Send a pull request to list yours!
* [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints
* [`https-proxy-agent`][https-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTPS endpoints
* [`pac-proxy-agent`][pac-proxy-agent]: A PAC file proxy `http.Agent` implementation for HTTP and HTTPS
* [`socks-proxy-agent`][socks-proxy-agent]: A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS
Example
-------
Here's a minimal example that creates a new `net.Socket` or `tls.Socket`
based on the `secureEndpoint` property. This agent can be used with both
the `http` and `https` modules.
```ts
import * as net from 'net';
import * as tls from 'tls';
import * as http from 'http';
import { Agent } from 'agent-base';
class MyAgent extends Agent {
connect(req, opts) {
// `secureEndpoint` is true when using the "https" module
if (opts.secureEndpoint) {
return tls.connect(opts);
} else {
return net.connect(opts);
}
}
});
// Keep alive enabled means that `connect()` will only be
// invoked when a new connection needs to be created
const agent = new MyAgent({ keepAlive: true });
// Pass the `agent` option when creating the HTTP request
http.get('http://nodejs.org/api/', { agent }, (res) => {
console.log('"response" event!', res.headers);
res.pipe(process.stdout);
});
```
[http-proxy-agent]: ../http-proxy-agent
[https-proxy-agent]: ../https-proxy-agent
[pac-proxy-agent]: ../pac-proxy-agent
[socks-proxy-agent]: ../socks-proxy-agent
[http.Agent]: https://nodejs.org/api/http.html#http_class_http_agent

View File

@@ -0,0 +1,15 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as http from 'http';
import * as https from 'https';
import type { Readable } from 'stream';
export type ThenableRequest = http.ClientRequest & {
then: Promise<http.IncomingMessage>['then'];
};
export declare function toBuffer(stream: Readable): Promise<Buffer>;
export declare function json(stream: Readable): Promise<any>;
export declare function req(url: string | URL, opts?: https.RequestOptions): ThenableRequest;
//# sourceMappingURL=helpers.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;;;AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,GAAG;IAClD,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAsB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE;AAGD,wBAAsB,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAUzD;AAED,wBAAgB,GAAG,CAClB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE,KAAK,CAAC,cAAmB,GAC7B,eAAe,CAcjB"}

View File

@@ -0,0 +1,66 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.req = exports.json = exports.toBuffer = void 0;
const http = __importStar(require("http"));
const https = __importStar(require("https"));
async function toBuffer(stream) {
let length = 0;
const chunks = [];
for await (const chunk of stream) {
length += chunk.length;
chunks.push(chunk);
}
return Buffer.concat(chunks, length);
}
exports.toBuffer = toBuffer;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function json(stream) {
const buf = await toBuffer(stream);
const str = buf.toString('utf8');
try {
return JSON.parse(str);
}
catch (_err) {
const err = _err;
err.message += ` (input: ${str})`;
throw err;
}
}
exports.json = json;
function req(url, opts = {}) {
const href = typeof url === 'string' ? url : url.href;
const req = (href.startsWith('https:') ? https : http).request(url, opts);
const promise = new Promise((resolve, reject) => {
req
.once('response', resolve)
.once('error', reject)
.end();
});
req.then = promise.then.bind(promise);
return req;
}
exports.req = req;
//# sourceMappingURL=helpers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,6CAA+B;AAOxB,KAAK,UAAU,QAAQ,CAAC,MAAgB;IAC9C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE;QACjC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACnB;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AARD,4BAQC;AAED,8DAA8D;AACvD,KAAK,UAAU,IAAI,CAAC,MAAgB;IAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACvB;IAAC,OAAO,IAAa,EAAE;QACvB,MAAM,GAAG,GAAG,IAAa,CAAC;QAC1B,GAAG,CAAC,OAAO,IAAI,YAAY,GAAG,GAAG,CAAC;QAClC,MAAM,GAAG,CAAC;KACV;AACF,CAAC;AAVD,oBAUC;AAED,SAAgB,GAAG,CAClB,GAAiB,EACjB,OAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IACtD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAC7D,GAAG,EACH,IAAI,CACe,CAAC;IACrB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrE,GAAG;aACD,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC;aACzB,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;aACrB,GAAG,EAAqB,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACZ,CAAC;AAjBD,kBAiBC"}

View File

@@ -0,0 +1,41 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as net from 'net';
import * as tls from 'tls';
import * as http from 'http';
import type { Duplex } from 'stream';
export * from './helpers';
interface HttpConnectOpts extends net.TcpNetConnectOpts {
secureEndpoint: false;
protocol?: string;
}
interface HttpsConnectOpts extends tls.ConnectionOptions {
secureEndpoint: true;
protocol?: string;
port: number;
}
export type AgentConnectOpts = HttpConnectOpts | HttpsConnectOpts;
declare const INTERNAL: unique symbol;
export declare abstract class Agent extends http.Agent {
private [INTERNAL];
options: Partial<net.TcpNetConnectOpts & tls.ConnectionOptions>;
keepAlive: boolean;
constructor(opts?: http.AgentOptions);
abstract connect(req: http.ClientRequest, options: AgentConnectOpts): Promise<Duplex | http.Agent> | Duplex | http.Agent;
/**
* Determine whether this is an `http` or `https` request.
*/
isSecureEndpoint(options?: AgentConnectOpts): boolean;
private incrementSockets;
private decrementSockets;
getName(options: AgentConnectOpts): string;
createSocket(req: http.ClientRequest, options: AgentConnectOpts, cb: (err: Error | null, s?: Duplex) => void): void;
createConnection(): Duplex;
get defaultPort(): number;
set defaultPort(v: number);
get protocol(): string;
set protocol(v: string);
}
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,cAAc,WAAW,CAAC;AAE1B,UAAU,eAAgB,SAAQ,GAAG,CAAC,iBAAiB;IACtD,cAAc,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAiB,SAAQ,GAAG,CAAC,iBAAiB;IACvD,cAAc,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAElE,QAAA,MAAM,QAAQ,eAAmC,CAAC;AAQlD,8BAAsB,KAAM,SAAQ,IAAI,CAAC,KAAK;IAC7C,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAgB;IAGlC,OAAO,EAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACjE,SAAS,EAAG,OAAO,CAAC;gBAER,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY;IAKpC,QAAQ,CAAC,OAAO,CACf,GAAG,EAAE,IAAI,CAAC,aAAa,EACvB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK;IAErD;;OAEG;IACH,gBAAgB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO;IAqCrD,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM;IAa1C,YAAY,CACX,GAAG,EAAE,IAAI,CAAC,aAAa,EACvB,OAAO,EAAE,gBAAgB,EACzB,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI;IAgC5C,gBAAgB,IAAI,MAAM;IAW1B,IAAI,WAAW,IAAI,MAAM,CAKxB;IAED,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,EAIxB;IAED,IAAI,QAAQ,IAAI,MAAM,CAKrB;IAED,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,EAIrB;CACD"}

View File

@@ -0,0 +1,180 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Agent = void 0;
const net = __importStar(require("net"));
const http = __importStar(require("http"));
const https_1 = require("https");
__exportStar(require("./helpers"), exports);
const INTERNAL = Symbol('AgentBaseInternalState');
class Agent extends http.Agent {
constructor(opts) {
super(opts);
this[INTERNAL] = {};
}
/**
* Determine whether this is an `http` or `https` request.
*/
isSecureEndpoint(options) {
if (options) {
// First check the `secureEndpoint` property explicitly, since this
// means that a parent `Agent` is "passing through" to this instance.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (typeof options.secureEndpoint === 'boolean') {
return options.secureEndpoint;
}
// If no explicit `secure` endpoint, check if `protocol` property is
// set. This will usually be the case since using a full string URL
// or `URL` instance should be the most common usage.
if (typeof options.protocol === 'string') {
return options.protocol === 'https:';
}
}
// Finally, if no `protocol` property was set, then fall back to
// checking the stack trace of the current call stack, and try to
// detect the "https" module.
const { stack } = new Error();
if (typeof stack !== 'string')
return false;
return stack
.split('\n')
.some((l) => l.indexOf('(https.js:') !== -1 ||
l.indexOf('node:https:') !== -1);
}
// In order to support async signatures in `connect()` and Node's native
// connection pooling in `http.Agent`, the array of sockets for each origin
// has to be updated synchronously. This is so the length of the array is
// accurate when `addRequest()` is next called. We achieve this by creating a
// fake socket and adding it to `sockets[origin]` and incrementing
// `totalSocketCount`.
incrementSockets(name) {
// If `maxSockets` and `maxTotalSockets` are both Infinity then there is no
// need to create a fake socket because Node.js native connection pooling
// will never be invoked.
if (this.maxSockets === Infinity && this.maxTotalSockets === Infinity) {
return null;
}
// All instances of `sockets` are expected TypeScript errors. The
// alternative is to add it as a private property of this class but that
// will break TypeScript subclassing.
if (!this.sockets[name]) {
// @ts-expect-error `sockets` is readonly in `@types/node`
this.sockets[name] = [];
}
const fakeSocket = new net.Socket({ writable: false });
this.sockets[name].push(fakeSocket);
// @ts-expect-error `totalSocketCount` isn't defined in `@types/node`
this.totalSocketCount++;
return fakeSocket;
}
decrementSockets(name, socket) {
if (!this.sockets[name] || socket === null) {
return;
}
const sockets = this.sockets[name];
const index = sockets.indexOf(socket);
if (index !== -1) {
sockets.splice(index, 1);
// @ts-expect-error `totalSocketCount` isn't defined in `@types/node`
this.totalSocketCount--;
if (sockets.length === 0) {
// @ts-expect-error `sockets` is readonly in `@types/node`
delete this.sockets[name];
}
}
}
// In order to properly update the socket pool, we need to call `getName()` on
// the core `https.Agent` if it is a secureEndpoint.
getName(options) {
const secureEndpoint = typeof options.secureEndpoint === 'boolean'
? options.secureEndpoint
: this.isSecureEndpoint(options);
if (secureEndpoint) {
// @ts-expect-error `getName()` isn't defined in `@types/node`
return https_1.Agent.prototype.getName.call(this, options);
}
// @ts-expect-error `getName()` isn't defined in `@types/node`
return super.getName(options);
}
createSocket(req, options, cb) {
const connectOpts = {
...options,
secureEndpoint: this.isSecureEndpoint(options),
};
const name = this.getName(connectOpts);
const fakeSocket = this.incrementSockets(name);
Promise.resolve()
.then(() => this.connect(req, connectOpts))
.then((socket) => {
this.decrementSockets(name, fakeSocket);
if (socket instanceof http.Agent) {
try {
// @ts-expect-error `addRequest()` isn't defined in `@types/node`
return socket.addRequest(req, connectOpts);
}
catch (err) {
return cb(err);
}
}
this[INTERNAL].currentSocket = socket;
// @ts-expect-error `createSocket()` isn't defined in `@types/node`
super.createSocket(req, options, cb);
}, (err) => {
this.decrementSockets(name, fakeSocket);
cb(err);
});
}
createConnection() {
const socket = this[INTERNAL].currentSocket;
this[INTERNAL].currentSocket = undefined;
if (!socket) {
throw new Error('No socket was returned in the `connect()` function');
}
return socket;
}
get defaultPort() {
return (this[INTERNAL].defaultPort ??
(this.protocol === 'https:' ? 443 : 80));
}
set defaultPort(v) {
if (this[INTERNAL]) {
this[INTERNAL].defaultPort = v;
}
}
get protocol() {
return (this[INTERNAL].protocol ??
(this.isSecureEndpoint() ? 'https:' : 'http:'));
}
set protocol(v) {
if (this[INTERNAL]) {
this[INTERNAL].protocol = v;
}
}
}
exports.Agent = Agent;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,46 @@
{
"name": "agent-base",
"version": "7.1.3",
"description": "Turn a function into an `http.Agent` instance",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/agent-base"
},
"keywords": [
"http",
"agent",
"base",
"barebones",
"https"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"devDependencies": {
"@types/debug": "^4.1.7",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"@types/semver": "^7.3.13",
"@types/ws": "^6.0.4",
"async-listen": "^3.0.0",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"ws": "^5.2.4",
"tsconfig": "0.0.0"
},
"engines": {
"node": ">= 14"
},
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail",
"lint": "eslint . --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,44 @@
http-proxy-agent
================
### An HTTP(s) proxy `http.Agent` implementation for HTTP
This module provides an `http.Agent` implementation that connects to a specified
HTTP or HTTPS proxy server, and can be used with the built-in `http` module.
__Note:__ For HTTP proxy usage with the `https` module, check out
[`https-proxy-agent`](../https-proxy-agent).
Example
-------
```ts
import * as http from 'http';
import { HttpProxyAgent } from 'http-proxy-agent';
const agent = new HttpProxyAgent('http://168.63.76.32:3128');
http.get('http://nodejs.org/api/', { agent }, (res) => {
console.log('"response" event!', res.headers);
res.pipe(process.stdout);
});
```
API
---
### new HttpProxyAgent(proxy: string | URL, options?: HttpProxyAgentOptions)
The `HttpProxyAgent` class implements an `http.Agent` subclass that connects
to the specified "HTTP(s) proxy server" in order to proxy HTTP requests.
The `proxy` argument is the URL for the proxy server.
The `options` argument accepts the usual `http.Agent` constructor options, and
some additional properties:
* `headers` - Object containing additional headers to send to the proxy server
in each request. This may also be a function that returns a headers object.
**NOTE:** If your proxy does not strip these headers from the request, they
will also be sent to the destination server.

View File

@@ -0,0 +1,44 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as net from 'net';
import * as tls from 'tls';
import * as http from 'http';
import { Agent, AgentConnectOpts } from 'agent-base';
import { URL } from 'url';
import type { OutgoingHttpHeaders } from 'http';
type Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;
type ConnectOptsMap = {
http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;
https: Omit<tls.ConnectionOptions, 'host' | 'port'>;
};
type ConnectOpts<T> = {
[P in keyof ConnectOptsMap]: Protocol<T> extends P ? ConnectOptsMap[P] : never;
}[keyof ConnectOptsMap];
export type HttpProxyAgentOptions<T> = ConnectOpts<T> & http.AgentOptions & {
headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
};
interface HttpProxyAgentClientRequest extends http.ClientRequest {
outputData?: {
data: string;
}[];
_header?: string | null;
_implicitHeader(): void;
}
/**
* The `HttpProxyAgent` implements an HTTP Agent subclass that connects
* to the specified "HTTP proxy server" in order to proxy HTTP requests.
*/
export declare class HttpProxyAgent<Uri extends string> extends Agent {
static protocols: readonly ["http", "https"];
readonly proxy: URL;
proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;
constructor(proxy: Uri | URL, opts?: HttpProxyAgentOptions<Uri>);
addRequest(req: HttpProxyAgentClientRequest, opts: AgentConnectOpts): void;
setRequestProps(req: HttpProxyAgentClientRequest, opts: AgentConnectOpts): void;
connect(req: HttpProxyAgentClientRequest, opts: AgentConnectOpts): Promise<net.Socket>;
}
export {};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAKhD,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC,EAAE,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE/E,KAAK,cAAc,GAAG;IACrB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACnD,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,IAAI;KACpB,CAAC,IAAI,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAC/C,cAAc,CAAC,CAAC,CAAC,GACjB,KAAK;CACR,CAAC,MAAM,cAAc,CAAC,CAAC;AAExB,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,GACpD,IAAI,CAAC,YAAY,GAAG;IACnB,OAAO,CAAC,EAAE,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,CAAC,CAAC;CAC5D,CAAC;AAEH,UAAU,2BAA4B,SAAQ,IAAI,CAAC,aAAa;IAC/D,UAAU,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;KACb,EAAE,CAAC;IACJ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,IAAI,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,cAAc,CAAC,GAAG,SAAS,MAAM,CAAE,SAAQ,KAAK;IAC5D,MAAM,CAAC,SAAS,6BAA8B;IAE9C,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,YAAY,EAAE,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,CAAC,CAAC;IAChE,WAAW,EAAE,GAAG,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;gBAE/C,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC;IAuB/D,UAAU,CAAC,GAAG,EAAE,2BAA2B,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAO1E,eAAe,CACd,GAAG,EAAE,2BAA2B,EAChC,IAAI,EAAE,gBAAgB,GACpB,IAAI;IA0CD,OAAO,CACZ,GAAG,EAAE,2BAA2B,EAChC,IAAI,EAAE,gBAAgB,GACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;CA2CtB"}

View File

@@ -0,0 +1,148 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpProxyAgent = void 0;
const net = __importStar(require("net"));
const tls = __importStar(require("tls"));
const debug_1 = __importDefault(require("debug"));
const events_1 = require("events");
const agent_base_1 = require("agent-base");
const url_1 = require("url");
const debug = (0, debug_1.default)('http-proxy-agent');
/**
* The `HttpProxyAgent` implements an HTTP Agent subclass that connects
* to the specified "HTTP proxy server" in order to proxy HTTP requests.
*/
class HttpProxyAgent extends agent_base_1.Agent {
constructor(proxy, opts) {
super(opts);
this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy;
this.proxyHeaders = opts?.headers ?? {};
debug('Creating new HttpProxyAgent instance: %o', this.proxy.href);
// Trim off the brackets from IPv6 addresses
const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, '');
const port = this.proxy.port
? parseInt(this.proxy.port, 10)
: this.proxy.protocol === 'https:'
? 443
: 80;
this.connectOpts = {
...(opts ? omit(opts, 'headers') : null),
host,
port,
};
}
addRequest(req, opts) {
req._header = null;
this.setRequestProps(req, opts);
// @ts-expect-error `addRequest()` isn't defined in `@types/node`
super.addRequest(req, opts);
}
setRequestProps(req, opts) {
const { proxy } = this;
const protocol = opts.secureEndpoint ? 'https:' : 'http:';
const hostname = req.getHeader('host') || 'localhost';
const base = `${protocol}//${hostname}`;
const url = new url_1.URL(req.path, base);
if (opts.port !== 80) {
url.port = String(opts.port);
}
// Change the `http.ClientRequest` instance's "path" field
// to the absolute path of the URL that will be requested.
req.path = String(url);
// Inject the `Proxy-Authorization` header if necessary.
const headers = typeof this.proxyHeaders === 'function'
? this.proxyHeaders()
: { ...this.proxyHeaders };
if (proxy.username || proxy.password) {
const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;
headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`;
}
if (!headers['Proxy-Connection']) {
headers['Proxy-Connection'] = this.keepAlive
? 'Keep-Alive'
: 'close';
}
for (const name of Object.keys(headers)) {
const value = headers[name];
if (value) {
req.setHeader(name, value);
}
}
}
async connect(req, opts) {
req._header = null;
if (!req.path.includes('://')) {
this.setRequestProps(req, opts);
}
// At this point, the http ClientRequest's internal `_header` field
// might have already been set. If this is the case then we'll need
// to re-generate the string since we just changed the `req.path`.
let first;
let endOfHeaders;
debug('Regenerating stored HTTP header string for request');
req._implicitHeader();
if (req.outputData && req.outputData.length > 0) {
debug('Patching connection write() output buffer with updated header');
first = req.outputData[0].data;
endOfHeaders = first.indexOf('\r\n\r\n') + 4;
req.outputData[0].data =
req._header + first.substring(endOfHeaders);
debug('Output buffer: %o', req.outputData[0].data);
}
// Create a socket connection to the proxy server.
let socket;
if (this.proxy.protocol === 'https:') {
debug('Creating `tls.Socket`: %o', this.connectOpts);
socket = tls.connect(this.connectOpts);
}
else {
debug('Creating `net.Socket`: %o', this.connectOpts);
socket = net.connect(this.connectOpts);
}
// Wait for the socket's `connect` event, so that this `callback()`
// function throws instead of the `http` request machinery. This is
// important for i.e. `PacProxyAgent` which determines a failed proxy
// connection via the `callback()` function throwing.
await (0, events_1.once)(socket, 'connect');
return socket;
}
}
HttpProxyAgent.protocols = ['http', 'https'];
exports.HttpProxyAgent = HttpProxyAgent;
function omit(obj, ...keys) {
const ret = {};
let key;
for (key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key];
}
}
return ret;
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,47 @@
{
"name": "http-proxy-agent",
"version": "7.0.2",
"description": "An HTTP(s) proxy `http.Agent` implementation for HTTP",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/http-proxy-agent"
},
"keywords": [
"http",
"proxy",
"endpoint",
"agent"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.0",
"debug": "^4.3.4"
},
"devDependencies": {
"@types/debug": "^4.1.7",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"async-listen": "^3.0.0",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"proxy": "2.1.1",
"tsconfig": "0.0.0"
},
"engines": {
"node": ">= 14"
},
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail",
"lint": "eslint . --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,70 @@
https-proxy-agent
================
### An HTTP(s) proxy `http.Agent` implementation for HTTPS
This module provides an `http.Agent` implementation that connects to a specified
HTTP or HTTPS proxy server, and can be used with the built-in `https` module.
Specifically, this `Agent` implementation connects to an intermediary "proxy"
server and issues the [CONNECT HTTP method][CONNECT], which tells the proxy to
open a direct TCP connection to the destination server.
Since this agent implements the CONNECT HTTP method, it also works with other
protocols that use this method when connecting over proxies (i.e. WebSockets).
See the "Examples" section below for more.
Examples
--------
#### `https` module example
```ts
import * as https from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://168.63.76.32:3128');
https.get('https://example.com', { agent }, (res) => {
console.log('"response" event!', res.headers);
res.pipe(process.stdout);
});
```
#### `ws` WebSocket connection example
```ts
import WebSocket from 'ws';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://168.63.76.32:3128');
const socket = new WebSocket('ws://echo.websocket.org', { agent });
socket.on('open', function () {
console.log('"open" event!');
socket.send('hello world');
});
socket.on('message', function (data, flags) {
console.log('"message" event! %j %j', data, flags);
socket.close();
});
```
API
---
### new HttpsProxyAgent(proxy: string | URL, options?: HttpsProxyAgentOptions)
The `HttpsProxyAgent` class implements an `http.Agent` subclass that connects
to the specified "HTTP(s) proxy server" in order to proxy HTTPS and/or WebSocket
requests. This is achieved by using the [HTTP `CONNECT` method][CONNECT].
The `proxy` argument is the URL for the proxy server.
The `options` argument accepts the usual `http.Agent` constructor options, and
some additional properties:
* `headers` - Object containing additional headers to send to the proxy server
in the `CONNECT` request.
[CONNECT]: http://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_Tunneling

View File

@@ -0,0 +1,47 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as net from 'net';
import * as tls from 'tls';
import * as http from 'http';
import { Agent, AgentConnectOpts } from 'agent-base';
import { URL } from 'url';
import type { OutgoingHttpHeaders } from 'http';
type Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;
type ConnectOptsMap = {
http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;
https: Omit<tls.ConnectionOptions, 'host' | 'port'>;
};
type ConnectOpts<T> = {
[P in keyof ConnectOptsMap]: Protocol<T> extends P ? ConnectOptsMap[P] : never;
}[keyof ConnectOptsMap];
export type HttpsProxyAgentOptions<T> = ConnectOpts<T> & http.AgentOptions & {
headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
};
/**
* The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to
* the specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
*
* Outgoing HTTP requests are first tunneled through the proxy server using the
* `CONNECT` HTTP request method to establish a connection to the proxy server,
* and then the proxy server connects to the destination target and issues the
* HTTP request from the proxy server.
*
* `https:` requests have their socket connection upgraded to TLS once
* the connection to the proxy server has been established.
*/
export declare class HttpsProxyAgent<Uri extends string> extends Agent {
static protocols: readonly ["http", "https"];
readonly proxy: URL;
proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;
constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>);
/**
* Called when the node-core HTTP client library is creating a
* new HTTP request.
*/
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket>;
}
export {};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAuBhD,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC,EAAE,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE/E,KAAK,cAAc,GAAG;IACrB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACnD,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,IAAI;KACpB,CAAC,IAAI,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAC/C,cAAc,CAAC,CAAC,CAAC,GACjB,KAAK;CACR,CAAC,MAAM,cAAc,CAAC,CAAC;AAExB,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,GACrD,IAAI,CAAC,YAAY,GAAG;IACnB,OAAO,CAAC,EAAE,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,CAAC,CAAC;CAC5D,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe,CAAC,GAAG,SAAS,MAAM,CAAE,SAAQ,KAAK;IAC7D,MAAM,CAAC,SAAS,6BAA8B;IAE9C,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,YAAY,EAAE,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,CAAC,CAAC;IAChE,WAAW,EAAE,GAAG,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;gBAE/C,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC;IA0BhE;;;OAGG;IACG,OAAO,CACZ,GAAG,EAAE,IAAI,CAAC,aAAa,EACvB,IAAI,EAAE,gBAAgB,GACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;CAwGtB"}

View File

@@ -0,0 +1,180 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpsProxyAgent = void 0;
const net = __importStar(require("net"));
const tls = __importStar(require("tls"));
const assert_1 = __importDefault(require("assert"));
const debug_1 = __importDefault(require("debug"));
const agent_base_1 = require("agent-base");
const url_1 = require("url");
const parse_proxy_response_1 = require("./parse-proxy-response");
const debug = (0, debug_1.default)('https-proxy-agent');
const setServernameFromNonIpHost = (options) => {
if (options.servername === undefined &&
options.host &&
!net.isIP(options.host)) {
return {
...options,
servername: options.host,
};
}
return options;
};
/**
* The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to
* the specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
*
* Outgoing HTTP requests are first tunneled through the proxy server using the
* `CONNECT` HTTP request method to establish a connection to the proxy server,
* and then the proxy server connects to the destination target and issues the
* HTTP request from the proxy server.
*
* `https:` requests have their socket connection upgraded to TLS once
* the connection to the proxy server has been established.
*/
class HttpsProxyAgent extends agent_base_1.Agent {
constructor(proxy, opts) {
super(opts);
this.options = { path: undefined };
this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy;
this.proxyHeaders = opts?.headers ?? {};
debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href);
// Trim off the brackets from IPv6 addresses
const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, '');
const port = this.proxy.port
? parseInt(this.proxy.port, 10)
: this.proxy.protocol === 'https:'
? 443
: 80;
this.connectOpts = {
// Attempt to negotiate http/1.1 for proxy servers that support http/2
ALPNProtocols: ['http/1.1'],
...(opts ? omit(opts, 'headers') : null),
host,
port,
};
}
/**
* Called when the node-core HTTP client library is creating a
* new HTTP request.
*/
async connect(req, opts) {
const { proxy } = this;
if (!opts.host) {
throw new TypeError('No "host" provided');
}
// Create a socket connection to the proxy server.
let socket;
if (proxy.protocol === 'https:') {
debug('Creating `tls.Socket`: %o', this.connectOpts);
socket = tls.connect(setServernameFromNonIpHost(this.connectOpts));
}
else {
debug('Creating `net.Socket`: %o', this.connectOpts);
socket = net.connect(this.connectOpts);
}
const headers = typeof this.proxyHeaders === 'function'
? this.proxyHeaders()
: { ...this.proxyHeaders };
const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`;
// Inject the `Proxy-Authorization` header if necessary.
if (proxy.username || proxy.password) {
const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;
headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`;
}
headers.Host = `${host}:${opts.port}`;
if (!headers['Proxy-Connection']) {
headers['Proxy-Connection'] = this.keepAlive
? 'Keep-Alive'
: 'close';
}
for (const name of Object.keys(headers)) {
payload += `${name}: ${headers[name]}\r\n`;
}
const proxyResponsePromise = (0, parse_proxy_response_1.parseProxyResponse)(socket);
socket.write(`${payload}\r\n`);
const { connect, buffered } = await proxyResponsePromise;
req.emit('proxyConnect', connect);
this.emit('proxyConnect', connect, req);
if (connect.statusCode === 200) {
req.once('socket', resume);
if (opts.secureEndpoint) {
// The proxy is connecting to a TLS server, so upgrade
// this socket connection to a TLS connection.
debug('Upgrading socket connection to TLS');
return tls.connect({
...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'),
socket,
});
}
return socket;
}
// Some other status code that's not 200... need to re-play the HTTP
// header "data" events onto the socket once the HTTP machinery is
// attached so that the node core `http` can parse and handle the
// error status code.
// Close the original socket, and a new "fake" socket is returned
// instead, so that the proxy doesn't get the HTTP request
// written to it (which may contain `Authorization` headers or other
// sensitive data).
//
// See: https://hackerone.com/reports/541502
socket.destroy();
const fakeSocket = new net.Socket({ writable: false });
fakeSocket.readable = true;
// Need to wait for the "socket" event to re-play the "data" events.
req.once('socket', (s) => {
debug('Replaying proxy buffer for failed request');
(0, assert_1.default)(s.listenerCount('data') > 0);
// Replay the "buffered" Buffer onto the fake `socket`, since at
// this point the HTTP module machinery has been hooked up for
// the user.
s.push(buffered);
s.push(null);
});
return fakeSocket;
}
}
HttpsProxyAgent.protocols = ['http', 'https'];
exports.HttpsProxyAgent = HttpsProxyAgent;
function resume(socket) {
socket.resume();
}
function omit(obj, ...keys) {
const ret = {};
let key;
for (key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key];
}
}
return ret;
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAA2B;AAC3B,yCAA2B;AAE3B,oDAA4B;AAC5B,kDAAgC;AAChC,2CAAqD;AACrD,6BAA0B;AAC1B,iEAA4D;AAG5D,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,mBAAmB,CAAC,CAAC;AAE/C,MAAM,0BAA0B,GAAG,CAGlC,OAAU,EACT,EAAE;IACH,IACC,OAAO,CAAC,UAAU,KAAK,SAAS;QAChC,OAAO,CAAC,IAAI;QACZ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EACtB;QACD,OAAO;YACN,GAAG,OAAO;YACV,UAAU,EAAE,OAAO,CAAC,IAAI;SACxB,CAAC;KACF;IACD,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAqBF;;;;;;;;;;;GAWG;AACH,MAAa,eAAoC,SAAQ,kBAAK;IAO7D,YAAY,KAAgB,EAAE,IAAkC;QAC/D,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAChE,IAAI,CAAC,YAAY,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACxC,KAAK,CAAC,2CAA2C,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEpE,4CAA4C;QAC5C,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAC5D,UAAU,EACV,EAAE,CACF,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI;YAC3B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ;gBAClC,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,EAAE,CAAC;QACN,IAAI,CAAC,WAAW,GAAG;YAClB,sEAAsE;YACtE,aAAa,EAAE,CAAC,UAAU,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxC,IAAI;YACJ,IAAI;SACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CACZ,GAAuB,EACvB,IAAsB;QAEtB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAEvB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACf,MAAM,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;SAC1C;QAED,kDAAkD;QAClD,IAAI,MAAkB,CAAC;QACvB,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE;YAChC,KAAK,CAAC,2BAA2B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACrD,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;SACnE;aAAM;YACN,KAAK,CAAC,2BAA2B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACrD,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;SACvC;QAED,MAAM,OAAO,GACZ,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;YACtC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE;YACrB,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClE,IAAI,OAAO,GAAG,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,eAAe,CAAC;QAE1D,wDAAwD;QACxD,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,IAAI,GAAG,GAAG,kBAAkB,CACjC,KAAK,CAAC,QAAQ,CACd,IAAI,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACpD,IAAI,CACJ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;SACvB;QAED,OAAO,CAAC,IAAI,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAEtC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;YACjC,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,SAAS;gBAC3C,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,OAAO,CAAC;SACX;QACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YACxC,OAAO,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;SAC3C;QAED,MAAM,oBAAoB,GAAG,IAAA,yCAAkB,EAAC,MAAM,CAAC,CAAC;QAExD,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;QAE/B,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,oBAAoB,CAAC;QACzD,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAExC,IAAI,OAAO,CAAC,UAAU,KAAK,GAAG,EAAE;YAC/B,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE3B,IAAI,IAAI,CAAC,cAAc,EAAE;gBACxB,sDAAsD;gBACtD,8CAA8C;gBAC9C,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBAC5C,OAAO,GAAG,CAAC,OAAO,CAAC;oBAClB,GAAG,IAAI,CACN,0BAA0B,CAAC,IAAI,CAAC,EAChC,MAAM,EACN,MAAM,EACN,MAAM,CACN;oBACD,MAAM;iBACN,CAAC,CAAC;aACH;YAED,OAAO,MAAM,CAAC;SACd;QAED,oEAAoE;QACpE,kEAAkE;QAClE,iEAAiE;QACjE,qBAAqB;QAErB,iEAAiE;QACjE,0DAA0D;QAC1D,oEAAoE;QACpE,mBAAmB;QACnB,EAAE;QACF,4CAA4C;QAC5C,MAAM,CAAC,OAAO,EAAE,CAAC;QAEjB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC;QAE3B,oEAAoE;QACpE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAa,EAAE,EAAE;YACpC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YACnD,IAAA,gBAAM,EAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,gEAAgE;YAChE,8DAA8D;YAC9D,YAAY;YACZ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACnB,CAAC;;AA9IM,yBAAS,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AADlC,0CAAe;AAkJ5B,SAAS,MAAM,CAAC,MAAkC;IACjD,MAAM,CAAC,MAAM,EAAE,CAAC;AACjB,CAAC;AAED,SAAS,IAAI,CACZ,GAAM,EACN,GAAG,IAAO;IAIV,MAAM,GAAG,GAAG,EAEX,CAAC;IACF,IAAI,GAAqB,CAAC;IAC1B,KAAK,GAAG,IAAI,GAAG,EAAE;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;SACpB;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}

View File

@@ -0,0 +1,15 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { IncomingHttpHeaders } from 'http';
import { Readable } from 'stream';
export interface ConnectResponse {
statusCode: number;
statusText: string;
headers: IncomingHttpHeaders;
}
export declare function parseProxyResponse(socket: Readable): Promise<{
connect: ConnectResponse;
buffered: Buffer;
}>;
//# sourceMappingURL=parse-proxy-response.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parse-proxy-response.d.ts","sourceRoot":"","sources":["../src/parse-proxy-response.ts"],"names":[],"mappings":";;;AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlC,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,QAAQ,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyGzD"}

View File

@@ -0,0 +1,101 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseProxyResponse = void 0;
const debug_1 = __importDefault(require("debug"));
const debug = (0, debug_1.default)('https-proxy-agent:parse-proxy-response');
function parseProxyResponse(socket) {
return new Promise((resolve, reject) => {
// we need to buffer any HTTP traffic that happens with the proxy before we get
// the CONNECT response, so that if the response is anything other than an "200"
// response code, then we can re-play the "data" events on the socket once the
// HTTP parser is hooked up...
let buffersLength = 0;
const buffers = [];
function read() {
const b = socket.read();
if (b)
ondata(b);
else
socket.once('readable', read);
}
function cleanup() {
socket.removeListener('end', onend);
socket.removeListener('error', onerror);
socket.removeListener('readable', read);
}
function onend() {
cleanup();
debug('onend');
reject(new Error('Proxy connection ended before receiving CONNECT response'));
}
function onerror(err) {
cleanup();
debug('onerror %o', err);
reject(err);
}
function ondata(b) {
buffers.push(b);
buffersLength += b.length;
const buffered = Buffer.concat(buffers, buffersLength);
const endOfHeaders = buffered.indexOf('\r\n\r\n');
if (endOfHeaders === -1) {
// keep buffering
debug('have not received end of HTTP headers yet...');
read();
return;
}
const headerParts = buffered
.slice(0, endOfHeaders)
.toString('ascii')
.split('\r\n');
const firstLine = headerParts.shift();
if (!firstLine) {
socket.destroy();
return reject(new Error('No header received from proxy CONNECT response'));
}
const firstLineParts = firstLine.split(' ');
const statusCode = +firstLineParts[1];
const statusText = firstLineParts.slice(2).join(' ');
const headers = {};
for (const header of headerParts) {
if (!header)
continue;
const firstColon = header.indexOf(':');
if (firstColon === -1) {
socket.destroy();
return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`));
}
const key = header.slice(0, firstColon).toLowerCase();
const value = header.slice(firstColon + 1).trimStart();
const current = headers[key];
if (typeof current === 'string') {
headers[key] = [current, value];
}
else if (Array.isArray(current)) {
current.push(value);
}
else {
headers[key] = value;
}
}
debug('got proxy server response: %o %o', firstLine, headers);
cleanup();
resolve({
connect: {
statusCode,
statusText,
headers,
},
buffered,
});
}
socket.on('error', onerror);
socket.on('end', onend);
read();
});
}
exports.parseProxyResponse = parseProxyResponse;
//# sourceMappingURL=parse-proxy-response.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parse-proxy-response.js","sourceRoot":"","sources":["../src/parse-proxy-response.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,50 @@
{
"name": "https-proxy-agent",
"version": "7.0.6",
"description": "An HTTP(s) proxy `http.Agent` implementation for HTTPS",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/https-proxy-agent"
},
"keywords": [
"https",
"proxy",
"endpoint",
"agent"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
"debug": "4"
},
"devDependencies": {
"@types/async-retry": "^1.4.5",
"@types/debug": "4",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"async-listen": "^3.0.0",
"async-retry": "^1.3.3",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"proxy": "2.2.0",
"tsconfig": "0.0.0"
},
"engines": {
"node": ">= 14"
},
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail test/test.ts",
"test-e2e": "jest --env node --verbose --bail test/e2e.test.ts",
"lint": "eslint --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,50 @@
socks-proxy-agent
================
### A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS
This module provides an `http.Agent` implementation that connects to a
specified SOCKS proxy server, and can be used with the built-in `http`
and `https` modules.
It can also be used in conjunction with the `ws` module to establish a WebSocket
connection over a SOCKS proxy. See the "Examples" section below.
Examples
--------
```ts
import https from 'https';
import { SocksProxyAgent } from 'socks-proxy-agent';
const agent = new SocksProxyAgent(
'socks://your-name%40gmail.com:abcdef12345124@br41.nordvpn.com'
);
https.get('https://ipinfo.io', { agent }, (res) => {
console.log(res.headers);
res.pipe(process.stdout);
});
```
#### `ws` WebSocket connection example
```ts
import WebSocket from 'ws';
import { SocksProxyAgent } from 'socks-proxy-agent';
const agent = new SocksProxyAgent(
'socks://your-name%40gmail.com:abcdef12345124@br41.nordvpn.com'
);
var socket = new WebSocket('ws://echo.websocket.events', { agent });
socket.on('open', function () {
console.log('"open" event!');
socket.send('hello world');
});
socket.on('message', function (data, flags) {
console.log('"message" event! %j %j', data, flags);
socket.close();
});
```

View File

@@ -0,0 +1,27 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { SocksProxy } from 'socks';
import { Agent, AgentConnectOpts } from 'agent-base';
import * as net from 'net';
import * as http from 'http';
import { URL } from 'url';
type SocksSocketOptions = Omit<net.TcpNetConnectOpts, 'port' | 'host'>;
export type SocksProxyAgentOptions = Omit<SocksProxy, 'ipaddress' | 'host' | 'port' | 'type' | 'userId' | 'password'> & {
socketOptions?: SocksSocketOptions;
} & http.AgentOptions;
export declare class SocksProxyAgent extends Agent {
static protocols: readonly ["socks", "socks4", "socks4a", "socks5", "socks5h"];
readonly shouldLookup: boolean;
readonly proxy: SocksProxy;
timeout: number | null;
socketOptions: SocksSocketOptions | null;
constructor(uri: string | URL, opts?: SocksProxyAgentOptions);
/**
* Initiates a SOCKS connection to the specified SOCKS proxy server,
* which in turn connects to the specified remote host and port.
*/
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket>;
}
export {};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAe,UAAU,EAAsB,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAoF1B,KAAK,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACxC,UAAU,EAEV,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAC9D,GAAG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACnC,GAAG,IAAI,CAAC,YAAY,CAAC;AAEtB,qBAAa,eAAgB,SAAQ,KAAK;IACzC,MAAM,CAAC,SAAS,+DAML;IAEX,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAC;gBAE7B,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,sBAAsB;IAY5D;;;OAGG;IACG,OAAO,CACZ,GAAG,EAAE,IAAI,CAAC,aAAa,EACvB,IAAI,EAAE,gBAAgB,GACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;CA4EtB"}

View File

@@ -0,0 +1,195 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SocksProxyAgent = void 0;
const socks_1 = require("socks");
const agent_base_1 = require("agent-base");
const debug_1 = __importDefault(require("debug"));
const dns = __importStar(require("dns"));
const net = __importStar(require("net"));
const tls = __importStar(require("tls"));
const url_1 = require("url");
const debug = (0, debug_1.default)('socks-proxy-agent');
const setServernameFromNonIpHost = (options) => {
if (options.servername === undefined &&
options.host &&
!net.isIP(options.host)) {
return {
...options,
servername: options.host,
};
}
return options;
};
function parseSocksURL(url) {
let lookup = false;
let type = 5;
const host = url.hostname;
// From RFC 1928, Section 3: https://tools.ietf.org/html/rfc1928#section-3
// "The SOCKS service is conventionally located on TCP port 1080"
const port = parseInt(url.port, 10) || 1080;
// figure out if we want socks v4 or v5, based on the "protocol" used.
// Defaults to 5.
switch (url.protocol.replace(':', '')) {
case 'socks4':
lookup = true;
type = 4;
break;
// pass through
case 'socks4a':
type = 4;
break;
case 'socks5':
lookup = true;
type = 5;
break;
// pass through
case 'socks': // no version specified, default to 5h
type = 5;
break;
case 'socks5h':
type = 5;
break;
default:
throw new TypeError(`A "socks" protocol must be specified! Got: ${String(url.protocol)}`);
}
const proxy = {
host,
port,
type,
};
if (url.username) {
Object.defineProperty(proxy, 'userId', {
value: decodeURIComponent(url.username),
enumerable: false,
});
}
if (url.password != null) {
Object.defineProperty(proxy, 'password', {
value: decodeURIComponent(url.password),
enumerable: false,
});
}
return { lookup, proxy };
}
class SocksProxyAgent extends agent_base_1.Agent {
constructor(uri, opts) {
super(opts);
const url = typeof uri === 'string' ? new url_1.URL(uri) : uri;
const { proxy, lookup } = parseSocksURL(url);
this.shouldLookup = lookup;
this.proxy = proxy;
this.timeout = opts?.timeout ?? null;
this.socketOptions = opts?.socketOptions ?? null;
}
/**
* Initiates a SOCKS connection to the specified SOCKS proxy server,
* which in turn connects to the specified remote host and port.
*/
async connect(req, opts) {
const { shouldLookup, proxy, timeout } = this;
if (!opts.host) {
throw new Error('No `host` defined!');
}
let { host } = opts;
const { port, lookup: lookupFn = dns.lookup } = opts;
if (shouldLookup) {
// Client-side DNS resolution for "4" and "5" socks proxy versions.
host = await new Promise((resolve, reject) => {
// Use the request's custom lookup, if one was configured:
lookupFn(host, {}, (err, res) => {
if (err) {
reject(err);
}
else {
resolve(res);
}
});
});
}
const socksOpts = {
proxy,
destination: {
host,
port: typeof port === 'number' ? port : parseInt(port, 10),
},
command: 'connect',
timeout: timeout ?? undefined,
// @ts-expect-error the type supplied by socks for socket_options is wider
// than necessary since socks will always override the host and port
socket_options: this.socketOptions ?? undefined,
};
const cleanup = (tlsSocket) => {
req.destroy();
socket.destroy();
if (tlsSocket)
tlsSocket.destroy();
};
debug('Creating socks proxy connection: %o', socksOpts);
const { socket } = await socks_1.SocksClient.createConnection(socksOpts);
debug('Successfully created socks proxy connection');
if (timeout !== null) {
socket.setTimeout(timeout);
socket.on('timeout', () => cleanup());
}
if (opts.secureEndpoint) {
// The proxy is connecting to a TLS server, so upgrade
// this socket connection to a TLS connection.
debug('Upgrading socket connection to TLS');
const tlsSocket = tls.connect({
...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'),
socket,
});
tlsSocket.once('error', (error) => {
debug('Socket TLS error', error.message);
cleanup(tlsSocket);
});
return tlsSocket;
}
return socket;
}
}
SocksProxyAgent.protocols = [
'socks',
'socks4',
'socks4a',
'socks5',
'socks5h',
];
exports.SocksProxyAgent = SocksProxyAgent;
function omit(obj, ...keys) {
const ret = {};
let key;
for (key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key];
}
}
return ret;
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,142 @@
{
"name": "socks-proxy-agent",
"version": "8.0.5",
"description": "A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"author": {
"email": "nathan@tootallnate.net",
"name": "Nathan Rajlich",
"url": "http://n8.io/"
},
"contributors": [
{
"name": "Kiko Beats",
"email": "josefrancisco.verdu@gmail.com"
},
{
"name": "Josh Glazebrook",
"email": "josh@joshglazebrook.com"
},
{
"name": "talmobi",
"email": "talmobi@users.noreply.github.com"
},
{
"name": "Indospace.io",
"email": "justin@indospace.io"
},
{
"name": "Kilian von Pflugk",
"email": "github@jumoog.io"
},
{
"name": "Kyle",
"email": "admin@hk1229.cn"
},
{
"name": "Matheus Fernandes",
"email": "matheus.frndes@gmail.com"
},
{
"name": "Ricky Miller",
"email": "richardkazuomiller@gmail.com"
},
{
"name": "Shantanu Sharma",
"email": "shantanu34@outlook.com"
},
{
"name": "Tim Perry",
"email": "pimterry@gmail.com"
},
{
"name": "Vadim Baryshev",
"email": "vadimbaryshev@gmail.com"
},
{
"name": "jigu",
"email": "luo1257857309@gmail.com"
},
{
"name": "Alba Mendez",
"email": "me@jmendeth.com"
},
{
"name": "Дмитрий Гуденков",
"email": "Dimangud@rambler.ru"
},
{
"name": "Andrei Bitca",
"email": "63638922+andrei-bitca-dc@users.noreply.github.com"
},
{
"name": "Andrew Casey",
"email": "amcasey@users.noreply.github.com"
},
{
"name": "Brandon Ros",
"email": "brandonros1@gmail.com"
},
{
"name": "Dang Duy Thanh",
"email": "thanhdd.it@gmail.com"
},
{
"name": "Dimitar Nestorov",
"email": "8790386+dimitarnestorov@users.noreply.github.com"
}
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/socks-proxy-agent"
},
"keywords": [
"agent",
"http",
"https",
"proxy",
"socks",
"socks4",
"socks4a",
"socks5",
"socks5h"
],
"dependencies": {
"agent-base": "^7.1.2",
"debug": "^4.3.4",
"socks": "^2.8.3"
},
"devDependencies": {
"@types/async-retry": "^1.4.5",
"@types/debug": "^4.1.7",
"@types/dns2": "^2.0.3",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"async-listen": "^3.0.0",
"async-retry": "^1.3.3",
"cacheable-lookup": "^6.1.0",
"dns2": "^2.1.0",
"jest": "^29.5.0",
"socksv5": "github:TooTallNate/socksv5#fix/dstSock-close-event",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"proxy": "2.2.0",
"tsconfig": "0.0.0"
},
"engines": {
"node": ">= 14"
},
"license": "MIT",
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail test/test.ts",
"test-e2e": "jest --env node --verbose --bail test/e2e.test.ts",
"lint": "eslint . --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}

View File

@@ -0,0 +1,58 @@
{
"name": "pac-proxy-agent",
"version": "7.2.0",
"description": "A PAC file proxy `http.Agent` implementation for HTTP",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/TooTallNate/proxy-agents.git",
"directory": "packages/pac-proxy-agent"
},
"keywords": [
"pac",
"proxy",
"agent",
"http",
"https",
"socks",
"request",
"access"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"dependencies": {
"@tootallnate/quickjs-emscripten": "^0.23.0",
"agent-base": "^7.1.2",
"debug": "^4.3.4",
"get-uri": "^6.0.1",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.6",
"pac-resolver": "^7.0.1",
"socks-proxy-agent": "^8.0.5"
},
"devDependencies": {
"@types/debug": "^4.1.7",
"@types/jest": "^29.5.1",
"@types/node": "^14.18.45",
"async-listen": "^3.0.0",
"jest": "^29.5.0",
"socksv5": "0.0.6",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4",
"proxy": "2.2.0",
"tsconfig": "0.0.0"
},
"engines": {
"node": ">= 14"
},
"scripts": {
"build": "tsc",
"test": "jest --env node --verbose --bail",
"lint": "eslint --ext .ts",
"pack": "node ../../scripts/pack.mjs"
}
}