From edf445b5324db2d350652cfb273bfcf7438079cc Mon Sep 17 00:00:00 2001 From: zizifn <1803942+zizifn@users.noreply.github.com> Date: Tue, 6 Dec 2022 02:02:13 +0800 Subject: [PATCH] support http client --- README.md | 3 ++- apps/deno-bypass/src/bypass.ts | 4 ++- apps/edge-bypass-client/src/lib/helper.ts | 21 ++++++++++++++- apps/edge-bypass-client/src/main.ts | 31 +++++++++++++---------- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 42b2790..8511176 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,8 @@ https://proxy-switchyomega.com/proxy/ ### 其他软件 proxy 设置 -下面以电报为例,其他软件也是一样的。具体方式请用搜索引擎。 +> 电报客户端一直不停的发送 HTTP 请求,所以代理电报可能会快速消耗资源和免费额度。 +> 下面以电报为例,其他软件也是一样的。具体方式请用搜索引擎。 路径, setting--> Advance-->Conntction type--> Use Custom proxy ![tel](./doc/tel.jpg) diff --git a/apps/deno-bypass/src/bypass.ts b/apps/deno-bypass/src/bypass.ts index 22d89bf..0bd9068 100644 --- a/apps/deno-bypass/src/bypass.ts +++ b/apps/deno-bypass/src/bypass.ts @@ -34,8 +34,10 @@ ${userID ? 'has UUID env' : 'no UUID env'} hostname: serverAddress, }); - // request.body readablestream end casue socket to be end, this will casue socket send FIN package early + // 1. request.body readablestream end casue socket to be end, this will casue socket send FIN package early // and casue deno can't get TCP pcakge. + // 2. current soluction for this, let proxy client wait for few ms and then end readablestream + // 3. this is only inpact HTTP proxy not https const proxyResp = request.body?.pipeThrough(connection); return new Response(proxyResp, { status: 200, diff --git a/apps/edge-bypass-client/src/lib/helper.ts b/apps/edge-bypass-client/src/lib/helper.ts index 01d08e1..3c887d3 100644 --- a/apps/edge-bypass-client/src/lib/helper.ts +++ b/apps/edge-bypass-client/src/lib/helper.ts @@ -43,4 +43,23 @@ function rawHTTPPackage(req: IncomingMessage) { return concatStreams([[rawHttpHeader], req]); } -export { concatStreams, rawHTTPPackage, rawHTTPHeader }; +async function* deplay(ms) { + yield await new Promise((res, reject) => { + setTimeout(() => res(''), ms); + }); +} + +// delay few ms for +// // request.body readablestream end casue socket to be end, this will casue socket send FIN package early +// and casue deno can't get TCP pcakge. +function rawHTTPPackageWithDelay(req: IncomingMessage) { + const rawHttpHeader = rawHTTPHeader(req); + return concatStreams([[rawHttpHeader], req, deplay(500)]); +} + +export { + concatStreams, + rawHTTPPackage, + rawHTTPHeader, + rawHTTPPackageWithDelay, +}; diff --git a/apps/edge-bypass-client/src/main.ts b/apps/edge-bypass-client/src/main.ts index 51d6c4e..325c7fc 100644 --- a/apps/edge-bypass-client/src/main.ts +++ b/apps/edge-bypass-client/src/main.ts @@ -1,9 +1,14 @@ import { createServer } from 'node:http'; -import { Readable } from 'node:stream'; +import { pipeline, Readable } from 'node:stream'; import { config } from './lib/cmd'; import * as url from 'node:url'; import * as undici from 'undici'; -import { concatStreams, rawHTTPPackage } from './lib/helper'; +import { + concatStreams, + rawHTTPHeader, + rawHTTPPackage, + rawHTTPPackageWithDelay, +} from './lib/helper'; const httpProxyServer = createServer(async (req, resp) => { const reqUrl = url.parse(req.url); @@ -12,7 +17,6 @@ const httpProxyServer = createServer(async (req, resp) => { console.log( `Client Connected To Proxy, client http version is ${req.httpVersion}, ${clientSocketLoggerInfo}}` ); - // make call to edge http server // 1. forward all package remote, socket over http body const { body, headers, statusCode, trailers } = await undici.request( @@ -22,10 +26,11 @@ const httpProxyServer = createServer(async (req, resp) => { 'x-host': reqUrl.hostname, 'x-port': reqUrl.port || '80', 'x-uuid': config.uuid, - // "Content-Type": "text/plain", + 'x-http': 'true', }, method: 'POST', - body: Readable.from(concatStreams([rawHTTPPackage(req), req.socket])), + // append few ms for body + body: Readable.from(rawHTTPPackageWithDelay(req)), } ); console.log(`${clientSocketLoggerInfo} remote server return ${statusCode}`); @@ -41,14 +46,14 @@ const httpProxyServer = createServer(async (req, resp) => { }); // issue with pipeline // https://stackoverflow.com/questions/55959479/error-err-stream-premature-close-premature-close-in-node-pipeline-stream - // pipeline(body, req.socket, (error) => { - // console.log( - // `${clientSocketLoggerInfo} remote server to clientSocket has error: ` + - // error - // ); - // req.socket.end(); - // req.socket.destroy(); - // }); + pipeline(body, req.socket, (error) => { + console.log( + `${clientSocketLoggerInfo} remote server to clientSocket has error: ` + + error + ); + req.socket.end(); + req.socket.destroy(); + }); } catch (error) { req.socket.end(); req.socket.destroy();