mirror of
https://github.com/lush2020/edgetunnel.git
synced 2026-03-21 08:52:43 +08:00
init work
This commit is contained in:
@@ -93,7 +93,7 @@ proxy to www.google.com:443 and remote return 200
|
||||
### 浏览器 switchyomega 设置
|
||||
|
||||
具体安装和配置,请查看官网.
|
||||
https://proxy-switchyomega.com/settings/
|
||||
https://proxy-switchyomega.com/proxy/
|
||||
|
||||
除了端口(port)和下图可能不一样。其他都应该是一样的。
|
||||
|
||||
|
||||
1
apps/deno-bypass/.env
Normal file
1
apps/deno-bypass/.env
Normal file
@@ -0,0 +1 @@
|
||||
UUID=***REMOVED******
|
||||
@@ -7,13 +7,13 @@
|
||||
"run": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "deno run --allow-net apps/deno-bypass/src/bypass.ts "
|
||||
"command": "deno run --allow-net --allow-env --allow-write apps/deno-bypass/src/bypass.ts "
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "deno run --allow-net --watch apps/deno-bypass/src/bypass.ts "
|
||||
"command": "deno run --allow-net --allow-write --allow-env --watch apps/deno-bypass/src/bypass.ts "
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
70
apps/deno-bypass/src/bypass copy.ts
Normal file
70
apps/deno-bypass/src/bypass copy.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
||||
|
||||
const userID = Deno.env.get('UUID') || '***REMOVED******';
|
||||
|
||||
const handler = async (request: Request): Promise<Response> => {
|
||||
const headers = request.headers;
|
||||
const serverAddress = headers.get('x-host') || '';
|
||||
const remotePort = headers.get('x-port') || 443;
|
||||
const uuid = headers.get('x-uuid');
|
||||
|
||||
if (!serverAddress || !remotePort || !userID) {
|
||||
return new Response(
|
||||
`Version 0.0.1-2022/12/04!!
|
||||
${userID ? 'has UUID env' : 'no UUID env'}
|
||||
感谢 deno deploy 严肃对待 web standard。支持 HTTP request & response streaming。
|
||||
`,
|
||||
{
|
||||
status: 200,
|
||||
headers: {},
|
||||
}
|
||||
);
|
||||
}
|
||||
console.log(
|
||||
`want to proxy to server address ${serverAddress}, and port ${remotePort}`
|
||||
);
|
||||
|
||||
if (uuid !== userID) {
|
||||
return new Response('Do not send right UUID!', {
|
||||
status: 403,
|
||||
headers: {},
|
||||
});
|
||||
}
|
||||
const connection = await Deno.connect({
|
||||
port: Number(remotePort),
|
||||
hostname: serverAddress,
|
||||
});
|
||||
const result = request.body?.pipeThrough(
|
||||
new TransformStream({
|
||||
transform(chunk, controller) {
|
||||
console.log('-- transform--');
|
||||
controller.enqueue(chunk);
|
||||
},
|
||||
})
|
||||
);
|
||||
const proxyResp = result?.pipeThrough(connection);
|
||||
for await (let chunk of connection.readable) {
|
||||
console.log('-------', new TextDecoder().decode(chunk));
|
||||
}
|
||||
// let timer: number | undefined = undefined;
|
||||
// const body = new ReadableStream({
|
||||
// start(controller) {
|
||||
// timer = setInterval(() => {
|
||||
// const message = `It is ${new Date().toISOString()}\n`;
|
||||
// controller.enqueue(new TextEncoder().encode(message));
|
||||
// }, 1000);
|
||||
// },
|
||||
// pull(chunk) {},
|
||||
// cancel() {
|
||||
// if (timer !== undefined) {
|
||||
// clearInterval(timer);
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
return new Response('111', {
|
||||
status: 200,
|
||||
headers: {},
|
||||
});
|
||||
};
|
||||
|
||||
serve(handler, { port: 8080, hostname: '0.0.0.0' });
|
||||
@@ -1,4 +1,4 @@
|
||||
import { serve } from 'https://deno.land/std@0.157.0/http/server.ts';
|
||||
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
||||
|
||||
const userID = Deno.env.get('UUID');
|
||||
|
||||
@@ -34,7 +34,48 @@ ${userID ? 'has UUID env' : 'no UUID env'}
|
||||
port: Number(remotePort),
|
||||
hostname: serverAddress,
|
||||
});
|
||||
|
||||
// connection.write(
|
||||
// new TextEncoder().encode('GET http://www.baidu.com/ HTTP/1.1\r\n')
|
||||
// );
|
||||
// connection.write(new TextEncoder().encode('Host: www.baidu.com\r\n\r\n'));
|
||||
// connection.close();
|
||||
|
||||
// GET / HTTP/1.1
|
||||
// Host: www.baidu.com
|
||||
// User-Agent: curl/7.83.1
|
||||
// Accept: */*
|
||||
// const body2 = new ReadableStream({
|
||||
// start(controller) {
|
||||
// controller.enqueue(new TextEncoder().encode('GET / HTTP/1.1\r\n'));
|
||||
// controller.enqueue(new TextEncoder().encode('Host: www.baidu.com\r\n'));
|
||||
// controller.enqueue(
|
||||
// new TextEncoder().encode('User-Agent: curl/7.83.1\r\n')
|
||||
// );
|
||||
// controller.enqueue(new TextEncoder().encode('Accept: */*\r\n\r\n'));
|
||||
// // controller.close();
|
||||
// },
|
||||
// cancel() {},
|
||||
// });
|
||||
|
||||
// for await (const chunk of body2) {
|
||||
// connection.write(chunk);
|
||||
// }
|
||||
const proxyResp = request.body?.pipeThrough(connection);
|
||||
// const proxyResp = request.body
|
||||
// ?.pipeThrough(
|
||||
// new TransformStream({
|
||||
// async transform(chunk, controller) {
|
||||
// console.log('transform');
|
||||
// controller.enqueue(chunk);
|
||||
// },
|
||||
// async flush(controller) {
|
||||
// console.log('flush');
|
||||
// return new Promise((res) => setTimeout(res, 1000));
|
||||
// },
|
||||
// })
|
||||
// )
|
||||
// .pipeThrough(connection);
|
||||
return new Response(proxyResp, {
|
||||
status: 200,
|
||||
headers: {},
|
||||
|
||||
@@ -32,7 +32,12 @@
|
||||
"serve": {
|
||||
"executor": "@nrwl/js:node",
|
||||
"options": {
|
||||
"buildTarget": "edge-bypass-client:build"
|
||||
"buildTarget": "edge-bypass-client:build",
|
||||
"args": [
|
||||
"run",
|
||||
"--config",
|
||||
"./apps/edge-bypass-client/src/assets/config-local.json"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@@ -43,7 +48,7 @@
|
||||
"pkg": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "npx pkg dist/apps/edge-bypass-client/main.js --targets linux,linux-arm64,macos,win --compress GZip --output dist/pkg/edge-tunnel-client/edgetunnel"
|
||||
"command": "npx pkg dist/apps/edge-bypass-client/main.js --targets linux,linux-arm64,macos,win --compress GZip --output dist/pkg/edge-tunnel-client/edgetunnel"
|
||||
},
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
async function* concatStreams(readables) {
|
||||
for (const readable of readables) {
|
||||
for await (const chunk of readable) {
|
||||
yield chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { concatStreams };
|
||||
58
apps/edge-bypass-client/src/lib/cmd.ts
Normal file
58
apps/edge-bypass-client/src/lib/cmd.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { Command } from 'commander';
|
||||
import { writeFileSync, existsSync, readFileSync } from 'fs';
|
||||
import { exit } from 'node:process';
|
||||
let config: {
|
||||
port: string;
|
||||
address: string;
|
||||
uuid: string;
|
||||
config: string;
|
||||
} = null;
|
||||
const program = new Command();
|
||||
program.option('-v').action((options) => {
|
||||
console.log(options);
|
||||
exit();
|
||||
});
|
||||
program
|
||||
.command('run')
|
||||
.description('launch local http proxy for edge pass')
|
||||
.option(
|
||||
'--config <config>',
|
||||
'address of remote proxy, etc https://***.deno.dev/'
|
||||
)
|
||||
.option(
|
||||
'--address <address>',
|
||||
'address of remote proxy, etc https://***.deno.dev/'
|
||||
)
|
||||
.option('--port <port>', 'local port of http proxy proxy')
|
||||
.option('--uuid <uuid>', 'uuid')
|
||||
.option('--save', 'if this is pass, will save to config.json')
|
||||
.action((options) => {
|
||||
console.log(__dirname);
|
||||
console.log(process.cwd());
|
||||
if (options.config) {
|
||||
if (existsSync(options.config)) {
|
||||
const content = readFileSync(options.config, {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
config = JSON.parse(content);
|
||||
return;
|
||||
} else {
|
||||
console.error('config not exsit!');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
config = options;
|
||||
if (config.address && config.port && config.uuid) {
|
||||
if (options.save) {
|
||||
writeFileSync('./config.json', JSON.stringify(options), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.error('need pass all args!');
|
||||
exit();
|
||||
}
|
||||
});
|
||||
program.parse();
|
||||
|
||||
export { config };
|
||||
46
apps/edge-bypass-client/src/lib/helper.ts
Normal file
46
apps/edge-bypass-client/src/lib/helper.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { IncomingMessage } from 'http';
|
||||
import * as os from 'os';
|
||||
import * as url from 'node:url';
|
||||
|
||||
async function* concatStreams(readables: any[]) {
|
||||
for (const readable of readables) {
|
||||
for await (const chunk of readable) {
|
||||
yield chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// POST http://zizi.press/test11.ttt?test1=66 HTTP/1.1
|
||||
// Host: zizi.press
|
||||
// User-Agent: curl/7.83.1
|
||||
// Connection: Keep-Alive
|
||||
// Content-Type: application/json
|
||||
// Accept: application/json
|
||||
// Content-Length: 16
|
||||
|
||||
// {"tool": "curl"}
|
||||
|
||||
//-------------------------------------
|
||||
// GET http://zizi.press/test11.ttt?test1=66 HTTP/1.1
|
||||
// Host: zizi.press
|
||||
// User-Agent: curl/7.83.1
|
||||
// Accept: */*
|
||||
// Connection: Keep-Alive
|
||||
|
||||
function rawHTTPHeader(req: IncomingMessage) {
|
||||
const reqUrl = url.parse(req.url);
|
||||
const headers = Object.entries(req.headers)
|
||||
.map(([key, value]) => {
|
||||
return `${key}:${value}`;
|
||||
})
|
||||
.join(os.EOL);
|
||||
const raw = `${req.method} ${reqUrl.path} HTTP/${req.httpVersion}${os.EOL}${headers}${os.EOL}${os.EOL}`;
|
||||
return raw;
|
||||
}
|
||||
|
||||
function rawHTTPPackage(req: IncomingMessage) {
|
||||
const rawHttpHeader = rawHTTPHeader(req);
|
||||
return concatStreams([[rawHttpHeader], req]);
|
||||
}
|
||||
|
||||
export { concatStreams, rawHTTPPackage, rawHTTPHeader };
|
||||
0
apps/edge-bypass-client/src/lib/http-handler.ts
Normal file
0
apps/edge-bypass-client/src/lib/http-handler.ts
Normal file
@@ -7,7 +7,7 @@ import { writeFileSync, existsSync, readFileSync } from 'fs';
|
||||
import { exit } from 'node:process';
|
||||
import * as url from 'node:url';
|
||||
import * as undici from 'undici';
|
||||
import { concatStreams } from './helper';
|
||||
import { concatStreams } from './lib/helper';
|
||||
|
||||
let config: {
|
||||
port: string;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { writeFileSync, existsSync, readFileSync } from 'fs';
|
||||
import { exit } from 'node:process';
|
||||
import * as url from 'node:url';
|
||||
import * as undici from 'undici';
|
||||
import { concatStreams } from './helper';
|
||||
import { concatStreams } from './lib/helper';
|
||||
import * as http from 'node:http';
|
||||
|
||||
let config: {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { writeFileSync, existsSync, readFileSync } from 'fs';
|
||||
import { exit } from 'node:process';
|
||||
import * as url from 'node:url';
|
||||
import * as undici from 'undici';
|
||||
import { concatStreams } from './helper';
|
||||
import { concatStreams } from './lib/helper';
|
||||
import * as http from 'node:http';
|
||||
|
||||
let config: {
|
||||
@@ -73,6 +73,8 @@ httpProxyServer.on('connect', async (req, clientSocket, head) => {
|
||||
`HTTP/${req.httpVersion} 200 Connection Established\r\n\r\n`
|
||||
);
|
||||
|
||||
// make call to edge http server
|
||||
// 1. forward all package remote, socket over http body
|
||||
const { body, headers, statusCode, trailers } = await undici.request(
|
||||
config.address,
|
||||
{
|
||||
@@ -87,6 +89,7 @@ httpProxyServer.on('connect', async (req, clientSocket, head) => {
|
||||
}
|
||||
);
|
||||
|
||||
// 2. forward remote reponse body to clientSocket
|
||||
body.pipe(clientSocket).on('error', (error) => {
|
||||
console.log('serever reponse to clientSocket: ' + error);
|
||||
});
|
||||
|
||||
@@ -1,136 +1,155 @@
|
||||
import { createServer, Socket } from 'node:net';
|
||||
import { Duplex } from 'node:stream';
|
||||
import { Socket } from 'node:net';
|
||||
import { createServer } from 'node:http';
|
||||
import { Duplex, pipeline, Readable } from 'node:stream';
|
||||
import { fetch } from 'undici';
|
||||
import { ReadableStream, WritableStream } from 'node:stream/web';
|
||||
import { Command } from 'commander';
|
||||
import { writeFileSync, existsSync, readFileSync } from 'fs';
|
||||
import { exit } from 'node:process';
|
||||
import { config } from './lib/cmd';
|
||||
import * as url from 'node:url';
|
||||
import * as undici from 'undici';
|
||||
import { concatStreams, rawHTTPHeader, rawHTTPPackage } from './lib/helper';
|
||||
|
||||
let config: {
|
||||
port: string;
|
||||
address: string;
|
||||
uuid: string;
|
||||
config: string;
|
||||
} = null;
|
||||
const program = new Command();
|
||||
program
|
||||
.command('run')
|
||||
.description('launch local http proxy for edge pass')
|
||||
.option(
|
||||
'--config <config>',
|
||||
'address of remote proxy, etc https://***.deno.dev/'
|
||||
)
|
||||
.option(
|
||||
'--address <address>',
|
||||
'address of remote proxy, etc https://***.deno.dev/'
|
||||
)
|
||||
.option('--port <port>', 'local port of http proxy proxy', '8134')
|
||||
.option('--uuid <uuid>', 'uuid')
|
||||
.option('--save', 'if this is pass, will save to config.json')
|
||||
.action((options) => {
|
||||
if (options.config) {
|
||||
if (existsSync(options.config)) {
|
||||
const content = readFileSync(options.config, {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
config = JSON.parse(content);
|
||||
return;
|
||||
} else {
|
||||
console.error('config not exsit!');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
config = options;
|
||||
if (options.save) {
|
||||
writeFileSync('./config.json', JSON.stringify(options), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
}
|
||||
});
|
||||
program.parse();
|
||||
const httpProxyServer = createServer(async (req, resp) => {
|
||||
const reqUrl = url.parse(req.url);
|
||||
const clientSocketLoggerInfo = `[proxy to ${req.url}(http)]`;
|
||||
try {
|
||||
console.log(
|
||||
`Client Connected To Proxy, client http version is ${req.httpVersion}, ${clientSocketLoggerInfo}}`
|
||||
);
|
||||
|
||||
const server = createServer();
|
||||
server.on('connection', (clientToProxySocket: Socket) => {
|
||||
console.log('Client Connected To Proxy');
|
||||
// We need only the data once, the starting packet
|
||||
clientToProxySocket.once('data', async (data) => {
|
||||
// If you want to see the packet uncomment below
|
||||
// console.log(data.toString());
|
||||
let isTLSConnection = data.toString().indexOf('CONNECT') !== -1;
|
||||
let serverPort = '80';
|
||||
let serverAddress: string;
|
||||
if (isTLSConnection) {
|
||||
// Port changed if connection is TLS
|
||||
serverPort = data
|
||||
.toString()
|
||||
.split('CONNECT ')[1]
|
||||
.split(' ')[0]
|
||||
.split(':')[1];
|
||||
serverAddress = data
|
||||
.toString()
|
||||
.split('CONNECT ')[1]
|
||||
.split(' ')[0]
|
||||
.split(':')[0];
|
||||
} else {
|
||||
serverAddress = data.toString().split('Host: ')[1].split('\r\n')[0];
|
||||
}
|
||||
|
||||
const {
|
||||
readable: clientToProxySocketReadable,
|
||||
writable: clientToProxySocketWritable,
|
||||
} = Duplex.toWeb(clientToProxySocket) as any as {
|
||||
readable: ReadableStream;
|
||||
writable: WritableStream;
|
||||
};
|
||||
|
||||
// console.log(serverAddress);
|
||||
if (isTLSConnection) {
|
||||
clientToProxySocket.write('HTTP/1.1 200 OK\r\n\n');
|
||||
} else {
|
||||
// TODO
|
||||
// proxyToServerSocket.write(data);
|
||||
}
|
||||
|
||||
fetch(config.address, {
|
||||
headers: {
|
||||
'x-host': serverAddress,
|
||||
'x-port': serverPort,
|
||||
'x-uuid': config.uuid,
|
||||
// "Content-Type": "text/plain",
|
||||
const raws = rawHTTPPackage(req);
|
||||
const readableStream = new Readable({
|
||||
async read() {
|
||||
const { value, done } = await raws.next();
|
||||
if (!done) {
|
||||
this.push(value);
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
this.push(null);
|
||||
},
|
||||
method: 'POST',
|
||||
// body: Uint8Array.from(chunks),
|
||||
body: clientToProxySocketReadable,
|
||||
duplex: 'half',
|
||||
})
|
||||
.then((resp) => {
|
||||
console.log(
|
||||
`proxy to ${serverAddress}:${serverPort} and remote return ${resp.status}`
|
||||
);
|
||||
resp.body.pipeTo(clientToProxySocketWritable).catch((error) => {
|
||||
console.error('pipe to', JSON.stringify(error));
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('fetch error', error);
|
||||
});
|
||||
clientToProxySocket.on('error', (err) => {
|
||||
console.log('CLIENT TO PROXY ERROR');
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
// make call to edge http server
|
||||
// 1. forward all package remote, socket over http body
|
||||
const { body, headers, statusCode, trailers } = await undici.request(
|
||||
config.address,
|
||||
{
|
||||
headers: {
|
||||
'x-host': reqUrl.hostname,
|
||||
'x-port': reqUrl.port || '80',
|
||||
'x-uuid': config.uuid,
|
||||
// "Content-Type": "text/plain",
|
||||
},
|
||||
method: 'POST',
|
||||
// body: Readable.from(rawHTTPPackage(req)),
|
||||
body: readableStream,
|
||||
|
||||
// body: rawHTTPHeader(req),
|
||||
// body: req,
|
||||
}
|
||||
);
|
||||
// for await (const item of rawHTTPPackage(req)) {
|
||||
// myReadable.push(item);
|
||||
// }
|
||||
// console.log(headers, statusCode);
|
||||
// for await (let chunk of body) {
|
||||
// console.log(chunk.toString());
|
||||
// }
|
||||
// 2. forward remote reponse body to clientSocket
|
||||
|
||||
pipeline(body, resp, (error) => {
|
||||
console.log(
|
||||
`${clientSocketLoggerInfo} remote server to clientSocket has error: ` +
|
||||
error
|
||||
);
|
||||
resp.destroy();
|
||||
});
|
||||
body.on('error', (err) => {
|
||||
console.log('body error', err);
|
||||
});
|
||||
body.on('data', () => {
|
||||
if (!readableStream.closed) {
|
||||
readableStream.push(null);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
resp.destroy();
|
||||
console.log('${clientSocketLogger} has error ', error);
|
||||
}
|
||||
});
|
||||
|
||||
server.on('error', (err) => {
|
||||
// handle https website
|
||||
httpProxyServer.on('connect', async (req, clientSocket, head) => {
|
||||
const reqUrl = url.parse('https://' + req.url);
|
||||
const clientSocketLoggerInfo = `[proxy to ${req.url}]`;
|
||||
try {
|
||||
console.log(
|
||||
`Client Connected To Proxy, client http version is ${
|
||||
req.httpVersion
|
||||
}, ${clientSocketLoggerInfo}, head is ${head.toString()}`
|
||||
);
|
||||
// We need only the data once, the starting packet, per http proxy spec
|
||||
clientSocket.write(
|
||||
`HTTP/${req.httpVersion} 200 Connection Established\r\n\r\n`
|
||||
);
|
||||
|
||||
console.log(config);
|
||||
// make call to edge http server
|
||||
// 1. forward all package remote, socket over http body
|
||||
const { body, headers, statusCode, trailers } = await undici.request(
|
||||
config.address,
|
||||
{
|
||||
headers: {
|
||||
'x-host': reqUrl.hostname,
|
||||
'x-port': reqUrl.port,
|
||||
'x-uuid': config.uuid,
|
||||
// "Content-Type": "text/plain",
|
||||
},
|
||||
method: 'POST',
|
||||
body: Readable.from(concatStreams([head, clientSocket])),
|
||||
}
|
||||
);
|
||||
console.log(`${clientSocketLoggerInfo} remote server return ${statusCode}`);
|
||||
// 2. forward remote reponse body to clientSocket
|
||||
pipeline(body, clientSocket, (error) => {
|
||||
console.log(
|
||||
`${clientSocketLoggerInfo} remote server to clientSocket has error: `,
|
||||
error
|
||||
);
|
||||
body?.destroy();
|
||||
clientSocket.destroy();
|
||||
});
|
||||
clientSocket.on('error', (e) => {
|
||||
body?.destroy();
|
||||
clientSocket.destroy();
|
||||
console.log(`${clientSocketLoggerInfo} clientSocket has error: ` + e);
|
||||
});
|
||||
clientSocket.on('end', () => {
|
||||
console.log(`${clientSocketLoggerInfo} has done and end.`);
|
||||
});
|
||||
} catch (error) {
|
||||
clientSocket.destroy();
|
||||
console.log(`${clientSocketLoggerInfo} has error `, error);
|
||||
}
|
||||
});
|
||||
|
||||
httpProxyServer.on('error', (err) => {
|
||||
console.log('SERVER ERROR');
|
||||
console.log(err);
|
||||
throw err;
|
||||
});
|
||||
httpProxyServer.on('clientError', (err, clientSocket) => {
|
||||
console.log('client error: ' + err);
|
||||
clientSocket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
|
||||
});
|
||||
|
||||
server.on('close', () => {
|
||||
httpProxyServer.on('close', () => {
|
||||
console.log('Client Disconnected');
|
||||
});
|
||||
|
||||
server.listen(Number(config.port), () => {
|
||||
httpProxyServer.listen(Number(config.port), () => {
|
||||
console.log('Server runnig at http://localhost:' + config.port);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ var proxyServer = http.createServer(httpOptions);
|
||||
// handle http proxy requests
|
||||
function httpOptions(clientReq, clientRes) {
|
||||
var reqUrl = url.parse(clientReq.url);
|
||||
console.log(reqUrl);
|
||||
console.log('proxy for http request: ' + reqUrl.href);
|
||||
|
||||
var options = {
|
||||
|
||||
4
test.mjs
Normal file
4
test.mjs
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Readable } from 'stream';
|
||||
const readableStream = new Readable();
|
||||
readableStream.push('ping!');
|
||||
readableStream.push('pong!');
|
||||
Reference in New Issue
Block a user