@adonisjs/http-server
Version:
AdonisJS HTTP server with support packed with Routing and Cookies
632 lines (631 loc) • 23.3 kB
TypeScript
import Macroable from '@poppinss/macroable';
import type { Encryption } from '@adonisjs/encryption';
import { ServerResponse, IncomingMessage } from 'node:http';
import type { Qs } from './qs.js';
import { Redirect } from './redirect.js';
import type { Router } from './router/main.js';
import type { HttpContext } from './http_context/main.js';
import type { CastableHeader, CookieOptions, ResponseConfig, ResponseStream } from './types/response.js';
/**
* The response is a wrapper over [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse)
* streamlining the process of writing response body and automatically setting up appropriate headers.
*/
export declare class Response extends Macroable {
#private;
request: IncomingMessage;
response: ServerResponse;
/**
* Does response has body set that will written to the
* response socket at the end of the request
*/
get hasLazyBody(): boolean;
/**
* Find if the response has non-stream content
*/
get hasContent(): boolean;
/**
* Returns true when response body is set using "response.stream"
* method
*/
get hasStream(): boolean;
/**
* Returns true when response body is set using "response.download"
* or "response.attachment" methods
*/
get hasFileToStream(): boolean;
/**
* Returns the response content. Check if the response
* has content using the "hasContent" method
*/
get content(): [any, boolean, (string | undefined)?] | undefined;
/**
* Returns reference to the stream set using "response.stream"
* method
*/
get outgoingStream(): import("stream").Readable | undefined;
/**
* Returns reference to the file path set using "response.stream"
* method.
*/
get fileToStream(): {
path: string;
generateEtag: boolean;
} | undefined;
/**
* Lazy body is used to set the response body. However, do not
* write it on the socket immediately unless `response.finish`
* is called.
*/
lazyBody: Partial<{
content: [any, boolean, string?];
stream: [ResponseStream, ((error: NodeJS.ErrnoException) => [string, number?])?];
fileToStream: [string, boolean, ((error: NodeJS.ErrnoException) => [string, number?])?];
}>;
/**
* The ctx will be set by the context itself. It creates a circular
* reference
*/
ctx?: HttpContext;
constructor(request: IncomingMessage, response: ServerResponse, encryption: Encryption, config: ResponseConfig, router: Router, qs: Qs);
/**
* Returns a boolean telling if response is finished or not.
* Any more attempts to update headers or body will result
* in raised exceptions.
*/
get finished(): boolean;
/**
* Returns a boolean telling if response headers has been sent or not.
* Any more attempts to update headers will result in raised
* exceptions.
*/
get headersSent(): boolean;
/**
* Returns a boolean telling if response headers and body is written
* or not. When value is `true`, you can feel free to write headers
* and body.
*/
get isPending(): boolean;
/**
* Writes the body with appropriate response headers. Etag header is set
* when `generateEtag` is set to `true`.
*
* Empty body results in `204`.
*/
protected writeBody(content: any, generateEtag: boolean, jsonpCallbackName?: string): void;
/**
* Stream the body to the response and handles cleaning up the stream
*/
protected streamBody(body: ResponseStream, errorCallback?: (error: NodeJS.ErrnoException) => [string, number?]): Promise<void>;
/**
* Downloads a file by streaming it to the response
*/
protected streamFileForDownload(filePath: string, generateEtag: boolean, errorCallback?: (error: NodeJS.ErrnoException) => [string, number?]): Promise<void>;
/**
* Listen for the event the response is written
* to the TCP socket.
*
* Under the hood the callback is registered with
* the "https://github.com/jshttp/on-finished" package
*/
onFinish(callback: (err: Error | null, response: ServerResponse) => void): void;
/**
* Writes headers with the Node.js res object using the
* response.setHeader method
*/
relayHeaders(): void;
/**
* Calls res.writeHead on the Node.js res object.
*/
writeHead(statusCode?: number): this;
/**
* Returns the existing value for a given HTTP response
* header.
*/
getHeader(key: string): import("http").OutgoingHttpHeader | undefined;
/**
* Get response headers
*/
getHeaders(): {
[x: string]: import("http").OutgoingHttpHeader | undefined;
accept?: string | string[] | undefined;
"accept-charset"?: string | string[] | undefined;
"accept-encoding"?: string | string[] | undefined;
"accept-language"?: string | string[] | undefined;
"accept-ranges"?: string | undefined;
"access-control-allow-credentials"?: string | undefined;
"access-control-allow-headers"?: string | undefined;
"access-control-allow-methods"?: string | undefined;
"access-control-allow-origin"?: string | undefined;
"access-control-expose-headers"?: string | undefined;
"access-control-max-age"?: string | undefined;
"access-control-request-headers"?: string | undefined;
"access-control-request-method"?: string | undefined;
age?: string | undefined;
allow?: string | undefined;
authorization?: string | undefined;
"cache-control"?: string | undefined;
"cdn-cache-control"?: string | undefined;
connection?: string | string[] | undefined;
"content-disposition"?: string | undefined;
"content-encoding"?: string | undefined;
"content-language"?: string | undefined;
"content-length"?: string | number | undefined;
"content-location"?: string | undefined;
"content-range"?: string | undefined;
"content-security-policy"?: string | undefined;
"content-security-policy-report-only"?: string | undefined;
"content-type"?: string | undefined;
cookie?: string | string[] | undefined;
dav?: string | string[] | undefined;
dnt?: string | undefined;
date?: string | undefined;
etag?: string | undefined;
expect?: string | undefined;
expires?: string | undefined;
forwarded?: string | undefined;
from?: string | undefined;
host?: string | undefined;
"if-match"?: string | undefined;
"if-modified-since"?: string | undefined;
"if-none-match"?: string | undefined;
"if-range"?: string | undefined;
"if-unmodified-since"?: string | undefined;
"last-modified"?: string | undefined;
link?: string | string[] | undefined;
location?: string | undefined;
"max-forwards"?: string | undefined;
origin?: string | undefined;
pragma?: string | string[] | undefined;
"proxy-authenticate"?: string | string[] | undefined;
"proxy-authorization"?: string | undefined;
"public-key-pins"?: string | undefined;
"public-key-pins-report-only"?: string | undefined;
range?: string | undefined;
referer?: string | undefined;
"referrer-policy"?: string | undefined;
refresh?: string | undefined;
"retry-after"?: string | undefined;
"sec-websocket-accept"?: string | undefined;
"sec-websocket-extensions"?: string | string[] | undefined;
"sec-websocket-key"?: string | undefined;
"sec-websocket-protocol"?: string | string[] | undefined;
"sec-websocket-version"?: string | undefined;
server?: string | undefined;
"set-cookie"?: string | string[] | undefined;
"strict-transport-security"?: string | undefined;
te?: string | undefined;
trailer?: string | undefined;
"transfer-encoding"?: string | undefined;
"user-agent"?: string | undefined;
upgrade?: string | undefined;
"upgrade-insecure-requests"?: string | undefined;
vary?: string | undefined;
via?: string | string[] | undefined;
warning?: string | undefined;
"www-authenticate"?: string | string[] | undefined;
"x-content-type-options"?: string | undefined;
"x-dns-prefetch-control"?: string | undefined;
"x-frame-options"?: string | undefined;
"x-xss-protection"?: string | undefined;
};
/**
* Set header on the response. To `append` values to the existing header, we suggest
* using [[append]] method.
*
* If `value` is non existy, then header won't be set.
*
* @example
* ```js
* response.header('content-type', 'application/json')
* ```
*/
header(key: string, value: CastableHeader): this;
/**
* Append value to an existing header. To replace the value, we suggest using
* [[header]] method.
*
* If `value` is not existy, then header won't be set.
*
* @example
* ```js
* response.append('set-cookie', 'username=virk')
* ```
*/
append(key: string, value: CastableHeader): this;
/**
* Adds HTTP response header, when it doesn't exists already.
*/
safeHeader(key: string, value: CastableHeader): this;
/**
* Removes the existing response header from being sent.
*/
removeHeader(key: string): this;
/**
* Returns the status code for the response
*/
getStatus(): number;
/**
* Set HTTP status code
*/
status(code: number): this;
/**
* Set's status code only when it's not explictly
* set
*/
safeStatus(code: number): this;
/**
* Set response type by looking up for the mime-type using
* partial types like file extensions.
*
* Make sure to read [mime-types](https://www.npmjs.com/package/mime-types) docs
* too.
*
* @example
* ```js
* response.type('.json') // Content-type: application/json
* ```
*/
type(type: string, charset?: string): this;
/**
* Set the Vary HTTP header
*/
vary(field: string | string[]): this;
/**
* Set etag by computing hash from the body. This class will set the etag automatically
* when `etag = true` in the defined config object.
*
* Use this function, when you want to compute etag manually for some other resons.
*/
setEtag(body: any, weak?: boolean): this;
/**
* Set X-Request-Id header by copying the header value from the request if it exists.
*
*/
setRequestId(): this;
/**
* Returns a boolean telling if the new response etag evaluates same
* as the request header `if-none-match`. In case of `true`, the
* server must return `304` response, telling the browser to
* use the client cache.
*
* You won't have to deal with this method directly, since AdonisJs will
* handle this for you when `http.etag = true` inside `config/app.js` file.
*
* However, this is how you can use it manually.
*
* @example
* ```js
* const responseBody = view.render('some-view')
*
* // sets the HTTP etag header for response
* response.setEtag(responseBody)
*
* if (response.fresh()) {
* response.sendStatus(304)
* } else {
* response.send(responseBody)
* }
* ```
*/
fresh(): boolean;
/**
* Returns the response body. Returns null when response
* body is a stream
*/
getBody(): any;
/**
* Send the body as response and optionally generate etag. The default value
* is read from `config/app.js` file, using `http.etag` property.
*
* This method buffers the body if `explicitEnd = true`, which is the default
* behavior and do not change, unless you know what you are doing.
*/
send(body: any, generateEtag?: boolean): void;
/**
* Alias of [[send]]
*/
json(body: any, generateEtag?: boolean): void;
/**
* Writes response as JSONP. The callback name is resolved as follows, with priority
* from top to bottom.
*
* 1. Explicitly defined as 2nd Param.
* 2. Fetch from request query string.
* 3. Use the config value `http.jsonpCallbackName` from `config/app.js`.
* 4. Fallback to `callback`.
*
* This method buffers the body if `explicitEnd = true`, which is the default
* behavior and do not change, unless you know what you are doing.
*/
jsonp(body: any, callbackName?: string, generateEtag?: boolean): void;
/**
* Pipe stream to the response. This method will gracefully destroy
* the stream, avoiding memory leaks.
*
* If `raiseErrors=false`, then this method will self handle all the exceptions by
* writing a generic HTTP response. To have more control over the error, it is
* recommended to set `raiseErrors=true` and wrap this function inside a
* `try/catch` statement.
*
* Streaming a file from the disk and showing 404 when file is missing.
*
* @example
* ```js
* // Errors handled automatically with generic HTTP response
* response.stream(fs.createReadStream('file.txt'))
*
* // Manually handle (note the await call)
* try {
* await response.stream(fs.createReadStream('file.txt'))
* } catch () {
* response.status(404).send('File not found')
* }
* ```
*/
stream(body: ResponseStream, errorCallback?: (error: NodeJS.ErrnoException) => [string, number?]): void;
/**
* Download file by streaming it from the file path. This method will setup
* appropriate `Content-type`, `Content-type` and `Last-modified` headers.
*
* Unexpected stream errors are handled gracefully to avoid memory leaks.
*
* If `raiseErrors=false`, then this method will self handle all the exceptions by
* writing a generic HTTP response. To have more control over the error, it is
* recommended to set `raiseErrors=true` and wrap this function inside a
* `try/catch` statement.
*
* @example
* ```js
* // Errors handled automatically with generic HTTP response
* response.download('somefile.jpg')
*
* // Manually handle (note the await call)
* try {
* await response.download('somefile.jpg')
* } catch (error) {
* response.status(error.code === 'ENOENT' ? 404 : 500)
* response.send('Cannot process file')
* }
* ```
*/
download(filePath: string, generateEtag?: boolean, errorCallback?: (error: NodeJS.ErrnoException) => [string, number?]): void;
/**
* Download the file by forcing the user to save the file vs displaying it
* within the browser.
*
* Internally calls [[download]]
*/
attachment(filePath: string, name?: string, disposition?: string, generateEtag?: boolean, errorCallback?: (error: NodeJS.ErrnoException) => [string, number?]): void;
/**
* Set the location header.
*
* @example
* ```js
* response.location('/login')
* ```
*/
location(url: string): this;
/**
* Redirect the request.
*
* @example
* ```js
* response.redirect('/foo')
* response.redirect().toRoute('foo.bar')
* response.redirect().back()
* ```
*/
redirect(): Redirect;
redirect(path: string, forwardQueryString?: boolean, statusCode?: number): void;
/**
* Abort the request with custom body and a status code. 400 is
* used when status is not defined
*/
abort(body: any, status?: number): never;
/**
* Abort the request with custom body and a status code when
* passed condition returns `true`
*/
abortIf(condition: unknown, body: any, status?: number): asserts condition is undefined | null | false;
/**
* Abort the request with custom body and a status code when
* passed condition returns `false`
*/
abortUnless<T>(condition: T, body: any, status?: number): asserts condition is Exclude<T, undefined | null | false>;
/**
* Set signed cookie as the response header. The inline options overrides
* all options from the config.
*/
cookie(key: string, value: any, options?: Partial<CookieOptions>): this;
/**
* Set encrypted cookie as the response header. The inline options overrides
* all options from the config.
*/
encryptedCookie(key: string, value: any, options?: Partial<CookieOptions>): this;
/**
* Set unsigned cookie as the response header. The inline options overrides
* all options from the config.
*/
plainCookie(key: string, value: any, options?: Partial<CookieOptions & {
encode: boolean;
}>): this;
/**
* Clear existing cookie.
*/
clearCookie(key: string, options?: Partial<CookieOptions>): this;
/**
* Finishes the response by writing the lazy body, when `explicitEnd = true`
* and response is already pending.
*
* Calling this method twice or when `explicitEnd = false` is noop.
*/
finish(): void;
/**
* Shorthand method to finish request with "100" status code
*/
continue(): void;
/**
* Shorthand method to finish request with "101" status code
*/
switchingProtocols(): void;
/**
* Shorthand method to finish request with "200" status code
*/
ok(body: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "201" status code
*/
created(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "202" status code
*/
accepted(body: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "203" status code
*/
nonAuthoritativeInformation(body: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "204" status code
*/
noContent(): void;
/**
* Shorthand method to finish request with "205" status code
*/
resetContent(): void;
/**
* Shorthand method to finish request with "206" status code
*/
partialContent(body: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "300" status code
*/
multipleChoices(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "301" status code
*/
movedPermanently(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "302" status code
*/
movedTemporarily(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "303" status code
*/
seeOther(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "304" status code
*/
notModified(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "305" status code
*/
useProxy(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "307" status code
*/
temporaryRedirect(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "400" status code
*/
badRequest(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "401" status code
*/
unauthorized(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "402" status code
*/
paymentRequired(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "403" status code
*/
forbidden(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "404" status code
*/
notFound(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "405" status code
*/
methodNotAllowed(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "406" status code
*/
notAcceptable(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "407" status code
*/
proxyAuthenticationRequired(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "408" status code
*/
requestTimeout(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "409" status code
*/
conflict(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "401" status code
*/
gone(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "411" status code
*/
lengthRequired(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "412" status code
*/
preconditionFailed(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "413" status code
*/
requestEntityTooLarge(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "414" status code
*/
requestUriTooLong(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "415" status code
*/
unsupportedMediaType(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "416" status code
*/
requestedRangeNotSatisfiable(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "417" status code
*/
expectationFailed(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "422" status code
*/
unprocessableEntity(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "429" status code
*/
tooManyRequests(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "500" status code
*/
internalServerError(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "501" status code
*/
notImplemented(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "502" status code
*/
badGateway(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "503" status code
*/
serviceUnavailable(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "504" status code
*/
gatewayTimeout(body?: any, generateEtag?: boolean): void;
/**
* Shorthand method to finish request with "505" status code
*/
httpVersionNotSupported(body?: any, generateEtag?: boolean): void;
}