Skip to content

Commit

Permalink
feat: download response
Browse files Browse the repository at this point in the history
  • Loading branch information
izatop committed Jul 16, 2023
1 parent 170f3b9 commit 445821b
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 18 deletions.
1 change: 0 additions & 1 deletion packages/app/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {Application} from "./Application.js";

export type ActionResponse = Error
| {stringify(): string}
| NodeJS.ReadableStream
| Buffer
| string
| number
Expand Down
4 changes: 4 additions & 0 deletions packages/web/src/Transport/RequestMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export class RequestMessage extends RequestAbstract {
}
}

public get url(): URL {
return this.#url;
}

public get host(): string {
return this.headers.get("host", "");
}
Expand Down
4 changes: 4 additions & 0 deletions packages/web/src/Transport/RequestProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class RequestProxy {
return this.#request.headers.get("authorization", "");
}

public get url(): URL {
return this.#request.url;
}

public get cookies(): Cookies {
return this.#request.cookies;
}
Expand Down
23 changes: 14 additions & 9 deletions packages/web/src/Transport/Responder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {IncomingMessage, ServerResponse} from "http";
import {Readable} from "stream";
import {ActionResponse, StrictKeyValueMap} from "@bunt/app";
import {
assert,
Expand Down Expand Up @@ -68,12 +69,6 @@ export class Responder extends RequestMessage {
return this.send(response);
}

if (isReadableStream(response)) {
response.pipe(this.#response);

return;
}

if (isError(response)) {
const transform = new TransformError(response, this.#errorCodeMap);
const accept = this.headers.get("accept");
Expand Down Expand Up @@ -110,7 +105,8 @@ export class Responder extends RequestMessage {
* @param body
* @param options
*/
protected send(body: string | undefined | Buffer, options: IRequestSendOptions = {code: 200}): void {
protected async send(body: string | undefined | Buffer | Readable,
options: IRequestSendOptions = {code: 200}): Promise<void> {
try {
const {code, status, headers = {}, cookies = []} = options;
const headersMap = StrictKeyValueMap.fromObject(headers);
Expand All @@ -129,10 +125,19 @@ export class Responder extends RequestMessage {
this.applyServerOptions();

this.#response.writeHead(code, status);
this.#response.write(body);
if (isReadableStream(body)) {
body.pipe(this.#response);
await new Promise((resolve, reject) => {
this.#response.on("finish", resolve);
this.#response.on("error", reject);
});

return;
}

this.#response.end(body);
} finally {
this.#complete = true;
this.#response.end();
}
}

Expand Down
18 changes: 18 additions & 0 deletions packages/web/src/Transport/Response/DownloadResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {createReadStream, statSync} from "fs";
import {Readable} from "stream";
import {ResponseAbstract} from "./ResponseAbstract.js";

export class DownloadResponse extends ResponseAbstract<string> {
constructor(filename: string, path: string, mimeType: string) {
const {size} = statSync(path);
super(path, {headers: {
"Content-Disposition": `attachment; filename=${filename}`,
"Content-Length": size.toString(),
"Content-Type": mimeType,
}});
}

public stringify(path: string): Readable {
return createReadStream(path);
}
}
5 changes: 3 additions & 2 deletions packages/web/src/Transport/Response/ResponseAbstract.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {Readable} from "stream";
import {isFunction, isInstanceOf, isNumber, isString, Promisify} from "@bunt/util";
import * as HTTP from "http-status";
import {Headers} from "../Headers.js";
Expand All @@ -12,7 +13,7 @@ export interface IResponseOptions {
export interface IResponseAnswer {
code: number;
status?: string;
body: string | Buffer;
body: string | Buffer | Readable;
headers: {[key: string]: string};
cookies: Cookie[];
}
Expand Down Expand Up @@ -89,5 +90,5 @@ export abstract class ResponseAbstract<T> {
return `${this.type}; charset=${this.encoding}`;
}

protected abstract stringify(data: T): string | Buffer;
protected abstract stringify(data: T): string | Buffer | Readable;
}
1 change: 1 addition & 0 deletions packages/web/src/Transport/Response/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from "./TextPlainResponse.js";
export * from "./NoContentResponse.js";
export * from "./Redirect.js";
export * from "./RedirectResponse.js";
export * from "./DownloadResponse.js";
12 changes: 6 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ __metadata:
languageName: node
linkType: hard

"@bunt/app@^0.28.2, @bunt/app@workspace:packages/app":
"@bunt/app@^0.28.3, @bunt/app@workspace:packages/app":
version: 0.0.0-use.local
resolution: "@bunt/app@workspace:packages/app"
dependencies:
Expand Down Expand Up @@ -456,7 +456,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@bunt/cli@workspace:packages/cli"
dependencies:
"@bunt/app": ^0.28.2
"@bunt/app": ^0.28.3
"@bunt/assert": ^0.28.1
"@bunt/util": ^0.28.1
path-to-regexp: ^6.2.1
Expand Down Expand Up @@ -551,11 +551,11 @@ __metadata:
languageName: unknown
linkType: soft

"@bunt/web@^0.28.2, @bunt/web@workspace:packages/web":
"@bunt/web@^0.28.3, @bunt/web@workspace:packages/web":
version: 0.0.0-use.local
resolution: "@bunt/web@workspace:packages/web"
dependencies:
"@bunt/app": ^0.28.2
"@bunt/app": ^0.28.3
"@bunt/util": ^0.28.1
http-status: ^1.6.2
path-to-regexp: ^6.2.1
Expand All @@ -566,10 +566,10 @@ __metadata:
version: 0.0.0-use.local
resolution: "@bunt/ws@workspace:packages/ws"
dependencies:
"@bunt/app": ^0.28.2
"@bunt/app": ^0.28.3
"@bunt/unit": ^0.28.2
"@bunt/util": ^0.28.1
"@bunt/web": ^0.28.2
"@bunt/web": ^0.28.3
"@types/websocket": ^1.0.5
"@types/ws": ^8.5.5
websocket: ^1.0.34
Expand Down

0 comments on commit 445821b

Please sign in to comment.