File-based response support & static server
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Clean up UniversalPath implementation
- Use Readable/Writable types correctly for stream methods
- Add .list() methods for getting child files
- Make Response body specify explicit types and support
writing Readable streams to the body
- Create a static file server that supports directory listing
This commit is contained in:
@@ -2,6 +2,7 @@ import {Request} from './Request'
|
||||
import {ErrorWithContext, HTTPStatus, BehaviorSubject} from '../../util'
|
||||
import {ServerResponse} from 'http'
|
||||
import {HTTPCookieJar} from '../kernel/HTTPCookieJar'
|
||||
import {Readable} from 'stream'
|
||||
|
||||
/**
|
||||
* Error thrown when the server tries to re-send headers after they have been sent once.
|
||||
@@ -47,7 +48,7 @@ export class Response {
|
||||
private isBlockingWriteback = false
|
||||
|
||||
/** The body contents that should be written to the response. */
|
||||
public body = ''
|
||||
public body: string | Buffer | Uint8Array | Readable = ''
|
||||
|
||||
/**
|
||||
* Behavior subject fired right before the response content is written.
|
||||
@@ -192,18 +193,29 @@ export class Response {
|
||||
* Write the headers and specified data to the client.
|
||||
* @param data
|
||||
*/
|
||||
public async write(data: unknown): Promise<void> {
|
||||
public async write(data: string | Buffer | Uint8Array | Readable): Promise<void> {
|
||||
return new Promise<void>((res, rej) => {
|
||||
if ( !this.sentHeaders ) {
|
||||
this.sendHeaders()
|
||||
}
|
||||
this.serverResponse.write(data, error => {
|
||||
if ( error ) {
|
||||
rej(error)
|
||||
} else {
|
||||
res()
|
||||
}
|
||||
})
|
||||
|
||||
if ( data instanceof Readable ) {
|
||||
data.pipe(this.serverResponse)
|
||||
.on('finish', () => {
|
||||
res()
|
||||
})
|
||||
.on('error', error => {
|
||||
rej(error)
|
||||
})
|
||||
} else {
|
||||
this.serverResponse.write(data, error => {
|
||||
if ( error ) {
|
||||
rej(error)
|
||||
} else {
|
||||
res()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -212,9 +224,14 @@ export class Response {
|
||||
*/
|
||||
public async send(): Promise<void> {
|
||||
await this.sending$.next(this)
|
||||
this.setHeader('Content-Length', String(this.body?.length ?? 0))
|
||||
|
||||
if ( !(this.body instanceof Readable) ) {
|
||||
this.setHeader('Content-Length', String(this.body?.length ?? 0))
|
||||
}
|
||||
|
||||
await this.write(this.body ?? '')
|
||||
this.end()
|
||||
|
||||
await this.sent$.next(this)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user