1 | 'use strict';
|
2 |
|
3 | const child = require('child_process');
|
4 | const path = require('path');
|
5 | const cli = require('heroku-cli-util');
|
6 | const exec = require('heroku-exec-util');
|
7 | const https = require('https')
|
8 | const http = require('http')
|
9 | const fs = require('fs')
|
10 | const co = require('co');
|
11 | const socks = require('@heroku/socksv5')
|
12 | var net = require("net");
|
13 |
|
14 | module.exports = function(topic, command) {
|
15 | return {
|
16 | topic: topic,
|
17 | command: command,
|
18 | description: 'Forward traffic on a local port to a dyno',
|
19 | help: `Example:
|
20 |
|
21 | $ heroku ps:forward 8080 --app murmuring-headland-14719`,
|
22 | args: [{name: 'port', optional: false}],
|
23 | flags: [
|
24 | { name: 'dyno', char: 'd', hasValue: true, description: 'specify the dyno to connect to' },
|
25 | { name: 'localPort', char: 'p', hasValue: true, description: 'the local port to use' } ],
|
26 | needsApp: true,
|
27 | needsAuth: true,
|
28 | run: cli.command(co.wrap(run))
|
29 | }
|
30 | };
|
31 |
|
32 | function * run(context, heroku) {
|
33 | yield exec.initFeature(context, heroku, function *(configVars) {
|
34 | let remotePort = context.args.port;
|
35 | let localPort = context.flags.localPort || remotePort;
|
36 |
|
37 | yield exec.createSocksProxy(context, heroku, configVars, function(dynoIp, dynoName, socksPort) {
|
38 | cli.log(`Listening on ${cli.color.white.bold(localPort)} and forwarding to ${cli.color.white.bold(`${dynoName}:${remotePort}`)}`)
|
39 | cli.log(`Use ${cli.color.magenta('CTRL+C')} to stop port fowarding`)
|
40 | net.createServer(function(connIn) {
|
41 | socks.connect({
|
42 | host: '0.0.0.0',
|
43 | port: remotePort,
|
44 | proxyHost: '127.0.0.1',
|
45 | proxyPort: socksPort,
|
46 | auths: [ socks.auth.None() ]
|
47 | }, function(socket) {
|
48 | connIn.pipe(socket);
|
49 | socket.pipe(connIn);
|
50 | });
|
51 | }).listen(localPort);
|
52 | });
|
53 | });
|
54 | return new Promise(resolve => {})
|
55 | }
|