homebridge-prometheus-exporter/src/adapters/http/fastify.ts
2022-11-13 13:34:33 +01:00

69 lines
2.3 KiB
TypeScript

import Fastify, { type FastifyReply, type FastifyRequest, type HookHandlerDoneFunction } from 'fastify'
import type { HttpAdapter, HttpResponse } from './api'
import type { HttpServer } from '../../http'
function adaptResponseToReply(response: HttpResponse, reply: FastifyReply): void {
if (response.statusCode) {
void reply.code(response.statusCode)
}
if (response.headers) {
void reply.headers(response.headers)
}
if (response.body) {
void reply.send(response.body)
}
}
function formatCombinedLog(request: FastifyRequest, reply: FastifyReply): string {
const remoteAddress = [request.socket.remoteAddress, request.socket.remotePort].filter((v) => v != null).join(':')
const userAgent = request.headers['user-agent'] || ''
const contentType = request.headers['content-type'] || ''
return `${remoteAddress} - "${request.method} ${request.url} HTTP/${request.raw.httpVersion}" ${reply.statusCode} "${request.protocol}://${request.hostname}" "${userAgent}" "${contentType}"`
}
export const serve: HttpAdapter = async (server: HttpServer) => {
const fastify = Fastify({
logger: false,
serverFactory: server.serverFactory,
})
fastify.addHook('onResponse', (request: FastifyRequest, reply: FastifyReply) => {
if (reply.statusCode >= 400) {
server.log?.warn(formatCombinedLog(request, reply))
} else if (server.debug) {
server.log?.debug(formatCombinedLog(request, reply))
}
})
fastify.addHook('onRequest', (request: FastifyRequest, reply: FastifyReply, next: HookHandlerDoneFunction) => {
const response = server.onRequest()
if (response) {
adaptResponseToReply(response, reply)
}
next()
})
fastify.setErrorHandler(async (error, request: FastifyRequest, reply: FastifyReply) => {
adaptResponseToReply(server.onError(error), reply)
})
fastify.setNotFoundHandler(async (request: FastifyRequest, reply: FastifyReply) => {
adaptResponseToReply(server.onNotFound(), reply)
})
fastify.get('/metrics', async (request: FastifyRequest, reply: FastifyReply) => {
adaptResponseToReply(server.onMetrics(), reply)
})
await fastify.listen({ port: server.port, host: '::' })
return {
shutdown() {
void fastify.close()
},
}
}