From b82ceebb07bc0096d253d85fb378fe87a3f641c6 Mon Sep 17 00:00:00 2001 From: huangapple Date: Fri, 9 Dec 2022 08:58:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0koa,faas=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E7=9A=84http-proxy=E5=8A=9F=E8=83=BD=EF=BC=8C=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81axios=E7=9A=84=E5=85=A8=E9=83=A8=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/http-proxy/README.md | 6 ++ packages/http-proxy/src/interface.ts | 2 + packages/http-proxy/src/middleware.ts | 1 + packages/http-proxy/test/express.test.ts | 90 ++++++++++++------- packages/http-proxy/test/faas.test.ts | 40 +++++++-- .../fixtures/express/src/configuration.ts | 14 +++ .../test/fixtures/faas/src/configuration.ts | 21 ++++- .../test/fixtures/koa/src/configuration.ts | 17 +++- .../fixtures/web/src/config/config.default.ts | 14 +++ packages/http-proxy/test/koa.test.ts | 43 +++++++-- packages/http-proxy/test/web.test.ts | 44 +++++++-- 11 files changed, 236 insertions(+), 56 deletions(-) diff --git a/packages/http-proxy/README.md b/packages/http-proxy/README.md index 80cb01b9edb0..8fe973b44bf6 100644 --- a/packages/http-proxy/README.md +++ b/packages/http-proxy/README.md @@ -31,5 +31,11 @@ export const httpProxy = { host: 'http://127.0.0.1', match: /\/assets\/(.*)/, target: 'http://127.0.0.1/$1', + + //额外的axios请求config, 会照搬过去 + extReqOptions:{ + //用来设置不校验https的ssl + httpsAgent: new https.Agent({ rejectUnauthorized: false }) + } } ``` diff --git a/packages/http-proxy/src/interface.ts b/packages/http-proxy/src/interface.ts index 9733185ec2db..aaba95d9a60d 100644 --- a/packages/http-proxy/src/interface.ts +++ b/packages/http-proxy/src/interface.ts @@ -6,6 +6,8 @@ export interface HttpProxyStrategy { ignoreHeaders?: { [key: string]: boolean; } + // 额外的axios请求config, 详情见 https://axios-http.com/docs/req_config + extReqOptions?: { [key: string]: any } } export interface HttpProxyConfig extends HttpProxyStrategy { diff --git a/packages/http-proxy/src/middleware.ts b/packages/http-proxy/src/middleware.ts index 1af6d23543f7..8d0a6a6e379f 100644 --- a/packages/http-proxy/src/middleware.ts +++ b/packages/http-proxy/src/middleware.ts @@ -56,6 +56,7 @@ export class HttpProxyMiddleware implements IMiddleware { const isStream = targetRes.on && targetRes.writable; const reqOptions: any = { + ...(proxy.extReqOptions || {}), method, url: url.href, headers: reqHeaders, diff --git a/packages/http-proxy/test/express.test.ts b/packages/http-proxy/test/express.test.ts index efae93168a0b..fa5a493dd4a2 100644 --- a/packages/http-proxy/test/express.test.ts +++ b/packages/http-proxy/test/express.test.ts @@ -6,40 +6,50 @@ import * as nock from 'nock'; describe('test/express.test.ts', function () { let app; beforeAll(async () => { - nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', {'content-type': 'image/png'}); - nock('https://www.baidu.com').get('/').reply(200, '123', {'content-type': 'text/html'}); - nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', {'content-type': 'application/x-javascript'}); + nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', { 'content-type': 'image/png' }); + nock('https://www.baidu.com').get('/').reply(200, '123', { 'content-type': 'text/html' }); + //奇怪, 同一个链接只能用一次, 再用nock会报404 + nock('https://www.baidu.com').get('/1234').reply(200, '1234', { 'content-type': 'text/html' }); + nock('https://www.baidu.com').get('/5678').reply(200, '5678', { 'content-type': 'text/html' }); + nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', { 'content-type': 'application/x-javascript' }); nock('https://httpbin.org') .persist() .get('/get?name=midway').reply(200, { - "args": { - "name": "midway" - }, - "headers": { - "Host": "httpbin.org", - }, - "url": "https://httpbin.org/get?name=midway" - }, {'content-type': 'application/json'}) + "args": { + "name": "midway" + }, + "headers": { + "Host": "httpbin.org", + }, + "url": "https://httpbin.org/get?name=midway" + }, { 'content-type': 'application/json' }) .post('/post').reply(200, function (uri, requestBody) { - const body = { - 'headers': { - 'Host': 'httpbin.org', - 'Content-Type': this.req.headers['content-type'], - 'url': 'https://httpbin.org/post' - }, + const body = { + 'headers': { + 'Host': 'httpbin.org', + 'Content-Type': this.req.headers['content-type'], 'url': 'https://httpbin.org/post' - } as any; - if (this.req.headers['content-type'] === 'application/x-www-form-urlencoded') { - body.form = { - "name": "midway" - }; - } - if (this.req.headers['content-type'] === 'application/json') { - body.data = JSON.stringify(requestBody); - } - return body; - }, {'content-type': 'application/json'}); - + }, + 'url': 'https://httpbin.org/post' + } as any; + if (this.req.headers['content-type'] === 'application/x-www-form-urlencoded') { + body.form = { + "name": "midway" + }; + } + if (this.req.headers['content-type'] === 'application/json') { + body.data = JSON.stringify(requestBody); + } + return body; + }, { 'content-type': 'application/json' }); + nock('https://aliyun.com').get('/1234').reply(302, '123', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/1234" + }); + nock('https://aliyun.com').get('/5678').reply(302, '456', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/5678" + }); const appDir = join(__dirname, 'fixtures/express'); app = await createApp(appDir); }) @@ -98,14 +108,14 @@ describe('test/express.test.ts', function () { it('post json to httpbin', async () => { const request = await createHttpRequest(app); await request.post('/httpbin/post') - .send({name: 'midway'}) + .send({ name: 'midway' }) .set('Accept', 'application/json') .expect(200) .then(async response => { assert(response.status === 200) assert(response.body.url === 'https://httpbin.org/post'); assert(response.body.headers['Content-Type'] === 'application/json'); - assert(response.body.data === JSON.stringify({ name: 'midway'})); + assert(response.body.data === JSON.stringify({ name: 'midway' })); }); }); @@ -122,4 +132,22 @@ describe('test/express.test.ts', function () { assert(response.body.form.name === 'midway'); }); }); + it('canredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/canredirects/1234') + .expect(200).then(async response => { + + assert(response.text === "1234") + }); + }); + + // express不懂为啥不支持 + // it('noredirects', async () => { + // const request = await createHttpRequest(app); + // await request.get('/noredirects/5678') + // .expect(302).then(async response => { + // assert(response.text === "456") + // }); + // }); + }); diff --git a/packages/http-proxy/test/faas.test.ts b/packages/http-proxy/test/faas.test.ts index c2c30d9a0db5..46a71a124c18 100644 --- a/packages/http-proxy/test/faas.test.ts +++ b/packages/http-proxy/test/faas.test.ts @@ -8,8 +8,11 @@ describe('test/faas.test.ts', function () { let app; beforeAll(async () => { // nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', {'content-type': 'image/png;charset=utf-8'}); - nock('https://www.baidu.com').get('/').reply(200, '123', {'content-type': 'text/html'}); - nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', {'content-type': 'application/x-javascript'}); + nock('https://www.baidu.com').get('/').reply(200, '123', { 'content-type': 'text/html' }); + //奇怪, 同一个链接只能用一次, 再用nock会报404 + nock('https://www.baidu.com').get('/1234').reply(200, '1234', { 'content-type': 'text/html' }); + nock('https://www.baidu.com').get('/5678').reply(200, '5678', { 'content-type': 'text/html' }); + nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', { 'content-type': 'application/x-javascript' }); nock('https://httpbin.org') .persist() .get('/get?name=midway').reply(200, { @@ -20,7 +23,7 @@ describe('test/faas.test.ts', function () { "Host": "httpbin.org", }, "url": "https://httpbin.org/get?name=midway" - }, {'content-type': 'application/json'}) + }, { 'content-type': 'application/json' }) .post('/post').reply(200, function (uri, requestBody) { const body = { 'headers': { @@ -39,8 +42,15 @@ describe('test/faas.test.ts', function () { body.data = JSON.stringify(requestBody); } return body; - }, {'content-type': 'application/json'}); - + }, { 'content-type': 'application/json' }); + nock('https://aliyun.com').get('/1234').reply(302, '123', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/1234" + }); + nock('https://aliyun.com').get('/5678').reply(302, '456', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/5678" + }); const appDir = join(__dirname, 'fixtures/faas'); app = await createFunctionApp(appDir, {}, ServerlessApp); }) @@ -99,14 +109,14 @@ describe('test/faas.test.ts', function () { it('post json to httpbin', async () => { const request = await createHttpRequest(app); await request.post('/httpbin/post') - .send({name: 'midway'}) + .send({ name: 'midway' }) .set('Accept', 'application/json') .expect(200) .then(async response => { assert(response.status === 200) assert(response.body.url === 'https://httpbin.org/post'); assert(response.body.headers['Content-Type'] === 'application/json'); - assert(response.body.data === JSON.stringify({ name: 'midway'})); + assert(response.body.data === JSON.stringify({ name: 'midway' })); }); }); @@ -123,4 +133,20 @@ describe('test/faas.test.ts', function () { assert(response.body.form.name === 'midway'); }); }); + it('canredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/canredirects/1234') + .expect(200).then(async response => { + + assert(response.text === "1234") + }); + }); + it('noredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/noredirects/5678') + .expect(302).then(async response => { + assert(response.text === "456") + }); + }); + }); diff --git a/packages/http-proxy/test/fixtures/express/src/configuration.ts b/packages/http-proxy/test/fixtures/express/src/configuration.ts index 65fa78d0d6ba..cf08261e9777 100644 --- a/packages/http-proxy/test/fixtures/express/src/configuration.ts +++ b/packages/http-proxy/test/fixtures/express/src/configuration.ts @@ -31,6 +31,20 @@ import * as proxy from '../../../../src'; d: { match: /.*?baidu.*$/, target: 'https://www.baidu.com/' + }, + e: { + match: /\/canredirects\//, + target: "https://aliyun.com/" + }, + f: { + match: /\/noredirects\//, + target: "https://aliyun.com/", + //额外的axios请求config, 会照搬过去 + extReqOptions: { + // `maxRedirects` defines the maximum number of redirects to follow in node.js. + // If set to 0, no redirects will be followed. + maxRedirects: 0 + } } } }, diff --git a/packages/http-proxy/test/fixtures/faas/src/configuration.ts b/packages/http-proxy/test/fixtures/faas/src/configuration.ts index 225e9b333d18..086e9324e392 100644 --- a/packages/http-proxy/test/fixtures/faas/src/configuration.ts +++ b/packages/http-proxy/test/fixtures/faas/src/configuration.ts @@ -30,6 +30,20 @@ import * as proxy from '../../../../src'; d: { match: /.*?baidu.*$/, target: 'https://www.baidu.com/' + }, + e: { + match: /\/canredirects\//, + target: "https://aliyun.com/" + }, + f: { + match: /\/noredirects\//, + target: "https://aliyun.com/", + //额外的axios请求config, 会照搬过去 + extReqOptions: { + // `maxRedirects` defines the maximum number of redirects to follow in node.js. + // If set to 0, no redirects will be followed. + maxRedirects: 0 + } } } } @@ -37,13 +51,14 @@ import * as proxy from '../../../../src'; } ] }) -export class AutoConfiguration {} +export class AutoConfiguration { +} @Provide() export class HelloHttpService { - @ServerlessTrigger(ServerlessTriggerType.HTTP, { path: '/*', method: 'all'}) + @ServerlessTrigger(ServerlessTriggerType.HTTP, { path: '/*', method: 'all' }) async get() { - return 'hello' + return 'hello' } } diff --git a/packages/http-proxy/test/fixtures/koa/src/configuration.ts b/packages/http-proxy/test/fixtures/koa/src/configuration.ts index 1ded1e15abb7..3f8523726065 100644 --- a/packages/http-proxy/test/fixtures/koa/src/configuration.ts +++ b/packages/http-proxy/test/fixtures/koa/src/configuration.ts @@ -31,6 +31,20 @@ import * as proxy from '../../../../src'; d: { match: /.*?baidu.*$/, target: 'https://www.baidu.com/' + }, + e: { + match: /\/canredirects\//, + target: "https://aliyun.com/" + }, + f: { + match: /\/noredirects\//, + target: "https://aliyun.com/", + //额外的axios请求config, 会照搬过去 + extReqOptions: { + // `maxRedirects` defines the maximum number of redirects to follow in node.js. + // If set to 0, no redirects will be followed. + maxRedirects: 0 + } } } } @@ -38,4 +52,5 @@ import * as proxy from '../../../../src'; } ] }) -export class AutoConfiguration {} +export class AutoConfiguration { +} diff --git a/packages/http-proxy/test/fixtures/web/src/config/config.default.ts b/packages/http-proxy/test/fixtures/web/src/config/config.default.ts index dc7dd93dcbe2..d4597f64d11a 100644 --- a/packages/http-proxy/test/fixtures/web/src/config/config.default.ts +++ b/packages/http-proxy/test/fixtures/web/src/config/config.default.ts @@ -19,6 +19,20 @@ export const httpProxy = { d: { match: /.*?baidu.*$/, target: 'https://www.baidu.com/' + }, + e: { + match: /\/canredirects\//, + target: "https://aliyun.com/" + }, + f: { + match: /\/noredirects\//, + target: "https://aliyun.com/", + //额外的axios请求config, 会照搬过去 + extReqOptions: { + // `maxRedirects` defines the maximum number of redirects to follow in node.js. + // If set to 0, no redirects will be followed. + maxRedirects: 0 + } } }, }; diff --git a/packages/http-proxy/test/koa.test.ts b/packages/http-proxy/test/koa.test.ts index bbba635c80b2..4fcd70de1738 100644 --- a/packages/http-proxy/test/koa.test.ts +++ b/packages/http-proxy/test/koa.test.ts @@ -6,9 +6,13 @@ import * as nock from 'nock'; describe('test/koa.test.ts', function () { let app; beforeAll(async () => { - nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', {'content-type': 'image/png'}); - nock('https://www.baidu.com').get('/').reply(200, '123', {'content-type': 'text/html'}); - nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', {'content-type': 'application/x-javascript'}); + nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', { 'content-type': 'image/png' }); + nock('https://www.baidu.com').get('/').reply(200, '123', { 'content-type': 'text/html' }); + + //奇怪, 同一个链接只能用一次, 再用nock会报404 + nock('https://www.baidu.com').get('/1234').reply(200, '1234', { 'content-type': 'text/html' }); + nock('https://www.baidu.com').get('/5678').reply(200, '5678', { 'content-type': 'text/html' }); + nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', { 'content-type': 'application/x-javascript' }); nock('https://httpbin.org') .persist() .get('/get?name=midway').reply(200, { @@ -19,7 +23,7 @@ describe('test/koa.test.ts', function () { "Host": "httpbin.org", }, "url": "https://httpbin.org/get?name=midway" - }, {'content-type': 'application/json'}) + }, { 'content-type': 'application/json' }) .post('/post').reply(200, function (uri, requestBody) { const body = { 'headers': { @@ -38,7 +42,15 @@ describe('test/koa.test.ts', function () { body.data = JSON.stringify(requestBody); } return body; - }, {'content-type': 'application/json'}); + }, { 'content-type': 'application/json' }); + nock('https://aliyun.com').get('/1234').reply(302, '123', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/1234" + }); + nock('https://aliyun.com').get('/5678').reply(302, '456', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/5678" + }); const appDir = join(__dirname, 'fixtures/koa'); app = await createApp(appDir); }) @@ -97,14 +109,14 @@ describe('test/koa.test.ts', function () { it('post json to httpbin', async () => { const request = await createHttpRequest(app); await request.post('/httpbin/post') - .send({name: 'midway'}) + .send({ name: 'midway' }) .set('Accept', 'application/json') .expect(200) .then(async response => { assert(response.status === 200) assert(response.body.url === 'https://httpbin.org/post'); assert(response.body.headers['Content-Type'] === 'application/json'); - assert(response.body.data === JSON.stringify({ name: 'midway'})); + assert(response.body.data === JSON.stringify({ name: 'midway' })); }); }); @@ -122,4 +134,21 @@ describe('test/koa.test.ts', function () { assert(response.body.form.name === 'midway'); }); }); + it('canredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/canredirects/1234') + .expect(200).then(async response => { + + assert(response.text === "1234") + }); + }); + it('noredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/noredirects/5678') + .expect(302).then(async response => { + assert(response.text === "456") + }); + }); + + }); diff --git a/packages/http-proxy/test/web.test.ts b/packages/http-proxy/test/web.test.ts index 747674f2e007..090c08f50e87 100644 --- a/packages/http-proxy/test/web.test.ts +++ b/packages/http-proxy/test/web.test.ts @@ -2,12 +2,16 @@ import { createApp, createHttpRequest, close } from '@midwayjs/mock'; import { join } from 'path'; import * as assert from 'assert'; import * as nock from 'nock'; + describe('test/web.test.ts', function () { let app; beforeAll(async () => { - nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', {'content-type': 'image/png'}); - nock('https://www.baidu.com').get('/').reply(200, '123', {'content-type': 'text/html'}); - nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', {'content-type': 'application/x-javascript'}); + nock('https://gw.alicdn.com').get('/tfs/TB1.1EzoBBh1e4jSZFhXXcC9VXa-48-48.png?version=123').reply(200, '123', { 'content-type': 'image/png' }); + nock('https://www.baidu.com').get('/').reply(200, '123', { 'content-type': 'text/html' }); + //奇怪, 同一个链接只能用一次, 再用nock会报404 + nock('https://www.baidu.com').get('/1234').reply(200, '1234', { 'content-type': 'text/html' }); + nock('https://www.baidu.com').get('/5678').reply(200, '5678', { 'content-type': 'text/html' }); + nock('https://sm.bdimg.com').get('/static/wiseindex/amd_modules/@searchfe/assert_3ed54c3.js').reply(200, '123', { 'content-type': 'application/x-javascript' }); nock('https://httpbin.org') .persist() .get('/get?name=midway').reply(200, { @@ -18,7 +22,7 @@ describe('test/web.test.ts', function () { "Host": "httpbin.org", }, "url": "https://httpbin.org/get?name=midway" - }, {'content-type': 'application/json'}) + }, { 'content-type': 'application/json' }) .post('/post').reply(200, function (uri, requestBody) { const body = { 'headers': { @@ -37,7 +41,15 @@ describe('test/web.test.ts', function () { body.data = JSON.stringify(requestBody); } return body; - }, {'content-type': 'application/json'}); + }, { 'content-type': 'application/json' }); + nock('https://aliyun.com').get('/1234').reply(302, '123', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/1234" + }); + nock('https://aliyun.com').get('/5678').reply(302, '456', { + 'content-type': 'text/html', + Location: "https://www.baidu.com/5678" + }); const appDir = join(__dirname, 'fixtures/web'); app = await createApp(appDir); }) @@ -96,14 +108,14 @@ describe('test/web.test.ts', function () { it('post json to httpbin', async () => { const request = await createHttpRequest(app); await request.post('/httpbin/post') - .send({name: 'midway'}) + .send({ name: 'midway' }) .set('Accept', 'application/json') .expect(200) .then(async response => { assert(response.status === 200) assert(response.body.url === 'https://httpbin.org/post'); assert(response.body.headers['Content-Type'] === 'application/json'); - assert(response.body.data === JSON.stringify({ name: 'midway'})); + assert(response.body.data === JSON.stringify({ name: 'midway' })); }); }); @@ -121,4 +133,22 @@ describe('test/web.test.ts', function () { assert(response.body.form.name === 'midway'); }); }); + it('canredirects', async () => { + const request = await createHttpRequest(app); + await request.get('/canredirects/1234') + .expect(200).then(async response => { + + assert(response.text === "1234") + }); + }); + + // 这个不懂为啥不支持 + // it('noredirects', async () => { + // const request = await createHttpRequest(app); + // await request.get('/noredirects/5678') + // .expect(302).then(async response => { + // assert(response.text === "456") + // }); + // }); + });