From 829282d508cedcab53477cb36dccbe75b1338af2 Mon Sep 17 00:00:00 2001 From: Harry Chen Date: Thu, 11 Mar 2021 20:25:46 +0800 Subject: [PATCH 1/3] feat: complete static-layer --- packages-serverless/koa-layer/package.json | 2 +- .../runtime-engine/src/interface.ts | 3 + .../runtime-engine/src/lightRuntime.ts | 1 + .../runtime-engine/src/runtime.ts | 4 + .../runtime-mock/src/runtime.ts | 1 + .../serverless-fc-starter/src/runtime.ts | 2 +- .../serverless-fc-trigger/src/apiGateway.ts | 7 +- .../serverless-http-parser/src/application.ts | 1 + .../serverless-http-parser/src/context.ts | 4 + .../serverless-http-parser/src/http/req.ts | 4 + .../serverless-http-parser/src/request.ts | 4 + .../serverless-http-parser/src/response.ts | 6 +- .../serverless-scf-starter/src/runtime.ts | 2 +- .../serverless-scf-trigger/src/apiGateway.ts | 7 +- packages-serverless/static-layer/CHANGELOG.md | 317 ++++++++++++++++++ packages-serverless/static-layer/index.js | 132 ++++++++ .../static-layer/jest.config.js | 9 + packages-serverless/static-layer/package.json | 37 ++ .../test/fixtures/app-fc-404/README.md | 33 ++ .../test/fixtures/app-fc-404/build/404.html | 10 + .../test/fixtures/app-fc-404/build/index.html | 12 + .../test/fixtures/app-fc-404/build/index.js | 1 + .../test/fixtures/app-fc-404/build/main.css | 0 .../test/fixtures/app-fc-404/f.yml | 11 + .../test/fixtures/app-fc-404/index.js | 35 ++ .../test/fixtures/app-fc-404/package.json | 21 ++ .../test/fixtures/app-fc/README.md | 33 ++ .../test/fixtures/app-fc/build/index.html | 12 + .../test/fixtures/app-fc/build/index.js | 1 + .../test/fixtures/app-fc/build/main.css | 0 .../static-layer/test/fixtures/app-fc/f.yml | 11 + .../test/fixtures/app-fc/index.js | 34 ++ .../test/fixtures/app-fc/package.json | 21 ++ .../test/fixtures/app-scf/README.md | 33 ++ .../static-layer/test/fixtures/app-scf/app.js | 34 ++ .../static-layer/test/fixtures/app-scf/f.yml | 6 + .../test/fixtures/app-scf/index.js | 27 ++ .../test/fixtures/app-scf/package.json | 21 ++ .../static-layer/test/index.test.js | 112 +++++++ 39 files changed, 1003 insertions(+), 8 deletions(-) create mode 100644 packages-serverless/static-layer/CHANGELOG.md create mode 100644 packages-serverless/static-layer/index.js create mode 100644 packages-serverless/static-layer/jest.config.js create mode 100644 packages-serverless/static-layer/package.json create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/README.md create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/build/404.html create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.html create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/build/main.css create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/f.yml create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/index.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc-404/package.json create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/README.md create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/build/index.html create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/build/index.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/build/main.css create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/f.yml create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/index.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-fc/package.json create mode 100644 packages-serverless/static-layer/test/fixtures/app-scf/README.md create mode 100644 packages-serverless/static-layer/test/fixtures/app-scf/app.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-scf/f.yml create mode 100644 packages-serverless/static-layer/test/fixtures/app-scf/index.js create mode 100644 packages-serverless/static-layer/test/fixtures/app-scf/package.json create mode 100644 packages-serverless/static-layer/test/index.test.js diff --git a/packages-serverless/koa-layer/package.json b/packages-serverless/koa-layer/package.json index b503eaee3fa6..d8182933b01b 100644 --- a/packages-serverless/koa-layer/package.json +++ b/packages-serverless/koa-layer/package.json @@ -18,7 +18,7 @@ "@midwayjs/serverless-scf-starter": "^2.8.9", "@midwayjs/serverless-scf-trigger": "^2.8.9", "koa": "^2.13.0", - "koa-bodyparser": "^4.2.1", + "koa-bodyparser": "^4.3.0", "koa-router": "^9.4.0", "supertest": "^4.0.2" }, diff --git a/packages-serverless/runtime-engine/src/interface.ts b/packages-serverless/runtime-engine/src/interface.ts index 7329185dbcf9..7b94abc702a7 100644 --- a/packages-serverless/runtime-engine/src/interface.ts +++ b/packages-serverless/runtime-engine/src/interface.ts @@ -59,11 +59,13 @@ export interface Runtime extends RuntimeExtension { setOptions(RuntimeOptions): void; getFunctionName(): string; getFunctionServiceName(): string; + getRuntimeConfig(): any; } export interface LightRuntime extends Runtime { invokeHandlerWrapper(context, invokeHandler); asyncEvent(handler: handlerWrapper): (...args) => void; + getApplication(): any; } export interface IServerlessLogger { @@ -120,4 +122,5 @@ export interface BootstrapOptions { runtime?: Runtime; initContext?: any; isAppMode?: boolean; + runtimeConfig?: any; } diff --git a/packages-serverless/runtime-engine/src/lightRuntime.ts b/packages-serverless/runtime-engine/src/lightRuntime.ts index b96f05ce2d97..3053ca50c6bd 100644 --- a/packages-serverless/runtime-engine/src/lightRuntime.ts +++ b/packages-serverless/runtime-engine/src/lightRuntime.ts @@ -34,4 +34,5 @@ export abstract class ServerlessLightRuntime } abstract asyncEvent(handler): (...args) => void; + abstract getApplication(): any; } diff --git a/packages-serverless/runtime-engine/src/runtime.ts b/packages-serverless/runtime-engine/src/runtime.ts index 1d229e32aa63..188930861c5b 100644 --- a/packages-serverless/runtime-engine/src/runtime.ts +++ b/packages-serverless/runtime-engine/src/runtime.ts @@ -263,6 +263,10 @@ export class ServerlessBaseRuntime extends EventEmitter implements Runtime { return !!this.options.isAppMode; } + getRuntimeConfig() { + return this.options?.runtimeConfig || {}; + } + /** * get function name in runtime */ diff --git a/packages-serverless/runtime-mock/src/runtime.ts b/packages-serverless/runtime-mock/src/runtime.ts index 2c0bee5a0361..942450bcd223 100644 --- a/packages-serverless/runtime-mock/src/runtime.ts +++ b/packages-serverless/runtime-mock/src/runtime.ts @@ -42,6 +42,7 @@ export class MockRuntime { : new BaseBootstrap({ runtime: this.options.runtime, layers: this.options.layers, + runtimeConfig: this.options.runtimeConfig, }); this.engine = this.bootstrap.getRuntimeEngine(); } diff --git a/packages-serverless/serverless-fc-starter/src/runtime.ts b/packages-serverless/serverless-fc-starter/src/runtime.ts index 84ad678fac2c..fa580067dc12 100644 --- a/packages-serverless/serverless-fc-starter/src/runtime.ts +++ b/packages-serverless/serverless-fc-starter/src/runtime.ts @@ -111,7 +111,7 @@ export class FCRuntime extends ServerlessLightRuntime { ctx.body = result; } - if (!ctx.response.explicitStatus) { + if (!ctx.response._explicitStatus) { if (ctx.body === null || ctx.body === 'undefined') { ctx.body = ''; ctx.type = 'text'; diff --git a/packages-serverless/serverless-fc-trigger/src/apiGateway.ts b/packages-serverless/serverless-fc-trigger/src/apiGateway.ts index 11dbc79b892a..328d494ee09c 100644 --- a/packages-serverless/serverless-fc-trigger/src/apiGateway.ts +++ b/packages-serverless/serverless-fc-trigger/src/apiGateway.ts @@ -36,7 +36,12 @@ export class ApiGatewayTrigger extends FCBaseTrigger { body: any; }) => { res.set(result.headers); - res.status(result.statusCode).send(result.body); + res.status(result.statusCode); + if (result.isBase64Encoded) { + res.send(Buffer.from(result.body, 'base64')); + } else { + res.send(result.body); + } } ); }); diff --git a/packages-serverless/serverless-http-parser/src/application.ts b/packages-serverless/serverless-http-parser/src/application.ts index 766700dfc170..f085846fd537 100644 --- a/packages-serverless/serverless-http-parser/src/application.ts +++ b/packages-serverless/serverless-http-parser/src/application.ts @@ -72,6 +72,7 @@ export class Application extends EventEmitter { this.on('error', this.onerror); return (req, res, respond) => { // if (!this.listenerCount('error')) this.on('error', this.onerror); + res.statusCode = 404; const onerror = err => ctx.onerror(err); const ctx = this.createContext(req, res); return respond(ctx).catch(onerror); diff --git a/packages-serverless/serverless-http-parser/src/context.ts b/packages-serverless/serverless-http-parser/src/context.ts index ba88fb23a8bc..82b623713d24 100644 --- a/packages-serverless/serverless-http-parser/src/context.ts +++ b/packages-serverless/serverless-http-parser/src/context.ts @@ -39,6 +39,10 @@ export const context = { return this.request.path; }, + set path(value) { + this.request.path = value; + }, + get query() { return this.request.query; }, diff --git a/packages-serverless/serverless-http-parser/src/http/req.ts b/packages-serverless/serverless-http-parser/src/http/req.ts index 9ed3d87e9733..e0b56cd0d29b 100644 --- a/packages-serverless/serverless-http-parser/src/http/req.ts +++ b/packages-serverless/serverless-http-parser/src/http/req.ts @@ -69,6 +69,10 @@ export class HTTPRequest { return this[EVENT].path; } + set path(value) { + this[EVENT].path = value; + } + get pathParameters() { return this[EVENT].pathParameters || {}; } diff --git a/packages-serverless/serverless-http-parser/src/request.ts b/packages-serverless/serverless-http-parser/src/request.ts index 26d35771e796..0894743df6e6 100644 --- a/packages-serverless/serverless-http-parser/src/request.ts +++ b/packages-serverless/serverless-http-parser/src/request.ts @@ -111,6 +111,10 @@ export const request = { return this.req.path; }, + set path(value) { + this.req.path = value; + }, + get method() { return this.req.method; }, diff --git a/packages-serverless/serverless-http-parser/src/response.ts b/packages-serverless/serverless-http-parser/src/response.ts index 19155d6acfc9..94346942a1b3 100644 --- a/packages-serverless/serverless-http-parser/src/response.ts +++ b/packages-serverless/serverless-http-parser/src/response.ts @@ -8,7 +8,7 @@ import * as only from 'only'; import * as vary from 'vary'; export const response = { - explicitStatus: null, + _explicitStatus: false, _body: null, res: null, ctx: null, @@ -62,7 +62,7 @@ export const response = { } // set the status - if (!this.explicitStatus) this.status = 200; + if (!this._explicitStatus) this.status = 200; // set the content-type only if not yet set const setType = !this.has('Content-Type'); @@ -247,7 +247,7 @@ export const response = { set status(code) { assert(Number.isInteger(code), 'status code must be a number'); assert(code >= 100 && code <= 999, `invalid status code: ${code}`); - this.explicitStatus = true; + this._explicitStatus = true; this.res.statusCode = code; if (this.body && statuses.empty[code]) this.body = null; }, diff --git a/packages-serverless/serverless-scf-starter/src/runtime.ts b/packages-serverless/serverless-scf-starter/src/runtime.ts index 4cf2352cbbb7..ee4005c9de81 100644 --- a/packages-serverless/serverless-scf-starter/src/runtime.ts +++ b/packages-serverless/serverless-scf-starter/src/runtime.ts @@ -62,7 +62,7 @@ export class SCFRuntime extends ServerlessLightRuntime { ctx.body = result; } - if (!ctx.response.explicitStatus) { + if (!ctx.response._explicitStatus) { if (ctx.body === null || ctx.body === 'undefined') { ctx.body = ''; ctx.type = 'text'; diff --git a/packages-serverless/serverless-scf-trigger/src/apiGateway.ts b/packages-serverless/serverless-scf-trigger/src/apiGateway.ts index 5855c6c33572..f6e89e2f99f0 100644 --- a/packages-serverless/serverless-scf-trigger/src/apiGateway.ts +++ b/packages-serverless/serverless-scf-trigger/src/apiGateway.ts @@ -53,7 +53,12 @@ export class ApiGatewayTrigger extends SCFBaseTrigger { body: any; }) => { res.set(result.headers); - res.status(result.statusCode).send(result.body); + res.status(result.statusCode); + if (result.isBase64Encoded) { + res.send(Buffer.from(result.body, 'base64')); + } else { + res.send(result.body); + } } ); }); diff --git a/packages-serverless/static-layer/CHANGELOG.md b/packages-serverless/static-layer/CHANGELOG.md new file mode 100644 index 000000000000..4860bf03b059 --- /dev/null +++ b/packages-serverless/static-layer/CHANGELOG.md @@ -0,0 +1,317 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [2.8.9](https://github.com/midwayjs/midway-faas/compare/v2.8.8...v2.8.9) (2021-03-08) + + +### Bug Fixes + +* delete method parse body and form body ([#891](https://github.com/midwayjs/midway-faas/issues/891)) ([f5c1e70](https://github.com/midwayjs/midway-faas/commit/f5c1e7042ed85656e323563421391a719999979e)) + + + + + +## [2.8.8](https://github.com/midwayjs/midway-faas/compare/v2.8.7...v2.8.8) (2021-03-06) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.7](https://github.com/midwayjs/midway-faas/compare/v2.8.6...v2.8.7) (2021-03-04) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.6](https://github.com/midwayjs/midway-faas/compare/v2.8.5...v2.8.6) (2021-03-03) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.5](https://github.com/midwayjs/midway-faas/compare/v2.8.4...v2.8.5) (2021-03-03) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.4](https://github.com/midwayjs/midway-faas/compare/v2.8.3...v2.8.4) (2021-03-03) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.3](https://github.com/midwayjs/midway-faas/compare/v2.8.2...v2.8.3) (2021-03-01) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.8.2](https://github.com/midwayjs/midway-faas/compare/v2.8.0...v2.8.2) (2021-02-27) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.7.7](https://github.com/midwayjs/midway-faas/compare/v2.7.6...v2.7.7) (2021-02-20) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.7.4](https://github.com/midwayjs/midway-faas/compare/v2.7.3...v2.7.4) (2021-02-03) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +# [2.7.0](https://github.com/midwayjs/midway-faas/compare/v2.6.13...v2.7.0) (2021-01-27) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.13](https://github.com/midwayjs/midway-faas/compare/v2.6.12...v2.6.13) (2021-01-21) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.11](https://github.com/midwayjs/midway-faas/compare/v2.6.10...v2.6.11) (2021-01-11) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.8](https://github.com/midwayjs/midway-faas/compare/v2.6.7...v2.6.8) (2021-01-06) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.7](https://github.com/midwayjs/midway-faas/compare/v2.6.6...v2.6.7) (2021-01-05) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.6](https://github.com/midwayjs/midway-faas/compare/v2.6.5...v2.6.6) (2021-01-04) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.5](https://github.com/midwayjs/midway-faas/compare/v2.6.4...v2.6.5) (2021-01-04) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.4](https://github.com/midwayjs/midway-faas/compare/v2.6.3...v2.6.4) (2021-01-02) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.3](https://github.com/midwayjs/midway-faas/compare/v2.6.2...v2.6.3) (2020-12-30) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.2](https://github.com/midwayjs/midway-faas/compare/v2.6.1...v2.6.2) (2020-12-30) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.6.1](https://github.com/midwayjs/midway-faas/compare/v2.6.0...v2.6.1) (2020-12-29) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +# [2.6.0](https://github.com/midwayjs/midway-faas/compare/v2.5.5...v2.6.0) (2020-12-28) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.5.3](https://github.com/midwayjs/midway-faas/compare/v2.5.2...v2.5.3) (2020-12-11) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +# [2.5.0](https://github.com/midwayjs/midway-faas/compare/v2.4.8...v2.5.0) (2020-11-28) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [2.4.3](https://github.com/midwayjs/midway-faas/compare/v2.4.2...v2.4.3) (2020-11-16) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +# [2.4.0](https://github.com/midwayjs/midway-faas/compare/v2.3.23...v2.4.0) (2020-11-11) + + +### Features + +* support define custom egg framework ([#709](https://github.com/midwayjs/midway-faas/issues/709)) ([f5baba1](https://github.com/midwayjs/midway-faas/commit/f5baba18d10e3dc91ba9651effadd00b8f66cf8b)) + + + + + +## [1.2.9](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.8...serverless-v1.2.9) (2020-08-26) + + +### Bug Fixes + +* support async entry for koa/express ([#621](https://github.com/midwayjs/midway-faas/issues/621)) ([19bb466](https://github.com/midwayjs/midway-faas/commit/19bb466e99f3c7e7cb5b755e9fb4bb89f0a65256)) + + + + + +## [1.2.8](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.7...serverless-v1.2.8) (2020-08-24) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.2.7](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.6...serverless-v1.2.7) (2020-08-21) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.2.6](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.5...serverless-v1.2.6) (2020-08-19) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.2.4](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.3...serverless-v1.2.4) (2020-08-19) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.2.2](https://github.com/midwayjs/midway-faas/compare/serverless-v1.2.1...serverless-v1.2.2) (2020-08-18) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.1.19](https://github.com/midwayjs/midway-faas/compare/serverless-v1.1.18...serverless-v1.1.19) (2020-08-11) + + +### Bug Fixes + +* application return 301 and buffer case ([#596](https://github.com/midwayjs/midway-faas/issues/596)) ([a31c022](https://github.com/midwayjs/midway-faas/commit/a31c022409d234e001030d81ce1e414159039a0b)) + + + + + +## [1.1.16](https://github.com/midwayjs/midway-faas/compare/serverless-v1.1.15...serverless-v1.1.16) (2020-08-05) + + +### Bug Fixes + +* remove layer console ([#586](https://github.com/midwayjs/midway-faas/issues/586)) ([51b144b](https://github.com/midwayjs/midway-faas/commit/51b144b8d18b15cc31b31d8a2eacf7b16c12cdd1)) + + + + + +## [1.1.8](https://github.com/midwayjs/midway-faas/compare/serverless-v1.1.7...serverless-v1.1.8) (2020-07-27) + +**Note:** Version bump only for package @midwayjs/koa-layer + + + + + +## [1.1.4](https://github.com/midwayjs/midway-faas/compare/v1.0.8...v1.1.4) (2020-07-24) + + +### Features + +* Support application layer ([#534](https://github.com/midwayjs/midway-faas/issues/534)) ([7a141c0](https://github.com/midwayjs/midway-faas/commit/7a141c0c9404dc20d4d146a14e01dff404943142)) + + + + + +# [1.1.0](https://github.com/midwayjs/midway-faas/compare/serverless-v1.0.11...serverless-v1.1.0) (2020-07-21) + + +### Features + +* Support application layer ([#534](https://github.com/midwayjs/midway-faas/issues/534)) ([7a141c0](https://github.com/midwayjs/midway-faas/commit/7a141c0c9404dc20d4d146a14e01dff404943142)) diff --git a/packages-serverless/static-layer/index.js b/packages-serverless/static-layer/index.js new file mode 100644 index 000000000000..f1796fa45db4 --- /dev/null +++ b/packages-serverless/static-layer/index.js @@ -0,0 +1,132 @@ +const staticCache = require('koa-static-cache'); +const { join } = require('path'); +const { readFileSync, existsSync, unlinkSync } = require('fs'); +const rewrite = require('koa-rewrite'); +const request = require('request'); +const KOA = require('koa'); +const os = require('os'); + +const socketPath = join(os.tmpdir(), `server-${Date.now()}.sock`); + +module.exports = engine => { + engine.addRuntimeExtension({ + async beforeRuntimeStart(runtime) { + const baseDir = runtime.getPropertyParser().getEntryDir(); + const runtimeConfig = runtime.getRuntimeConfig(); + let deployConfig = {}; + if ( + runtimeConfig['deployType'] && + runtimeConfig['deployType']['config'] + ) { + deployConfig = runtimeConfig['deployType']['config']; + } + + if (!deployConfig.rootDir) { + deployConfig.rootDir = 'build'; + } + + const staticConfig = { + dynamic: true, + index: 'index.html', + preload: false, + buffer: true, + maxFiles: 1000, + }; + staticConfig.dir = join(baseDir, deployConfig.rootDir); + staticConfig.prefix = deployConfig.prefix || '/'; + + const app = new KOA(); + // handleRequest = koaApp.callback(); + if (existsSync(socketPath)) { + unlinkSync(socketPath); + } + + let notFoundPageCache; + + if (deployConfig['rewrite']) { + for (const pattern of Object.keys(deployConfig['rewrite'])) { + app.use(rewrite(pattern, deployConfig['rewrite'][pattern])); + } + } + + app.use(async (ctx, next) => { + let orig = ctx.path; + const last = orig.split('/').pop(); + if (last.indexOf('.') === -1) { + orig += '/'; + } + if (/\/$/.test(orig)) { + ctx.path = orig + 'index.html'; + } + ctx.path = ctx.path.replace('//', '/'); + await next(); + if (!ctx.response._explicitStatus) { + ctx.status = 404; + if (deployConfig['notFoundUrl']) { + if (notFoundPageCache) { + ctx.body = notFoundPageCache; + } else { + const fullPath = join( + staticConfig.dir, + deployConfig['notFoundUrl'] + ); + if (existsSync(fullPath)) { + ctx.body = notFoundPageCache = readFileSync(fullPath); + ctx.type = 'text/html'; + } + } + } + } + }); + app.use(staticCache(staticConfig)); + app.listen(socketPath); + }, + async defaultInvokeHandler(context) { + return new Promise((resolve, reject) => { + delete context.headers['content-length']; + const requestOption = { + uri: `http://unix:${socketPath}:${context.path}`, + qs: context.query, + method: context.method, + headers: context.headers, + followRedirect: false, + }; + if ( + (context.headers['content-type'] || '').indexOf('application/json') >= + 0 + ) { + // post json + if (typeof context.request.body !== 'string') { + requestOption.body = JSON.stringify(context.request.body); + } else { + requestOption.body = context.request.body; + } + } else if ( + (context.headers['content-type'] || '').indexOf('form-urlencoded') >= + 0 + ) { + // post formdata + requestOption.form = context.request.body; + } else if (context.request.body) { + if (typeof context.request.body !== 'string') { + requestOption.form = context.request.body; + } else { + requestOption.body = context.request.body; + } + } + request(requestOption, (error, response, body) => { + context.res = response; + context.status = response.statusCode; + if (error) { + console.error('[static-layer]' + error); + resolve('Internal Server Error'); + } else { + context.res = response; + context.status = response.statusCode; + resolve(body); + } + }); + }); + }, + }); +}; diff --git a/packages-serverless/static-layer/jest.config.js b/packages-serverless/static-layer/jest.config.js new file mode 100644 index 000000000000..33736bad1dca --- /dev/null +++ b/packages-serverless/static-layer/jest.config.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testPathIgnorePatterns: ['/test/fixtures'], + coveragePathIgnorePatterns: ['/test/'], + forceExit: true, +}; diff --git a/packages-serverless/static-layer/package.json b/packages-serverless/static-layer/package.json new file mode 100644 index 000000000000..f9ab0e720a22 --- /dev/null +++ b/packages-serverless/static-layer/package.json @@ -0,0 +1,37 @@ +{ + "name": "@midwayjs/static-layer", + "version": "2.8.9", + "main": "index.js", + "scripts": { + "test": "midway-bin test", + "cov": "midway-bin cov" + }, + "dependencies": { + "koa": "^2.13.0", + "koa-static-cache": "^5.1.4", + "koa-rewrite": "^3.0.1", + "request": "^2.88.2" + }, + "devDependencies": { + "@midwayjs/cli": "^1.2.36", + "@midwayjs/runtime-engine": "^2.8.2", + "@midwayjs/runtime-mock": "^2.8.2", + "@midwayjs/serverless-fc-starter": "^2.8.9", + "@midwayjs/serverless-fc-trigger": "^2.8.9", + "@midwayjs/serverless-scf-starter": "^2.8.9", + "@midwayjs/serverless-scf-trigger": "^2.8.9", + "supertest": "^4.0.2" + }, + "engines": { + "node": ">= 10" + }, + "files": [ + "index.js" + ], + "repository": { + "type": "git", + "url": "git@github.com:midwayjs/midway-faas.git" + }, + "license": "MIT", + "gitHead": "1afeb34cbb6c0ad49ccdb9cfaebd254ae73afc6a" +} diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/README.md b/packages-serverless/static-layer/test/fixtures/app-fc-404/README.md new file mode 100644 index 000000000000..1f300321df3e --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/README.md @@ -0,0 +1,33 @@ +# test-eaas + +test-eaas + +## QuickStart + + + +see [egg docs][egg] for more detail. + +### Development + +```bash +$ npm i +$ npm run dev +$ open http://localhost:7001/ +``` + +### Deploy + +```bash +$ npm start +$ npm stop +``` + +### npm scripts + +- Use `npm run lint` to check code style. +- Use `npm test` to run unit test. +- Use `npm run autod` to auto detect dependencies upgrade, see [autod](https://www.npmjs.com/package/autod) for more detail. + + +[egg]: https://eggjs.org \ No newline at end of file diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/build/404.html b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/404.html new file mode 100644 index 000000000000..d0eedd275ebd --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/404.html @@ -0,0 +1,10 @@ + + + + + Title + + +404 + + diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.html b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.html new file mode 100644 index 000000000000..a98a137642d2 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.html @@ -0,0 +1,12 @@ + + + + + Title + + + + +hello world + + diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.js b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.js new file mode 100644 index 000000000000..2df17242dfb9 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/index.js @@ -0,0 +1 @@ +console.log('aaa') diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/build/main.css b/packages-serverless/static-layer/test/fixtures/app-fc-404/build/main.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/f.yml b/packages-serverless/static-layer/test/fixtures/app-fc-404/f.yml new file mode 100644 index 000000000000..1c4740f958da --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/f.yml @@ -0,0 +1,11 @@ +service: my-static-demo + +provider: + name: aliyun + +deployType: + type: static + config: + rootDir: build + prefix: / + notFoundUrl: /404.html diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/index.js b/packages-serverless/static-layer/test/fixtures/app-fc-404/index.js new file mode 100644 index 000000000000..6a4835c042ec --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/index.js @@ -0,0 +1,35 @@ +'use strict'; + +const { asyncWrapper } = require('@midwayjs/runtime-engine'); +const { start } = require('@midwayjs/serverless-fc-starter'); +const StaticLayer = require('../../../'); + +let runtime; +let inited; + +async function initializeMethod() { + if(!inited) { + inited = true; + runtime = await start({ + layers: [StaticLayer], + isAppMode: true, + runtimeConfig: { + deployType: { + config: { + rootDir: 'build', + notFoundUrl: '/404.html' + } + } + } + }); + } +} + +exports.initializer = asyncWrapper(async (...args) => { + await initializeMethod(); +}); + +exports.handler = asyncWrapper(async (...args) => { + await initializeMethod(); + return runtime.asyncEvent()(...args); +}); diff --git a/packages-serverless/static-layer/test/fixtures/app-fc-404/package.json b/packages-serverless/static-layer/test/fixtures/app-fc-404/package.json new file mode 100644 index 000000000000..5fd108c44d8b --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc-404/package.json @@ -0,0 +1,21 @@ +{ + "name": "test-app", + "version": "1.0.0", + "private": true, + "dependencies": { + "koa": "^2.15.1" + }, + "devDependencies": { + }, + "engines": { + "node": ">=10.0.0" + }, + "scripts": { + "dev": "node app.js" + }, + "repository": { + "type": "git", + "url": "" + }, + "license": "MIT" +} diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/README.md b/packages-serverless/static-layer/test/fixtures/app-fc/README.md new file mode 100644 index 000000000000..1f300321df3e --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/README.md @@ -0,0 +1,33 @@ +# test-eaas + +test-eaas + +## QuickStart + + + +see [egg docs][egg] for more detail. + +### Development + +```bash +$ npm i +$ npm run dev +$ open http://localhost:7001/ +``` + +### Deploy + +```bash +$ npm start +$ npm stop +``` + +### npm scripts + +- Use `npm run lint` to check code style. +- Use `npm test` to run unit test. +- Use `npm run autod` to auto detect dependencies upgrade, see [autod](https://www.npmjs.com/package/autod) for more detail. + + +[egg]: https://eggjs.org \ No newline at end of file diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/build/index.html b/packages-serverless/static-layer/test/fixtures/app-fc/build/index.html new file mode 100644 index 000000000000..a98a137642d2 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/build/index.html @@ -0,0 +1,12 @@ + + + + + Title + + + + +hello world + + diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/build/index.js b/packages-serverless/static-layer/test/fixtures/app-fc/build/index.js new file mode 100644 index 000000000000..2df17242dfb9 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/build/index.js @@ -0,0 +1 @@ +console.log('aaa') diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/build/main.css b/packages-serverless/static-layer/test/fixtures/app-fc/build/main.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/f.yml b/packages-serverless/static-layer/test/fixtures/app-fc/f.yml new file mode 100644 index 000000000000..1c4740f958da --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/f.yml @@ -0,0 +1,11 @@ +service: my-static-demo + +provider: + name: aliyun + +deployType: + type: static + config: + rootDir: build + prefix: / + notFoundUrl: /404.html diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/index.js b/packages-serverless/static-layer/test/fixtures/app-fc/index.js new file mode 100644 index 000000000000..242f6dbf7097 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/index.js @@ -0,0 +1,34 @@ +'use strict'; + +const { asyncWrapper } = require('@midwayjs/runtime-engine'); +const { start } = require('@midwayjs/serverless-fc-starter'); +const StaticLayer = require('../../../'); + +let runtime; +let inited; + +async function initializeMethod() { + if(!inited) { + inited = true; + runtime = await start({ + layers: [StaticLayer], + isAppMode: true, + runtimeConfig: { + deployType: { + config: { + rootDir: 'build', + } + } + } + }); + } +} + +exports.initializer = asyncWrapper(async (...args) => { + await initializeMethod(); +}); + +exports.handler = asyncWrapper(async (...args) => { + await initializeMethod(); + return runtime.asyncEvent()(...args); +}); diff --git a/packages-serverless/static-layer/test/fixtures/app-fc/package.json b/packages-serverless/static-layer/test/fixtures/app-fc/package.json new file mode 100644 index 000000000000..5fd108c44d8b --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-fc/package.json @@ -0,0 +1,21 @@ +{ + "name": "test-app", + "version": "1.0.0", + "private": true, + "dependencies": { + "koa": "^2.15.1" + }, + "devDependencies": { + }, + "engines": { + "node": ">=10.0.0" + }, + "scripts": { + "dev": "node app.js" + }, + "repository": { + "type": "git", + "url": "" + }, + "license": "MIT" +} diff --git a/packages-serverless/static-layer/test/fixtures/app-scf/README.md b/packages-serverless/static-layer/test/fixtures/app-scf/README.md new file mode 100644 index 000000000000..1f300321df3e --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-scf/README.md @@ -0,0 +1,33 @@ +# test-eaas + +test-eaas + +## QuickStart + + + +see [egg docs][egg] for more detail. + +### Development + +```bash +$ npm i +$ npm run dev +$ open http://localhost:7001/ +``` + +### Deploy + +```bash +$ npm start +$ npm stop +``` + +### npm scripts + +- Use `npm run lint` to check code style. +- Use `npm test` to run unit test. +- Use `npm run autod` to auto detect dependencies upgrade, see [autod](https://www.npmjs.com/package/autod) for more detail. + + +[egg]: https://eggjs.org \ No newline at end of file diff --git a/packages-serverless/static-layer/test/fixtures/app-scf/app.js b/packages-serverless/static-layer/test/fixtures/app-scf/app.js new file mode 100644 index 000000000000..04d31eabc298 --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-scf/app.js @@ -0,0 +1,34 @@ +const Koa = require('koa'); +const Router = require('koa-router'); +const app = new Koa(); +const assert = require('assert'); +const router = new Router(); +const bodyParser = require('koa-bodyparser'); + +router.get('/get', (ctx, next) => { + ctx.type = 'html'; + ctx.body = 'Hello World'; +}); + +router.get('/get/query', (ctx, next) => { + ctx.body = { + query: ctx.query + }; +}); + +router.post('/post', (ctx, next) => { + ctx.body = 'Hello World, post'; +}); + +router.post('/post/body', (ctx, next) => { + ctx.body = { + body: ctx.request.body + }; +}); + +app.use(bodyParser()); +app.use(router.routes()).use(router.allowedMethods()); + +// app.listen(3000); + +module.exports = app; diff --git a/packages-serverless/static-layer/test/fixtures/app-scf/f.yml b/packages-serverless/static-layer/test/fixtures/app-scf/f.yml new file mode 100644 index 000000000000..644969cfc01b --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-scf/f.yml @@ -0,0 +1,6 @@ +service: my-static-demo + +provider: + name: tencent + +deployType: static diff --git a/packages-serverless/static-layer/test/fixtures/app-scf/index.js b/packages-serverless/static-layer/test/fixtures/app-scf/index.js new file mode 100644 index 000000000000..621a0a0ecdef --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-scf/index.js @@ -0,0 +1,27 @@ +'use strict'; + +const { asyncWrapper } = require('@midwayjs/runtime-engine'); +const { start } = require('@midwayjs/serverless-scf-starter'); +const KoaLayer = require('../../../'); + +let runtime; +let inited; + +async function initializeMethod() { + if(!inited) { + inited = true; + runtime = await start({ + layers: [KoaLayer], + isAppMode: true + }); + } +} + +exports.initializer = asyncWrapper(async (...args) => { + await initializeMethod(); +}); + +exports.handler = asyncWrapper(async (...args) => { + await initializeMethod(); + return runtime.asyncEvent()(...args); +}); diff --git a/packages-serverless/static-layer/test/fixtures/app-scf/package.json b/packages-serverless/static-layer/test/fixtures/app-scf/package.json new file mode 100644 index 000000000000..5fd108c44d8b --- /dev/null +++ b/packages-serverless/static-layer/test/fixtures/app-scf/package.json @@ -0,0 +1,21 @@ +{ + "name": "test-app", + "version": "1.0.0", + "private": true, + "dependencies": { + "koa": "^2.15.1" + }, + "devDependencies": { + }, + "engines": { + "node": ">=10.0.0" + }, + "scripts": { + "dev": "node app.js" + }, + "repository": { + "type": "git", + "url": "" + }, + "license": "MIT" +} diff --git a/packages-serverless/static-layer/test/index.test.js b/packages-serverless/static-layer/test/index.test.js new file mode 100644 index 000000000000..c4e16c91c4ca --- /dev/null +++ b/packages-serverless/static-layer/test/index.test.js @@ -0,0 +1,112 @@ +const { createRuntime } = require('@midwayjs/runtime-mock'); +const { HTTPTrigger } = require('@midwayjs/serverless-fc-trigger'); +const FCApiGatewayTrigger = require('@midwayjs/serverless-fc-trigger') + .ApiGatewayTrigger; +const { join } = require('path'); +const request = require('supertest'); + +describe('/test/index.test.ts', () => { + describe('FC test with http trigger', () => { + let runtime; + let app; + + beforeAll(async () => { + const entryDir = join(__dirname, './fixtures/app-fc'); + process.env.ENTRY_DIR = entryDir; + runtime = createRuntime({ + functionDir: entryDir, + }); + await runtime.start(); + app = await runtime.delegate(new HTTPTrigger()); + }); + + afterAll(() => { + if (runtime) { + runtime.close(); + } + process.env.ENTRY_DIR = ''; + }); + + it('should test with get', done => { + request(app) + .get('/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(/hello world/) + .expect(200, done); + }); + }); + + describe('FC test with api gateway', () => { + let runtime; + let app; + + beforeAll(async () => { + const entryDir = join(__dirname, './fixtures/app-fc'); + process.env.ENTRY_DIR = entryDir; + runtime = createRuntime({ + functionDir: entryDir, + }); + await runtime.start(); + app = await runtime.delegate(new FCApiGatewayTrigger()); + }); + + afterAll(() => { + if (runtime) { + runtime.close(); + } + process.env.ENTRY_DIR = ''; + }); + + it('should test with get', done => { + request(app) + .get('/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(/hello world/) + .expect(200, done); + }); + + it('should test 404', done => { + request(app) + .get('/404') + .expect(404, done); + }); + + }); + + describe('FC test with 404', () => { + let runtime; + let app; + + beforeAll(async () => { + const entryDir = join(__dirname, './fixtures/app-fc-404'); + process.env.ENTRY_DIR = entryDir; + runtime = createRuntime({ + functionDir: entryDir, + }); + await runtime.start(); + app = await runtime.delegate(new FCApiGatewayTrigger()); + }); + + afterAll(() => { + if (runtime) { + runtime.close(); + } + process.env.ENTRY_DIR = ''; + }); + + it('should test custom 404 page', done => { + request(app) + .get('/404.html') + .expect(/404/) + .expect(200, done); + }); + + it('should not exists page and get 404 page', done => { + request(app) + .get('/404') + .expect(/404/) + .expect(404, done); + }); + + }); +}); From c6712bea0ca225ccf3ef327d99ff82fc3d827f4b Mon Sep 17 00:00:00 2001 From: Harry Chen Date: Fri, 12 Mar 2021 08:56:53 +0800 Subject: [PATCH 2/3] fix: buffer --- packages-serverless/koa-layer/index.js | 1 + packages-serverless/static-layer/index.js | 24 +---------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/packages-serverless/koa-layer/index.js b/packages-serverless/koa-layer/index.js index 3ae030e3cdb0..9a8132a64f78 100644 --- a/packages-serverless/koa-layer/index.js +++ b/packages-serverless/koa-layer/index.js @@ -29,6 +29,7 @@ module.exports = engine => { method: context.method, headers: context.headers, followRedirect: false, + encoding: null, }; if ( (context.headers['content-type'] || '').indexOf('application/json') >= diff --git a/packages-serverless/static-layer/index.js b/packages-serverless/static-layer/index.js index f1796fa45db4..3245a715935c 100644 --- a/packages-serverless/static-layer/index.js +++ b/packages-serverless/static-layer/index.js @@ -90,30 +90,8 @@ module.exports = engine => { method: context.method, headers: context.headers, followRedirect: false, + encoding: null, }; - if ( - (context.headers['content-type'] || '').indexOf('application/json') >= - 0 - ) { - // post json - if (typeof context.request.body !== 'string') { - requestOption.body = JSON.stringify(context.request.body); - } else { - requestOption.body = context.request.body; - } - } else if ( - (context.headers['content-type'] || '').indexOf('form-urlencoded') >= - 0 - ) { - // post formdata - requestOption.form = context.request.body; - } else if (context.request.body) { - if (typeof context.request.body !== 'string') { - requestOption.form = context.request.body; - } else { - requestOption.body = context.request.body; - } - } request(requestOption, (error, response, body) => { context.res = response; context.status = response.statusCode; From c8c29b13dabf642ca6b57f8d4a885d34dddab879 Mon Sep 17 00:00:00 2001 From: Harry Chen Date: Fri, 12 Mar 2021 09:21:51 +0800 Subject: [PATCH 3/3] fix: png --- packages-serverless/egg-layer/index.js | 4 ++++ packages-serverless/express-layer/index.js | 4 ++++ packages-serverless/koa-layer/index.js | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages-serverless/egg-layer/index.js b/packages-serverless/egg-layer/index.js index dae6b797c8cf..896a5bcad059 100644 --- a/packages-serverless/egg-layer/index.js +++ b/packages-serverless/egg-layer/index.js @@ -68,6 +68,10 @@ module.exports = engine => { headers: context.headers, followRedirect: false, }; + if (context.method === 'GET') { + // get 统一使用 buffer 返回,避免静态资源无法展示 + requestOption.encoding = null; + } if ( (context.headers['content-type'] || '').indexOf('application/json') >= 0 diff --git a/packages-serverless/express-layer/index.js b/packages-serverless/express-layer/index.js index 7b3e6b2f880c..59d4e7676ea7 100644 --- a/packages-serverless/express-layer/index.js +++ b/packages-serverless/express-layer/index.js @@ -31,6 +31,10 @@ module.exports = engine => { headers: context.headers, followRedirect: false, }; + if (context.method === 'GET') { + // get 统一使用 buffer 返回,避免静态资源无法展示 + requestOption.encoding = null; + } if ( (context.headers['content-type'] || '').indexOf('application/json') >= 0 diff --git a/packages-serverless/koa-layer/index.js b/packages-serverless/koa-layer/index.js index 9a8132a64f78..ac6be6022ad1 100644 --- a/packages-serverless/koa-layer/index.js +++ b/packages-serverless/koa-layer/index.js @@ -29,8 +29,11 @@ module.exports = engine => { method: context.method, headers: context.headers, followRedirect: false, - encoding: null, }; + if (context.method === 'GET') { + // get 统一使用 buffer 返回,避免静态资源无法展示 + requestOption.encoding = null; + } if ( (context.headers['content-type'] || '').indexOf('application/json') >= 0