mirror of
https://github.com/lush2020/edgetunnel.git
synced 2026-03-24 00:48:39 +08:00
add support for http
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -40,3 +40,5 @@ Thumbs.db
|
|||||||
|
|
||||||
##
|
##
|
||||||
**/config-local.json
|
**/config-local.json
|
||||||
|
|
||||||
|
**/.env
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
**v2ray-heroku 由于 heroku 取消免费,项目已经死了。 这是新的项目。**
|
**v2ray-heroku 由于 heroku 取消免费,项目已经死了。 这是新的项目。**
|
||||||
|
|
||||||
> 项目正在开发,基本可用,会有 bug。。
|
> 项目正在开发,基本可用,会有 bug。。
|
||||||
|
> **请定期按照 github 的提示,同步 code 到自己的项目**。
|
||||||
|
> 
|
||||||
|
|
||||||
> 本项目纯属技术性验证,探索最新的 web standard。不给予任何保证。请大家酌情使用。如果有兴趣想一起进行技术探讨可以联系我。💕
|
> 本项目纯属技术性验证,探索最新的 web standard。不给予任何保证。请大家酌情使用。如果有兴趣想一起进行技术探讨可以联系我。💕
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
||||||
|
|
||||||
const userID = Deno.env.get('UUID');
|
const userID = Deno.env.get('UUID');
|
||||||
|
|
||||||
const handler = async (request: Request): Promise<Response> => {
|
const handler = async (request: Request): Promise<Response> => {
|
||||||
@@ -35,47 +34,9 @@ ${userID ? 'has UUID env' : 'no UUID env'}
|
|||||||
hostname: serverAddress,
|
hostname: serverAddress,
|
||||||
});
|
});
|
||||||
|
|
||||||
// connection.write(
|
// request.body readablestream end casue socket to be end, this will casue socket send FIN package early
|
||||||
// new TextEncoder().encode('GET http://www.baidu.com/ HTTP/1.1\r\n')
|
// and casue deno can't get TCP pcakge.
|
||||||
// );
|
|
||||||
// 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(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, {
|
return new Response(proxyResp, {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {},
|
headers: {},
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
||||||
|
|
||||||
|
console.log('Current Deno version', Deno.version.deno);
|
||||||
|
|
||||||
const handler = async (request: Request): Promise<Response> => {
|
const handler = async (request: Request): Promise<Response> => {
|
||||||
const connection = await Deno.connect({
|
const connection = await Deno.connect({
|
||||||
port: 80,
|
port: 80,
|
||||||
hostname: 'www.baidcu.com',
|
hostname: 'www.baidu.com',
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET / HTTP/1.1
|
|
||||||
// Host: www.baidu.com
|
|
||||||
// User-Agent: curl/7.83.1
|
|
||||||
// Accept: */*
|
|
||||||
const body2 = new ReadableStream({
|
const body2 = new ReadableStream({
|
||||||
start(controller) {
|
start(controller) {
|
||||||
controller.enqueue(new TextEncoder().encode('GET / HTTP/1.1\r\n'));
|
controller.enqueue(new TextEncoder().encode('GET / HTTP/1.1\r\n'));
|
||||||
@@ -18,23 +15,24 @@ const handler = async (request: Request): Promise<Response> => {
|
|||||||
new TextEncoder().encode('User-Agent: curl/7.83.1\r\n')
|
new TextEncoder().encode('User-Agent: curl/7.83.1\r\n')
|
||||||
);
|
);
|
||||||
controller.enqueue(new TextEncoder().encode('Accept: */*\r\n\r\n'));
|
controller.enqueue(new TextEncoder().encode('Accept: */*\r\n\r\n'));
|
||||||
controller.close(); // 注释这个就好用
|
controller.close();
|
||||||
},
|
},
|
||||||
cancel() {},
|
cancel() {},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 或者不用 pipeThrough, 直接write
|
|
||||||
// for await (const chunk of body2) {
|
// for await (const chunk of body2) {
|
||||||
// connection.write(chunk);
|
// console.log('11');
|
||||||
// }
|
// }
|
||||||
// const proxyResp = connection.readable;
|
|
||||||
|
|
||||||
// -----------
|
|
||||||
const proxyResp = body2?.pipeThrough(connection);
|
const proxyResp = body2?.pipeThrough(connection);
|
||||||
|
|
||||||
return new Response(proxyResp, {
|
for await (const chunk of proxyResp) {
|
||||||
|
console.log('11');
|
||||||
|
}
|
||||||
|
return new Response('111', {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {},
|
headers: {
|
||||||
|
'x-ray': 'xxxx',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,19 +19,6 @@ const httpProxyServer = createServer(async (req, resp) => {
|
|||||||
`Client Connected To Proxy, client http version is ${req.httpVersion}, ${clientSocketLoggerInfo}}`
|
`Client Connected To Proxy, client http version is ${req.httpVersion}, ${clientSocketLoggerInfo}}`
|
||||||
);
|
);
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// make call to edge http server
|
// make call to edge http server
|
||||||
// 1. forward all package remote, socket over http body
|
// 1. forward all package remote, socket over http body
|
||||||
const { body, headers, statusCode, trailers } = await undici.request(
|
const { body, headers, statusCode, trailers } = await undici.request(
|
||||||
@@ -44,39 +31,30 @@ const httpProxyServer = createServer(async (req, resp) => {
|
|||||||
// "Content-Type": "text/plain",
|
// "Content-Type": "text/plain",
|
||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
// body: Readable.from(rawHTTPPackage(req)),
|
body: Readable.from(concatStreams([rawHTTPPackage(req), req.socket])),
|
||||||
body: readableStream,
|
|
||||||
|
|
||||||
// body: rawHTTPHeader(req),
|
|
||||||
// body: req,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// for await (const item of rawHTTPPackage(req)) {
|
console.log(`${clientSocketLoggerInfo} remote server return ${statusCode}`);
|
||||||
// myReadable.push(item);
|
|
||||||
// }
|
|
||||||
// console.log(headers, statusCode);
|
|
||||||
// for await (let chunk of body) {
|
|
||||||
// console.log(chunk.toString());
|
|
||||||
// }
|
|
||||||
// 2. forward remote reponse body to clientSocket
|
// 2. forward remote reponse body to clientSocket
|
||||||
|
for await (const chunk of body) {
|
||||||
pipeline(body, resp, (error) => {
|
req.socket.write(chunk);
|
||||||
console.log(
|
}
|
||||||
`${clientSocketLoggerInfo} remote server to clientSocket has error: ` +
|
|
||||||
error
|
|
||||||
);
|
|
||||||
resp.destroy();
|
|
||||||
});
|
|
||||||
body.on('error', (err) => {
|
body.on('error', (err) => {
|
||||||
console.log('body error', err);
|
console.log(`${clientSocketLoggerInfo} body error`, err);
|
||||||
});
|
|
||||||
body.on('data', () => {
|
|
||||||
if (!readableStream.closed) {
|
|
||||||
readableStream.push(null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
// 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();
|
||||||
|
// });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
resp.destroy();
|
req.socket.end();
|
||||||
|
req.socket.destroy();
|
||||||
console.log('${clientSocketLogger} has error ', error);
|
console.log('${clientSocketLogger} has error ', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -96,7 +74,6 @@ httpProxyServer.on('connect', async (req, clientSocket, head) => {
|
|||||||
`HTTP/${req.httpVersion} 200 Connection Established\r\n\r\n`
|
`HTTP/${req.httpVersion} 200 Connection Established\r\n\r\n`
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(config);
|
|
||||||
// make call to edge http server
|
// make call to edge http server
|
||||||
// 1. forward all package remote, socket over http body
|
// 1. forward all package remote, socket over http body
|
||||||
const { body, headers, statusCode, trailers } = await undici.request(
|
const { body, headers, statusCode, trailers } = await undici.request(
|
||||||
@@ -114,14 +91,21 @@ httpProxyServer.on('connect', async (req, clientSocket, head) => {
|
|||||||
);
|
);
|
||||||
console.log(`${clientSocketLoggerInfo} remote server return ${statusCode}`);
|
console.log(`${clientSocketLoggerInfo} remote server return ${statusCode}`);
|
||||||
// 2. forward remote reponse body to clientSocket
|
// 2. forward remote reponse body to clientSocket
|
||||||
pipeline(body, clientSocket, (error) => {
|
// 2. forward remote reponse body to clientSocket
|
||||||
console.log(
|
for await (const chunk of body) {
|
||||||
`${clientSocketLoggerInfo} remote server to clientSocket has error: `,
|
clientSocket.write(chunk);
|
||||||
error
|
}
|
||||||
);
|
body.on('error', (err) => {
|
||||||
body?.destroy();
|
console.log(`${clientSocketLoggerInfo} body error`, err);
|
||||||
clientSocket.destroy();
|
|
||||||
});
|
});
|
||||||
|
// pipeline(body, clientSocket, (error) => {
|
||||||
|
// console.log(
|
||||||
|
// `${clientSocketLoggerInfo} remote server to clientSocket has error: `,
|
||||||
|
// error
|
||||||
|
// );
|
||||||
|
// body?.destroy();
|
||||||
|
// clientSocket.destroy();
|
||||||
|
// });
|
||||||
clientSocket.on('error', (e) => {
|
clientSocket.on('error', (e) => {
|
||||||
body?.destroy();
|
body?.destroy();
|
||||||
clientSocket.destroy();
|
clientSocket.destroy();
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
var net = require('net');
|
|
||||||
var http = require('http');
|
|
||||||
var url = require('url');
|
|
||||||
|
|
||||||
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 = {
|
|
||||||
hostname: reqUrl.hostname,
|
|
||||||
port: reqUrl.port,
|
|
||||||
path: reqUrl.path,
|
|
||||||
method: clientReq.method,
|
|
||||||
headers: clientReq.headers,
|
|
||||||
};
|
|
||||||
|
|
||||||
// create socket connection on behalf of client, then pipe the response to client response (pass it on)
|
|
||||||
var serverConnection = http.request(options, function (res) {
|
|
||||||
clientRes.writeHead(res.statusCode, res.headers);
|
|
||||||
res.pipe(clientRes);
|
|
||||||
});
|
|
||||||
|
|
||||||
clientReq.pipe(serverConnection);
|
|
||||||
|
|
||||||
clientReq.on('error', (e) => {
|
|
||||||
console.log('client socket error: ' + e);
|
|
||||||
});
|
|
||||||
|
|
||||||
serverConnection.on('error', (e) => {
|
|
||||||
console.log('server connection error: ' + e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle https proxy requests (CONNECT method)
|
|
||||||
proxyServer.on('connect', (clientReq, clientSocket, head) => {
|
|
||||||
var reqUrl = url.parse('https://' + clientReq.url);
|
|
||||||
console.log(
|
|
||||||
'proxy for https request: ' + reqUrl.href + '(path encrypted by ssl)'
|
|
||||||
);
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
port: reqUrl.port,
|
|
||||||
host: reqUrl.hostname,
|
|
||||||
};
|
|
||||||
|
|
||||||
// create socket connection for client, then pipe (redirect) it to client socket
|
|
||||||
var serverSocket = net.connect(options, () => {
|
|
||||||
clientSocket.write(
|
|
||||||
'HTTP/' +
|
|
||||||
clientReq.httpVersion +
|
|
||||||
' 200 Connection Established\r\n' +
|
|
||||||
'Proxy-agent: Node.js-Proxy\r\n' +
|
|
||||||
'\r\n',
|
|
||||||
'UTF-8',
|
|
||||||
() => {
|
|
||||||
// creating pipes in both ends
|
|
||||||
serverSocket.write(head);
|
|
||||||
serverSocket.pipe(clientSocket);
|
|
||||||
clientSocket.pipe(serverSocket);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
clientSocket.on('error', (e) => {
|
|
||||||
console.log('client socket error: ' + e);
|
|
||||||
serverSocket.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
serverSocket.on('error', (e) => {
|
|
||||||
console.log('forward proxy server connection error: ' + e);
|
|
||||||
clientSocket.end();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
proxyServer.on('clientError', (err, clientSocket) => {
|
|
||||||
console.log('client error: ' + err);
|
|
||||||
clientSocket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
|
|
||||||
});
|
|
||||||
|
|
||||||
proxyServer.listen(2560);
|
|
||||||
|
|
||||||
console.log('forward proxy server started, listening on port 2560');
|
|
||||||
|
|
||||||
module.exports = proxyServer;
|
|
||||||
@@ -7,7 +7,7 @@ import { writeFileSync, existsSync, readFileSync } from 'fs';
|
|||||||
import { exit } from 'node:process';
|
import { exit } from 'node:process';
|
||||||
import * as url from 'node:url';
|
import * as url from 'node:url';
|
||||||
import * as undici from 'undici';
|
import * as undici from 'undici';
|
||||||
import { concatStreams } from './lib/helper';
|
import { concatStreams } from '../lib/helper';
|
||||||
|
|
||||||
let config: {
|
let config: {
|
||||||
port: string;
|
port: string;
|
||||||
@@ -7,7 +7,7 @@ import { writeFileSync, existsSync, readFileSync } from 'fs';
|
|||||||
import { exit } from 'node:process';
|
import { exit } from 'node:process';
|
||||||
import * as url from 'node:url';
|
import * as url from 'node:url';
|
||||||
import * as undici from 'undici';
|
import * as undici from 'undici';
|
||||||
import { concatStreams } from './lib/helper';
|
|
||||||
import * as http from 'node:http';
|
import * as http from 'node:http';
|
||||||
|
|
||||||
let config: {
|
let config: {
|
||||||
@@ -13,5 +13,6 @@
|
|||||||
{
|
{
|
||||||
"path": "./tsconfig.spec.json"
|
"path": "./tsconfig.spec.json"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"exclude": ["**test/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
3
libs/test/.babelrc
Normal file
3
libs/test/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]]
|
||||||
|
}
|
||||||
18
libs/test/.eslintrc.json
Normal file
18
libs/test/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"extends": ["../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
libs/test/README.md
Normal file
11
libs/test/README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# test
|
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev).
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `nx test test` to execute the unit tests via [Jest](https://jestjs.io).
|
||||||
|
|
||||||
|
## Running lint
|
||||||
|
|
||||||
|
Run `nx lint test` to execute the lint via [ESLint](https://eslint.org/).
|
||||||
16
libs/test/jest.config.ts
Normal file
16
libs/test/jest.config.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
export default {
|
||||||
|
displayName: 'test',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
testEnvironment: 'node',
|
||||||
|
transform: {
|
||||||
|
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
|
coverageDirectory: '../../coverage/libs/test',
|
||||||
|
};
|
||||||
95
libs/test/node.mjs
Normal file
95
libs/test/node.mjs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import { createServer } from 'node:http';
|
||||||
|
import { connect } from 'node:net';
|
||||||
|
import { Readable, Duplex, Writable } from 'node:stream';
|
||||||
|
import { ReadableStream, WritableStream } from 'node:stream/web';
|
||||||
|
|
||||||
|
const httpServer = createServer(async (req, resp) => {
|
||||||
|
// const rawHttp = 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() {},
|
||||||
|
// });
|
||||||
|
// async function* resposne() {
|
||||||
|
// for await (const chunk of [
|
||||||
|
// 'GET / HTTP/1.1\r\n',
|
||||||
|
// 'Host: www.baidu.com\r\n',
|
||||||
|
// 'User-Agent: curl/7.83.1\r\n',
|
||||||
|
// 'Accept: */*\r\n\r\n',
|
||||||
|
// ]) {
|
||||||
|
// yield chunk;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// const buffer = resposne();
|
||||||
|
// const rawHttp = new Readable({
|
||||||
|
// async read() {
|
||||||
|
// console.log('pull----');
|
||||||
|
// const { value, done } = await buffer.next();
|
||||||
|
// if (!done) {
|
||||||
|
// this.push(value);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
const rawHttp = Readable.from([
|
||||||
|
'GET / HTTP/1.1\r\n',
|
||||||
|
'Host: www.baidu.com\r\n',
|
||||||
|
'User-Agent: curl/7.83.1\r\n\r\n',
|
||||||
|
]);
|
||||||
|
// rawHttp.p;
|
||||||
|
// rawHttp.push('Accept: */*\r\n\r\n');
|
||||||
|
rawHttp.on('end', () => {
|
||||||
|
console.log('rawHttp--end-----');
|
||||||
|
});
|
||||||
|
const socket = connect(
|
||||||
|
{
|
||||||
|
port: 80,
|
||||||
|
host: 'www.baidu.com',
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log('connected');
|
||||||
|
resp.writeHead(200);
|
||||||
|
rawHttp.pipe(socket).pipe(resp);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// .pipe(resp)
|
||||||
|
// .on('close', () => {
|
||||||
|
// console.log('--close-----');
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
|
httpServer.listen('8888', () => {
|
||||||
|
console.log('Server runnig at http://localhost:8888');
|
||||||
|
});
|
||||||
|
|
||||||
|
// const httpServer = createServer(async (req, resp) => {
|
||||||
|
// const rawHttp = 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() {},
|
||||||
|
// });
|
||||||
|
// const socket = connect({
|
||||||
|
// port: 80,
|
||||||
|
// host: 'www.baidu.com',
|
||||||
|
// });
|
||||||
|
// resp.writeHead(200);
|
||||||
|
// const webStreamSocket = rawHttp.pipeThrough(Duplex.toWeb(socket));
|
||||||
|
// Readable.fromWeb(webStreamSocket).pipe(resp);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// httpServer.listen('8888', () => {
|
||||||
|
// console.log('Server runnig at http://localhost:8888');
|
||||||
|
// });
|
||||||
24
libs/test/project.json
Normal file
24
libs/test/project.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "test",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "libs/test/src",
|
||||||
|
"projectType": "library",
|
||||||
|
"targets": {
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nrwl/linter:eslint",
|
||||||
|
"outputs": ["{options.outputFile}"],
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["libs/test/**/*.ts"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"executor": "@nrwl/jest:jest",
|
||||||
|
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "libs/test/jest.config.ts",
|
||||||
|
"passWithNoTests": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
1
libs/test/src/index.ts
Normal file
1
libs/test/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './lib/test';
|
||||||
7
libs/test/src/lib/test.spec.ts
Normal file
7
libs/test/src/lib/test.spec.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { test } from './test';
|
||||||
|
|
||||||
|
describe('test', () => {
|
||||||
|
it('should work', () => {
|
||||||
|
expect(test()).toEqual('test');
|
||||||
|
});
|
||||||
|
});
|
||||||
3
libs/test/src/lib/test.ts
Normal file
3
libs/test/src/lib/test.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function test(): string {
|
||||||
|
return 'test';
|
||||||
|
}
|
||||||
13
libs/test/tsconfig.json
Normal file
13
libs/test/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"files": [],
|
||||||
|
"include": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.lib.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
libs/test/tsconfig.lib.json
Normal file
11
libs/test/tsconfig.lib.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"declaration": true,
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"],
|
||||||
|
"include": ["**/*.ts"]
|
||||||
|
}
|
||||||
20
libs/test/tsconfig.spec.json
Normal file
20
libs/test/tsconfig.spec.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"jest.config.ts",
|
||||||
|
"**/*.test.ts",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.test.tsx",
|
||||||
|
"**/*.spec.tsx",
|
||||||
|
"**/*.test.js",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.test.jsx",
|
||||||
|
"**/*.spec.jsx",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -14,7 +14,9 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {}
|
"paths": {
|
||||||
|
"@edge-bypass/test": ["libs/test/src/index.ts"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "tmp"]
|
"exclude": ["node_modules", "tmp"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user