0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-08 15:21:26 -05:00

fix(file_server): use media_types for Content-Type header (#4555)

This commit is contained in:
Khải 2020-04-01 23:51:01 +07:00 committed by GitHub
parent 5ac2c4aa2e
commit fa7929ad2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 39 deletions

View file

@ -7,7 +7,8 @@
// https://github.com/indexzero/http-server/blob/master/test/http-server-test.js // https://github.com/indexzero/http-server/blob/master/test/http-server-test.js
const { args, stat, readdir, open, exit } = Deno; const { args, stat, readdir, open, exit } = Deno;
import { posix } from "../path/mod.ts"; import { contentType } from "../media_types/mod.ts";
import { posix, extname } from "../path/mod.ts";
import { listenAndServe, ServerRequest, Response } from "./server.ts"; import { listenAndServe, ServerRequest, Response } from "./server.ts";
import { parse } from "../flags/mod.ts"; import { parse } from "../flags/mod.ts";
import { assert } from "../testing/asserts.ts"; import { assert } from "../testing/asserts.ts";
@ -96,21 +97,22 @@ function fileLenToString(len: number): string {
return `${(len / base).toFixed(2)}${suffix[suffixIndex]}`; return `${(len / base).toFixed(2)}${suffix[suffixIndex]}`;
} }
async function serveFile( export async function serveFile(
req: ServerRequest, req: ServerRequest,
filePath: string filePath: string
): Promise<Response> { ): Promise<Response> {
const [file, fileInfo] = await Promise.all([open(filePath), stat(filePath)]); const [file, fileInfo] = await Promise.all([open(filePath), stat(filePath)]);
const headers = new Headers(); const headers = new Headers();
headers.set("content-length", fileInfo.size.toString()); headers.set("content-length", fileInfo.size.toString());
headers.set("content-type", "text/plain; charset=utf-8"); const contentTypeValue = contentType(extname(filePath));
if (contentTypeValue) {
const res = { headers.set("content-type", contentTypeValue);
}
return {
status: 200, status: 200,
body: file, body: file,
headers, headers,
}; };
return res;
} }
// TODO: simplify this after deno.stat and deno.readdir are fixed // TODO: simplify this after deno.stat and deno.readdir are fixed
@ -296,39 +298,45 @@ function html(strings: TemplateStringsArray, ...values: unknown[]): string {
return html; return html;
} }
listenAndServe( function main(): void {
addr, listenAndServe(
async (req): Promise<void> => { addr,
let normalizedUrl = posix.normalize(req.url); async (req): Promise<void> => {
try { let normalizedUrl = posix.normalize(req.url);
normalizedUrl = decodeURIComponent(normalizedUrl); try {
} catch (e) { normalizedUrl = decodeURIComponent(normalizedUrl);
if (!(e instanceof URIError)) { } catch (e) {
throw e; if (!(e instanceof URIError)) {
throw e;
}
}
const fsPath = posix.join(target, normalizedUrl);
let response: Response | undefined;
try {
const info = await stat(fsPath);
if (info.isDirectory()) {
response = await serveDir(req, fsPath);
} else {
response = await serveFile(req, fsPath);
}
} catch (e) {
console.error(e.message);
response = await serveFallback(req, e);
} finally {
if (CORSEnabled) {
assert(response);
setCORS(response);
}
serverLog(req, response!);
req.respond(response!);
} }
} }
const fsPath = posix.join(target, normalizedUrl); );
let response: Response | undefined; console.log(`HTTP server listening on http://${addr}/`);
try { }
const info = await stat(fsPath);
if (info.isDirectory()) {
response = await serveDir(req, fsPath);
} else {
response = await serveFile(req, fsPath);
}
} catch (e) {
console.error(e.message);
response = await serveFallback(req, e);
} finally {
if (CORSEnabled) {
assert(response);
setCORS(response);
}
serverLog(req, response!);
req.respond(response!);
}
}
);
console.log(`HTTP server listening on http://${addr}/`); if (import.meta.main) {
main();
}

View file

@ -2,6 +2,8 @@
import { assert, assertEquals, assertStrContains } from "../testing/asserts.ts"; import { assert, assertEquals, assertStrContains } from "../testing/asserts.ts";
import { BufReader } from "../io/bufio.ts"; import { BufReader } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts"; import { TextProtoReader } from "../textproto/mod.ts";
import { ServerRequest } from "./server.ts";
import { serveFile } from "./file_server.ts";
const { test } = Deno; const { test } = Deno;
let fileServer: Deno.Process; let fileServer: Deno.Process;
@ -31,7 +33,7 @@ function killFileServer(): void {
fileServer.stdout?.close(); fileServer.stdout?.close();
} }
test(async function serveFile(): Promise<void> { test("file_server serveFile", async (): Promise<void> => {
await startFileServer(); await startFileServer();
try { try {
const res = await fetch("http://localhost:4500/README.md"); const res = await fetch("http://localhost:4500/README.md");
@ -141,3 +143,11 @@ test(async function printHelp(): Promise<void> {
helpProcess.close(); helpProcess.close();
helpProcess.stdout.close(); helpProcess.stdout.close();
}); });
test("contentType", async () => {
const request = new ServerRequest();
const response = await serveFile(request, "http/testdata/hello.html");
const contentType = response.headers!.get("content-type");
assertEquals(contentType, "text/html; charset=utf-8");
(response.body as Deno.File).close();
});

0
std/http/testdata/hello.html vendored Normal file
View file