You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.7 KiB
52 lines
1.7 KiB
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> {
|
|
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
|
|
}
|
|
}
|