Skip to content

Commit

Permalink
feat: Add customTag parameter to the tunnelConnectResponded event (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jirimoravcik authored Mar 1, 2023
1 parent a460ad8 commit 67b43c0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const server = new ProxyChain.Server({
// Custom user-defined function to authenticate incoming proxy requests,
// and optionally provide the URL to chained upstream proxy.
// The function must return an object (or promise resolving to the object) with the following signature:
// { requestAuthentication: Boolean, upstreamProxyUrl: String }
// { requestAuthentication: boolean, upstreamProxyUrl: string, failMsg?: string, customTag?: unknown }
// If the function is not defined or is null, the server runs in simple mode.
// Note that the function takes a single argument with the following properties:
// * request - An instance of http.IncomingMessage class with information about the client request
Expand All @@ -72,6 +72,12 @@ const server = new ProxyChain.Server({
// If "requestAuthentication" is true, you can use the following property
// to define a custom error message to return to the client instead of the default "Proxy credentials required"
failMsg: 'Bad username or password, please try again.',

// Optional custom tag that will be passed back via
// `tunnelConnectResponded` or `tunnelConnectFailed` events
// Can be used to pass information between proxy-chain
// and any external code or application using it
customTag: { userId: '123' },
};
},
});
Expand Down Expand Up @@ -326,7 +332,7 @@ the parameter types of the event callback are described in [Node.js's documentat
[1]: https://nodejs.org/api/http.html#http_event_connect

```javascript
server.on('tunnelConnectResponded', ({ proxyChainId, response, socket, head }) => {
server.on('tunnelConnectResponded', ({ proxyChainId, response, socket, head, customTag }) => {
console.log(`CONNECT response headers received: ${response.headers}`);
});
```
Expand All @@ -339,6 +345,14 @@ listenConnectAnonymizedProxy(anonymizedProxyUrl, ({ response, socket, head }) =>
});
```

You can also listen to CONNECT requests that receive response with status code different from 200.
The proxy server would emit a `tunnelConnectFailed` event.

```javascript
server.on('tunnelConnectFailed', ({ proxyChainId, response, socket, head, customTag }) => {
console.log(`CONNECT response failed with status code: ${response.statusCode}`);
});
```

## Helper functions

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "proxy-chain",
"version": "2.2.1",
"version": "2.3.0",
"description": "Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.",
"main": "dist/index.js",
"keywords": [
Expand Down
12 changes: 11 additions & 1 deletion src/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface HandlerOpts {
localAddress?: string;
ipFamily?: number;
dnsLookup?: typeof dns['lookup'];
customTag?: unknown;
}

interface ChainOpts {
Expand Down Expand Up @@ -72,7 +73,7 @@ export const chain = (

const { proxyChainId } = sourceSocket;

const { upstreamProxyUrlParsed: proxy } = handlerOpts;
const { upstreamProxyUrlParsed: proxy, customTag } = handlerOpts;

const options: Options = {
method: 'CONNECT',
Expand Down Expand Up @@ -127,6 +128,14 @@ export const chain = (
sourceSocket.end(createHttpResponse(status, `UPSTREAM${response.statusCode}`));
}

server.emit('tunnelConnectFailed', {
proxyChainId,
response,
customTag,
socket: targetSocket,
head: clientHead,
});

return;
}

Expand All @@ -138,6 +147,7 @@ export const chain = (
server.emit('tunnelConnectResponded', {
proxyChainId,
response,
customTag,
socket: targetSocket,
head: clientHead,
});
Expand Down
3 changes: 3 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type HandlerOpts = {
localAddress?: string;
ipFamily?: number;
dnsLookup?: typeof dns['lookup'];
customTag?: unknown;
};

export type PrepareRequestFunctionOpts = {
Expand All @@ -73,6 +74,7 @@ export type PrepareRequestFunctionResult = {
localAddress?: string;
ipFamily?: number;
dnsLookup?: typeof dns['lookup'];
customTag?: unknown;
};

type Promisable<T> = T | Promise<T>;
Expand Down Expand Up @@ -419,6 +421,7 @@ export class Server extends EventEmitter {
handlerOpts.ipFamily = funcResult.ipFamily;
handlerOpts.dnsLookup = funcResult.dnsLookup;
handlerOpts.customConnectServer = funcResult.customConnectServer;
handlerOpts.customTag = funcResult.customTag;

// If not authenticated, request client to authenticate
if (funcResult.requestAuthentication) {
Expand Down

0 comments on commit 67b43c0

Please sign in to comment.