Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(runtime): use gzip+base64 encode debug request header instead of uri encode #1652

Merged
merged 1 commit into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"openapi",
"openebs",
"OVERLIMIT",
"pako",
"passw",
"pgdb",
"presigner",
Expand All @@ -109,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