Skip to content

Commit

Permalink
chore(runtime): use gzip+base64 encode debug request header instead o…
Browse files Browse the repository at this point in the history
…f uri encode (#1652)
  • Loading branch information
maslow committed Nov 7, 2023
1 parent 75b6084 commit 623940c
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 30 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"telepresence",
"tolerations",
"uids",
"ungzip",
"upsert",
"upserted",
"urlencode",
Expand Down
22 changes: 22 additions & 0 deletions runtimes/nodejs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions runtimes/nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@aws-sdk/s3-request-presigner": "^3.231.0",
"@kubernetes/client-node": "^0.18.0",
"@lafjs/cloud": "^1.0.0-beta.12",
"@types/pako": "^2.0.2",
"axios": "^1.4.0",
"chalk": "^4.1.2",
"chatgpt": "^5.2.5",
Expand All @@ -50,6 +51,7 @@
"multer": "^1.4.5-lts.1",
"node-modules-utils": "^0.8.2",
"nodemailer": "^6.6.3",
"pako": "^2.1.0",
"validator": "^13.7.0",
"ws": "^8.11.0"
},
Expand Down
59 changes: 38 additions & 21 deletions runtimes/nodejs/src/handler/invoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
FunctionContext,
ICloudFunctionData,
} from '../support/engine'
import pako from 'pako'
import { base64ToUint8Array, uint8ArrayToBase64 } from '../support/utils'

export async function handleInvokeFunction(req: IRequest, res: Response) {
const ctx: FunctionContext = {
Expand All @@ -26,12 +28,6 @@ export async function handleInvokeFunction(req: IRequest, res: Response) {
}

let useInterceptor = true

// intercept the request, skip websocket request
if (true === req.method.startsWith('WebSocket:')) {
useInterceptor = false
}

if (!FunctionCache.get(INTERCEPTOR_FUNCTION_NAME)) {
useInterceptor = false
}
Expand Down Expand Up @@ -126,19 +122,31 @@ async function invokeDebug(
.send('permission denied: invalid develop token')
}

// get func_data from header
const funcStr = ctx.request.get('x-laf-func-data')
if (!funcStr) {
return ctx.response.status(400).send('x-laf-func-data is required')
}

// parse func_data
let funcData: ICloudFunctionData
try {
const decoded = decodeURIComponent(funcStr)
funcData = JSON.parse(decoded)
} catch (error) {
return ctx.response.status(400).send('x-laf-func-data is invalid')

// get func_data from header `x-laf-debug-data`
if (ctx.request.get('x-laf-debug-data')) {
const funcStr = ctx.request.get('x-laf-debug-data')
try {
// decode base64 string
const compressed = base64ToUint8Array(funcStr)
const restored = pako.ungzip(compressed, { to: 'string' })
funcData = JSON.parse(restored)
} catch (error) {
return ctx.response.status(400).send('x-laf-debug-data is invalid')
}
} else if (ctx.request.get('x-laf-func-data')) {
// reserve 'x-laf-func-data' check to keep compatible to old clients (laf-web, laf-cli)
const funcStr = ctx.request.get('x-laf-func-data')
try {
const decoded = decodeURIComponent(funcStr)
funcData = JSON.parse(decoded)
} catch (error) {
return ctx.response.status(400).send('x-laf-func-data is invalid')
}
} else {
return ctx.response.status(400).send('x-laf-debug-data is required')
}

const requestId = ctx.requestId
Expand All @@ -160,14 +168,23 @@ async function invokeDebug(
ctx.__function_name = funcName
const result = await func.execute(ctx, useInterceptor, debugConsole)


// set logs to response header
if (result.error) {
debugConsole.error(result.error)
}
const logs = encodeURIComponent(debugConsole.getLogs())
ctx.response.set('x-laf-func-logs', logs)
ctx.response.set('x-laf-func-time-usage', result.time_usage.toString())

const logs = debugConsole.getLogs()
if (ctx.request.get('x-laf-debug-data')) {
const compressed = pako.gzip(logs)
const base64Encoded = uint8ArrayToBase64(compressed)
ctx.response.set('x-laf-debug-logs', base64Encoded)
} else if (ctx.request.get('x-laf-func-data')) {
// keep compatible for old version clients(laf web & laf cli)
const encoded = encodeURIComponent(logs)
ctx.response.set('x-laf-func-logs', encoded)
}

ctx.response.set('x-laf-debug-time-usage', result.time_usage.toString())

if (result.error) {
return ctx.response.status(500).send({
Expand Down
9 changes: 9 additions & 0 deletions runtimes/nodejs/src/support/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ export function sleep(ms: number) {
export function md5(content: string) {
return crypto.createHash('md5').update(content).digest('hex')
}

export function uint8ArrayToBase64(buffer: Uint8Array) {
return Buffer.from(buffer).toString('base64')
}

export function base64ToUint8Array(base64: string) {
const buffer = Buffer.from(base64, 'base64')
return new Uint8Array(buffer)
}
1 change: 0 additions & 1 deletion runtimes/nodejs/src/support/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ async function handleWebSocketEvent(
}

const module = FunctionModule.get(WEBSOCKET_FUNCTION_NAME)
console.log(module)
const handler = module.default || module.main || module
if(typeof handler === 'function') {
await handler(param)
Expand Down
2 changes: 1 addition & 1 deletion server/src/gateway/website-task.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class WebsiteTaskService {
bucketName: site.bucketName,
})

assert(bucketDomain, 'bucket domain not found')
assert(bucketDomain, `bucket domain not found: ${site.bucketName}`)

// create website custom certificate if custom domain is set
// Warning: create certificate before ingress, otherwise apisix ingress will not work
Expand Down
14 changes: 7 additions & 7 deletions server/src/storage/bucket-task.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,6 @@ export class BucketTaskService {
this.logger.debug('minio bucket deleted:', doc.name)
}

// delete bucket domain
const domain = await this.bucketDomainService.findOne(doc)
if (domain) {
await this.bucketDomainService.deleteOne(doc)
this.logger.debug('bucket domain deleted:', domain)
}

// delete bucket website if exists
const websiteRes = await db
.collection<WebsiteHosting>('WebsiteHosting')
Expand All @@ -174,6 +167,13 @@ export class BucketTaskService {
this.logger.log('website state set to Deleted for bucket: ' + doc.name)
}

// delete bucket domain
const domain = await this.bucketDomainService.findOne(doc)
if (domain) {
await this.bucketDomainService.deleteOne(doc)
this.logger.debug('bucket domain deleted:', domain)
}

// update phase to `Deleted`
const updated = await db
.collection<StorageBucket>('StorageBucket')
Expand Down

0 comments on commit 623940c

Please sign in to comment.