send-stream
Version:
Streaming file serving library with Range and conditional-GET support from file system or any streaming sources.
199 lines (198 loc) • 8.99 kB
TypeScript
import type { ServerResponse } from 'node:http';
import { IncomingMessage } from 'node:http';
import type { IncomingHttpHeaders, Http2ServerResponse, ServerHttp2Stream } from 'node:http2';
import { Http2ServerRequest } from 'node:http2';
import type { Readable } from 'node:stream';
import { StreamResponse } from './response';
import type { ResponseHeaders } from './utils';
import { StreamRange } from './utils';
import type { StorageOptions, PrepareResponseOptions, StorageRequestHeaders, StorageInfo, StorageSendOptions } from './types';
/**
* send-stream storage base class
* @template Reference - reference type
* @template AttachedData - attached data type
*/
export declare abstract class Storage<Reference, AttachedData> {
/**
* Default mime type or false
*/
readonly defaultMimeType: string | false;
/**
* Max ranges for multiple range GET requests
*/
readonly maxRanges: number;
/**
* Produces week tags when true
*/
readonly weakEtags: boolean;
/**
* Mime type lookup function
*/
readonly mimeTypeLookup: NonNullable<StorageOptions['mimeTypeLookup']>;
/**
* Mime type default charset function
*/
readonly mimeTypeDefaultCharset: NonNullable<StorageOptions['mimeTypeDefaultCharset']>;
/**
* Dynamic compression preferences or false
*/
readonly dynamicCompression: {
encodingPreferences: ReadonlyMap<string, {
order: number;
}>;
identityEncodingPreference: {
order: number;
};
} | false;
/**
* Mime type compressible function
*/
readonly mimeTypeCompressible: NonNullable<StorageOptions['mimeTypeCompressible']>;
/**
* Minimum length to produce compressed content
*/
readonly dynamicCompressionMinLength: number;
/**
* Create storage
* @param opts - storage options
*/
constructor(opts?: StorageOptions);
/**
* Create last-mofified header value from storage information (uses mtimeMs)
* @param storageInfo - storage information
* @returns last-mofified header
*/
createLastModified(storageInfo: StorageInfo<AttachedData>): string | false;
/**
* Create etag header value from storage information (uses mtimeMs, size and contentEncoding)
* @param storageInfo - storage information
* @returns etag header
*/
createEtag(storageInfo: StorageInfo<AttachedData>): string | false;
/**
* Create cache-control header value from storage information (return always public, max-age=0 unless overriden)
* @param storageInfo - storage information
* @returns cache-control header
*/
createCacheControl(storageInfo: StorageInfo<AttachedData>): string | false;
/**
* Create mime type for content-type header value from storage information
* @param storageInfo - storage information (unused unless overriden)
* @returns mime type
*/
createMimeType(storageInfo: StorageInfo<AttachedData>): string | false;
/**
* Create charset that will be appended with mime type into content-type header
* @param storageInfo - storage information (unused unless overriden)
* @param mimeType - mime type
* @returns charset
*/
createMimeTypeCharset(storageInfo: StorageInfo<AttachedData>, mimeType: string): string | false;
/**
* Create content-disposition header type from storage information (return always inline unless overriden)
* @param storageInfo - storage information (unused unless overriden)
* @returns content-disposition header type
*/
createContentDispositionType(storageInfo: StorageInfo<AttachedData>): 'inline' | 'attachment' | undefined;
/**
* Create content-disposition header filename from storage information
* (return always the original filename unless overriden)
* @param storageInfo - storage information
* @returns content-disposition header filename
*/
createContentDispositionFilename(storageInfo: StorageInfo<AttachedData>): string | undefined;
/**
* Prepare to send file
* @param reference - file reference
* @param req - request headers or request objects
* @param [opts] - options
* @returns status, response headers and body to use
* @throws when method is incorrect or when storage can not create the storage stream
*/
prepareResponse(reference: Reference, req: IncomingMessage | Http2ServerRequest | IncomingHttpHeaders, opts?: PrepareResponseOptions): Promise<StreamResponse<AttachedData>>;
/**
* Send file directly to response
* @param reference - file reference
* @param req - request headers or request objects
* @param res - http response
* @param [opts] - options
* @throws when method is incorrect or when storage can not create the storage stream
*/
send(reference: Reference, req: IncomingMessage | Http2ServerRequest | IncomingHttpHeaders, res: ServerResponse | Http2ServerResponse | ServerHttp2Stream, opts?: StorageSendOptions): Promise<void>;
/**
* Create compressed stream
* (for gzip / brotli encodings only but this method can be overidden to eventually implement other encodings)
* @param stream - stream to compress
* @param contentEncoding - 'br' for brotli encoding or 'gzip' for gzip encoding, other values are not supported
* @param expectedSize - expected stream size
* @returns compressed stream
* @throws if content encoding is not supported
*/
createCompressedStream(stream: Readable, contentEncoding: string, expectedSize?: number): Readable;
/**
* Create Method Not Allowed error response
* @param isHeadMethod - true if HEAD method is used
* @param allowedMethods - allowed methods for Allow header
* @returns Method Not Allowed response
*/
createMethodNotAllowedError(isHeadMethod: boolean, allowedMethods: readonly string[]): StreamResponse<AttachedData>;
/**
* Create storage error response (Not Found response usually)
* @param isHeadMethod - true if HEAD method is used
* @param error - the error causing this response
* @returns the error response
*/
createStorageError(isHeadMethod: boolean, error: unknown): StreamResponse<AttachedData>;
/**
* Create Not Modified response
* @param responseHeaders - response headers
* @param storageInfo - the current storage info
* @returns the Not Modified response
*/
createNotModifiedResponse(responseHeaders: ResponseHeaders, storageInfo: StorageInfo<AttachedData>): StreamResponse<AttachedData>;
/**
* Create the Precondition Failed error response
* @param isHeadMethod - true if HEAD method is used
* @param storageInfo - the current storage info
* @returns the Precondition Failed error response
*/
createPreconditionFailedError(isHeadMethod: boolean, storageInfo: StorageInfo<AttachedData>): StreamResponse<AttachedData>;
/**
* Create the Range Not Satisfiable error response
* @param isHeadMethod - true if HEAD method is used
* @param size - size of content for Content-Range header
* @param storageInfo - the current storage info
* @returns the Range Not Satisfiable error response
*/
createRangeNotSatisfiableError(isHeadMethod: boolean, size: number, storageInfo: StorageInfo<AttachedData>): StreamResponse<AttachedData>;
/**
* Create the successful OK (200) or Partial Content (206) response
* (the http code could also be the one set in parameters)
* @param statusCode - 200 or 206 or the statusCode set in parameters
* @param responseHeaders - the response headers
* @param stream - the content stream
* @param storageInfo - the current storage info
* @returns the successful response
*/
createSuccessfulResponse(statusCode: number, responseHeaders: ResponseHeaders, stream: Readable, storageInfo: StorageInfo<AttachedData>): StreamResponse<AttachedData>;
/**
* Open file and retrieve storage information (filename, modification date, size, ...)
* @param reference - file reference
* @param requestHeaders - request headers
* @returns StorageInfo object
*/
abstract open(reference: Reference, requestHeaders: StorageRequestHeaders): Promise<StorageInfo<AttachedData>>;
/**
* Create readable stream from storage information
* @param storageInfo - storage information
* @param range - range to use or undefined if size is unknown
* @param autoClose - true if stream should close itself
* @returns readable stream
*/
abstract createReadableStream(storageInfo: StorageInfo<AttachedData>, range: StreamRange | undefined, autoClose: boolean): Readable;
/**
* Close storage information (if needed)
* @param storageInfo - storage information
*/
abstract close(storageInfo: StorageInfo<AttachedData>): Promise<void>;
}