|
|
|
@ -15,6 +15,7 @@ import {error} from "../http/response/ErrorResponseFactory";
|
|
|
|
|
import {ExecuteResolvedRoutePreflightHTTPModule} from "../http/kernel/module/ExecuteResolvedRoutePreflightHTTPModule";
|
|
|
|
|
import {ExecuteResolvedRoutePostflightHTTPModule} from "../http/kernel/module/ExecuteResolvedRoutePostflightHTTPModule";
|
|
|
|
|
import {ParseIncomingBodyHTTPModule} from "../http/kernel/module/ParseIncomingBodyHTTPModule";
|
|
|
|
|
import {Config} from "./Config";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Application unit that starts the HTTP/S server, creates Request and Response objects
|
|
|
|
@ -25,6 +26,9 @@ export class HTTPServer extends Unit {
|
|
|
|
|
@Inject()
|
|
|
|
|
protected readonly logging!: Logging
|
|
|
|
|
|
|
|
|
|
@Inject()
|
|
|
|
|
protected readonly config!: Config
|
|
|
|
|
|
|
|
|
|
@Inject()
|
|
|
|
|
protected readonly kernel!: HTTPKernel
|
|
|
|
|
|
|
|
|
@ -32,7 +36,7 @@ export class HTTPServer extends Unit {
|
|
|
|
|
protected server?: Server
|
|
|
|
|
|
|
|
|
|
public async up() {
|
|
|
|
|
const port = 8000
|
|
|
|
|
const port = this.config.get('server.port', 8000)
|
|
|
|
|
|
|
|
|
|
// TODO register these by config
|
|
|
|
|
PoweredByHeaderInjectionHTTPModule.register(this.kernel)
|
|
|
|
@ -68,18 +72,26 @@ export class HTTPServer extends Unit {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public get handler() {
|
|
|
|
|
const timeout = this.config.get('server.timeout', 10000)
|
|
|
|
|
|
|
|
|
|
return async (request: IncomingMessage, response: ServerResponse) => {
|
|
|
|
|
const extolloReq = new Request(request, response)
|
|
|
|
|
|
|
|
|
|
// FIXME make timeout configurable
|
|
|
|
|
withTimeout(10000, extolloReq.response.sent$.toPromise())
|
|
|
|
|
withTimeout(timeout, extolloReq.response.sent$.toPromise())
|
|
|
|
|
.onTime(req => {
|
|
|
|
|
this.logging.verbose(`Request lifecycle finished on time. (Path: ${extolloReq.path})`)
|
|
|
|
|
})
|
|
|
|
|
.late(req => {
|
|
|
|
|
this.logging.warn(`Request lifecycle finished late, so an error response was returned! (Path: ${extolloReq.path})`)
|
|
|
|
|
if ( !extolloReq.bypassTimeout ) {
|
|
|
|
|
this.logging.warn(`Request lifecycle finished late, so an error response was returned! (Path: ${extolloReq.path})`)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.timeout(() => {
|
|
|
|
|
if ( extolloReq.bypassTimeout ) {
|
|
|
|
|
this.logging.info(`Request lifecycle has timed out, but bypassRequest was set. (Path: ${extolloReq.path})`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.logging.error(`Request lifecycle has timed out. Will send error response instead. (Path: ${extolloReq.path})`)
|
|
|
|
|
extolloReq.response.setStatus(HTTPStatus.REQUEST_TIMEOUT)
|
|
|
|
|
extolloReq.response.body = 'Sorry, your request timed out.'
|
|
|
|
|