File server
Concepts
- Use Deno.open to read a file's content in chunks.
- Use the Deno standard library streams module to transform a Deno file into a ReadableStream.
- Use Deno's integrated HTTP server to run your own file server.
Overview
Sending files over the network is a common requirement. As seen in the Fetch Data example, because files can be of any size, it is important to use streams in order to prevent having to load entire files into memory.
Example
Command: deno run --allow-read --allow-net file_server.ts
import * as path from "https://deno.land/std@0.126.0/path/mod.ts";
import { readableStreamFromReader } from "https://deno.land/std@0.126.0/streams/mod.ts";
// Start listening on port 8080 of localhost.
const server = Deno.listen({ port: 8080 });
console.log("File server running on http://localhost:8080/");
for await (const conn of server) {
handleHttp(conn);
}
async function handleHttp(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
// Use the request pathname as filepath
const url = new URL(requestEvent.request.url);
const filepath = decodeURIComponent(url.pathname);
// Try opening the file
let file;
try {
file = await Deno.open("." + filepath, { read: true });
const stat = await file.stat();
// If File instance is a directory, lookup for an index.html
if (stat.isDirectory) {
file.close();
const filePath = path.join("./", filepath, "index.html");
file = await Deno.open(filePath, { read: true });
}
} catch {
// If the file cannot be opened, return a "404 Not Found" response
const notFoundResponse = new Response("404 Not Found", { status: 404 });
await requestEvent.respondWith(notFoundResponse);
return;
}
// Build a readable stream so the file doesn't have to be fully loaded into
// memory while we send it
const readableStream = readableStreamFromReader(file);
// Build and send the response
const response = new Response(readableStream);
await requestEvent.respondWith(response);
}
}
std/http
file server
Using the The Deno standard library provides you with a file server so that you don't have to write your own.
To use it, first install the remote script to your local file system. This will
install the script to the Deno installation root's bin directory, e.g.
/home/alice/.deno/bin/file_server
.
deno install --allow-net --allow-read https://deno.land/std@0.126.0/http/file_server.ts
You can now run the script with the simplified script name. Run it:
$ file_server .
Downloading https://deno.land/std@0.126.0/http/file_server.ts...
[...]
HTTP server listening on http://0.0.0.0:4507/
Now go to http://0.0.0.0:4507/ in your web browser to see your local directory contents.
The complete list of options are available via:
file_server --help
Example output:
Deno File Server
Serves a local directory in HTTP.
INSTALL:
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
USAGE:
file_server [path] [options]
OPTIONS:
-h, --help Prints help information
-p, --port <PORT> Set port
--cors Enable CORS via the "Access-Control-Allow-Origin" header
--host <HOST> Hostname (default is 0.0.0.0)
-c, --cert <FILE> TLS certificate file (enables TLS)
-k, --key <FILE> TLS key file (enables TLS)
--no-dir-listing Disable directory listing
All TLS options are required when one is provided.