Skip to content

Commit

Permalink
Restore proxy "bin"
Browse files Browse the repository at this point in the history
  • Loading branch information
TooTallNate committed Apr 29, 2023
1 parent 1c5fb60 commit 136a72e
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 138 deletions.
1 change: 1 addition & 0 deletions packages/proxy/.eslintignore
@@ -0,0 +1 @@
dist
130 changes: 0 additions & 130 deletions packages/proxy/bin.bak/proxy.ts

This file was deleted.

2 changes: 2 additions & 0 deletions packages/proxy/package.json
Expand Up @@ -30,11 +30,13 @@
},
"license": "MIT",
"dependencies": {
"@tootallnate/once": "^2.0.0",
"args": "^5.0.3",
"basic-auth-parser": "0.0.2-1",
"debug": "^4.3.4"
},
"devDependencies": {
"@types/args": "^5.0.0",
"@types/debug": "^4.1.7",
"@types/mocha": "^5.2.7",
"@types/node": "^14.18.43",
Expand Down
103 changes: 103 additions & 0 deletions packages/proxy/src/bin/proxy.ts
@@ -0,0 +1,103 @@
#!/usr/bin/env node
import args from 'args';
import createDebug from 'debug'
import { spawn } from 'child_process';
import once from '@tootallnate/once';
// @ts-expect-error no types for "basic-auth-parser"
import basicAuthParser = require('basic-auth-parser');
import { createProxy } from '../proxy';
//import pkg from '../pkg';

const debug = createDebug('proxy');

process.title = 'proxy';

args.option(
'port',
'Port number to the proxy server should bind to',
3128,
parseInt
)
.option(
'authenticate',
'"authenticate" command to run when the "Proxy-Authorization" header is sent',
'',
String
)
//.option(
// 'local-address',
// 'IP address of the network interface to send the outgoing requests through',
// '',
// String
//);

//const flags = args.parse(process.argv, { name: pkg.name });
const flags = args.parse(process.argv);
const { port, authenticate } = flags;

const proxy = createProxy();

/**
* Outbound proxy requests will use `agent: false`.
*/

//debug("setting outbound proxy request's `agent` to `false`");
//proxy.agent = false;

/**
* Proxy outgoing request localAddress parameter
*/

//if (flags.localAddress) {
// proxy.localAddress = flags.localAddress;
//}

/**
* Proxy authenticate function.
*/

if (authenticate) {
debug('setting `authenticate()` function for: "%s"', authenticate);
proxy.authenticate = async (req) => {
debug('authenticate(): "%s"', authenticate);

// parse the "Proxy-Authorization" header
const auth = req.headers['proxy-authorization'];
if (!auth) {
// optimization: don't invoke the child process if no
// "Proxy-Authorization" header was given
return false;
}
const parsed = basicAuthParser(auth);
debug('parsed "Proxy-Authorization": %j', parsed);

// spawn a child process with the user-specified "authenticate" command
const env = { ...process.env };
// add "auth" related ENV variables
for (const [ key, value ] of Object.entries(parsed)) {
env['PROXY_AUTH_' + key.toUpperCase()] = value as string;
}

// TODO: add Windows support (use `cross-spawn`?)
const child = spawn('/bin/sh', ['-c', authenticate], {
env,
stdio: ['ignore', 'inherit', 'inherit']
});

const [code, signal] = await once(child, 'exit');
debug(
'authentication child process "exit" event: %s %s',
code,
signal
);
return code === 0;
};
}

proxy.listen(port, function() {
console.log(
'HTTP(s) proxy server listening on port %d',
// @ts-expect-error "port" is a number
proxy.address().port
);
});
6 changes: 6 additions & 0 deletions packages/proxy/src/pkg.ts
@@ -0,0 +1,6 @@
import { join } from 'path';
import { readFileSync } from 'fs';

export default JSON.parse(
readFileSync(join(__dirname, '../package.json'), 'utf8')
);
11 changes: 3 additions & 8 deletions packages/proxy/src/proxy.ts
Expand Up @@ -3,8 +3,8 @@ import * as net from 'net';
import * as url from 'url';
import * as http from 'http';
import * as os from 'os';
import { join } from 'path';
import { readFileSync } from 'fs';
import pkg from './pkg';

import createDebug from 'debug';

// log levels
Expand All @@ -18,11 +18,6 @@ const debug = {
// hostname
const hostname = os.hostname();

// proxy server version
const { version } = JSON.parse(
readFileSync(join(__dirname, '../package.json'), 'utf8')
);

export interface ProxyServer extends http.Server {
authenticate?: (req: http.IncomingMessage) => boolean | Promise<boolean>;
}
Expand Down Expand Up @@ -108,7 +103,7 @@ async function onrequest(
const headers: http.OutgoingHttpHeaders = {};
let hasXForwardedFor = false;
let hasVia = false;
const via = '1.1 ' + hostname + ' (proxy/' + version + ')';
const via = '1.1 ' + hostname + ' (proxy/' + pkg.version + ')';

for (const header of eachHeader(req)) {
debug.request('Request Header: %o', header);
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 136a72e

Please sign in to comment.