import ResponseFactory from './ResponseFactory.ts' import {Request} from '../Request.ts' import {file_server} from '../../external/std.ts' import {HTTPStatus} from '../../const/http.ts' import {Logging} from '../../service/logging/Logging.ts' import {Injectable} from '../../../../di/src/decorator/Injection.ts' import {PathLike, universal_path} from '../../support/UniversalPath.ts' /** * Response factory to send the contents of a file given its path. * @extends ResponseFactory */ @Injectable() export default class FileResponseFactory extends ResponseFactory { constructor( protected readonly logger: Logging, /** * The path to the file to be sent. * @type string */ public readonly path: PathLike, ) { super() } /** * Write this response factory to the given request's response. * @param {Request} request * @return Request */ public async write(request: Request): Promise { request = await super.write(request) const path = typeof this.path === 'string' ? universal_path(this.path) : this.path const content = await file_server.serveFile(request.to_native, path.to_local) const length = content.headers && content.headers.get('content-length') if ( content.headers && content.body && length ) { request.response.body = content.body request.response.headers.set('Content-Length', length) if ( path.content_type ) request.response.headers.set('Content-Type', path.content_type) } else { this.logger.debug(`Tried to serve file that does not exist: ${path}`) request.response.status = HTTPStatus.NOT_FOUND } return request } }