-import type { IncomingMessage, RequestListener, ServerResponse } from 'node:http'
+import type { IncomingMessage, ServerResponse } from 'node:http'
import { StatusCodes } from 'http-status-codes'
-import { AbstractUIServer } from './AbstractUIServer.js'
-import { UIServerUtils } from './UIServerUtils.js'
import { BaseError } from '../../exception/index.js'
import {
ApplicationProtocolVersion,
+ MapStringifyFormat,
type ProcedureName,
type Protocol,
type ProtocolRequest,
ResponseStatus,
type UIServerConfiguration
} from '../../types/index.js'
-import { Constants, generateUUID, isNotEmptyString, logPrefix, logger } from '../../utils/index.js'
+import {
+ Constants,
+ generateUUID,
+ isNotEmptyString,
+ JSONStringify,
+ logger,
+ logPrefix
+} from '../../utils/index.js'
+import { AbstractUIServer } from './AbstractUIServer.js'
+import { isProtocolAndVersionSupported } from './UIServerUtils.js'
const moduleName = 'UIHttpServer'
GET = 'GET',
PUT = 'PUT',
POST = 'POST',
- PATCH = 'PATCH',
+ PATCH = 'PATCH'
}
export class UIHttpServer extends AbstractUIServer {
}
public start (): void {
- this.httpServer.on('request', this.requestListener.bind(this) as RequestListener)
+ this.httpServer.on('request', this.requestListener.bind(this))
this.startHttpServer()
}
.writeHead(this.responseStatusToStatusCode(payload.status), {
'Content-Type': 'application/json'
})
- .end(JSON.stringify(payload))
+ .end(JSONStringify(payload, undefined, MapStringifyFormat.object))
} else {
logger.error(
`${this.logPrefix(moduleName, 'sendResponse')} Response for unknown request id: ${uuid}`
}
private requestListener (req: IncomingMessage, res: ServerResponse): void {
- this.authenticate(req, (err) => {
+ this.authenticate(req, err => {
if (err != null) {
res
.writeHead(StatusCodes.UNAUTHORIZED, {
'WWW-Authenticate': 'Basic realm=users'
})
.end(`${StatusCodes.UNAUTHORIZED} Unauthorized`)
- .destroy()
+ res.destroy()
req.destroy()
}
})
const [protocol, version, procedureName] = req.url?.split('/').slice(1) as [
Protocol,
ProtocolVersion,
- ProcedureName,
+ ProcedureName
]
const uuid = generateUUID()
this.responseHandlers.set(uuid, res)
try {
const fullProtocol = `${protocol}${version}`
- if (!UIServerUtils.isProtocolAndVersionSupported(fullProtocol)) {
+ if (!isProtocolAndVersionSupported(fullProtocol)) {
throw new BaseError(`Unsupported UI protocol version: '${fullProtocol}'`)
}
this.registerProtocolVersionUIService(version)
- req.on('error', (error) => {
+ req.on('error', error => {
logger.error(
`${this.logPrefix(moduleName, 'requestListener.req.onerror')} Error on HTTP request:`,
error
bodyBuffer.push(chunk)
})
.on('end', () => {
- const body = JSON.parse(Buffer.concat(bodyBuffer).toString()) as RequestPayload
+ let requestPayload: RequestPayload | undefined
+ try {
+ requestPayload = JSON.parse(Buffer.concat(bodyBuffer).toString()) as RequestPayload
+ } catch (error) {
+ this.sendResponse(
+ this.buildProtocolResponse(uuid, {
+ status: ResponseStatus.FAILURE,
+ errorMessage: (error as Error).message,
+ errorStack: (error as Error).stack
+ })
+ )
+ return
+ }
this.uiServices
.get(version)
- ?.requestHandler(
- this.buildProtocolRequest(
- uuid,
- procedureName,
- body ?? Constants.EMPTY_FROZEN_OBJECT
- )
- )
+ ?.requestHandler(this.buildProtocolRequest(uuid, procedureName, requestPayload))
.then((protocolResponse?: ProtocolResponse) => {
if (protocolResponse != null) {
this.sendResponse(protocolResponse)