deno学习四 docker 运行官方的一个http file server
github 上已经有人搞了一个deno 的docker 镜像,是基于源码编译的,挺好的
所以结合官方的http server demo 使用docker 运行
环境准备
- docker-compose 文件
- version: "3"
- services:
- app:
- image: maxmcd/deno:slim
- volumes:
- - "./app:/opt"
- command: deno /opt/app.ts
- file-server:
- image: maxmcd/deno:slim
- ports:
- - "4500:4500"
- volumes:
- - "./server:/opt/server"
- command: deno /opt/server/app.ts --allow-net
- http server 内容
http 模块的我修改为了使用http,就不用管下载的问题了
- // This program serves files in the current directory over HTTP.
- // TODO Stream responses instead of reading them into memory.
- // TODO Add tests like these:
- // https://github.com/indexzero/http-server/blob/master/test/http-server-test.js
-
- import {
- listenAndServe,
- ServerRequest,
- setContentLength,
- Response
- } from "https://deno.land/x/net/http.ts";
- import { cwd, DenoError, ErrorKind, args, stat, readDir, open } from "deno";
-
- const dirViewerTemplate = `
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Deno File Server</title>
- <style>
- td {
- padding: 0 1rem;
- }
- td.mode {
- font-family: Courier;
- }
- </style>
- </head>
- <body>
- <h1>Index of <%DIRNAME%></h1>
- <table>
- <tr><th>Mode</th><th>Size</th><th>Name</th></tr>
- <%CONTENTS%>
- </table>
- </body>
- </html>
- `;
-
- const serverArgs = args.slice();
- let CORSEnabled = false;
- // TODO: switch to flags if we later want to add more options
- for (let i = 0; i < serverArgs.length; i++) {
- if (serverArgs[i] === "--cors") {
- CORSEnabled = true;
- serverArgs.splice(i, 1);
- break;
- }
- }
- let currentDir = cwd();
- const target = serverArgs[1];
- if (target) {
- currentDir = `${currentDir}/${target}`;
- }
- const addr = `0.0.0.0:${serverArgs[2] || 4500}`;
- const encoder = new TextEncoder();
-
- function modeToString(isDir: boolean, maybeMode: number | null) {
- const modeMap = ["---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"];
-
- if (maybeMode === null) {
- return "(unknown mode)";
- }
- const mode = maybeMode!.toString(8);
- if (mode.length < 3) {
- return "(unknown mode)";
- }
- let output = "";
- mode
- .split("")
- .reverse()
- .slice(0, 3)
- .forEach(v => {
- output = modeMap[+v] + output;
- });
- output = `(${isDir ? "d" : "-"}${output})`;
- return output;
- }
-
- function fileLenToString(len: number) {
- const multipler = 1024;
- let base = 1;
- const suffix = ["B", "K", "M", "G", "T"];
- let suffixIndex = 0;
-
- while (base * multipler < len) {
- if (suffixIndex >= suffix.length - 1) {
- break;
- }
- base *= multipler;
- suffixIndex++;
- }
-
- return `${(len / base).toFixed(2)}${suffix[suffixIndex]}`;
- }
-
- function createDirEntryDisplay(
- name: string,
- path: string,
- size: number | null,
- mode: number | null,
- isDir: boolean
- ) {
- const sizeStr = size === null ? "" : "" + fileLenToString(size!);
- return `
- <tr><td class="mode">${modeToString(
- isDir,
- mode
- )}</td><td>${sizeStr}</td><td><a href="${path}">${name}${
- isDir ? "/" : ""
- }</a></td>
- </tr>
- `;
- }
-
- // TODO: simplify this after deno.stat and deno.readDir are fixed
- async function serveDir(req: ServerRequest, dirPath: string, dirName: string) {
- // dirname has no prefix
- const listEntry: string[] = [];
- const fileInfos = await readDir(dirPath);
- for (const info of fileInfos) {
- if (info.name === "index.html" && info.isFile()) {
- // in case index.html as dir...
- return await serveFile(req, info.path);
- }
- // Yuck!
- let mode = null;
- try {
- mode = (await stat(info.path)).mode;
- } catch (e) {}
- listEntry.push(
- createDirEntryDisplay(
- info.name,
- dirName + "/" + info.name,
- info.isFile() ? info.len : null,
- mode,
- info.isDirectory()
- )
- );
- }
-
- const page = new TextEncoder().encode(
- dirViewerTemplate
- .replace("<%DIRNAME%>", dirName + "/")
- .replace("<%CONTENTS%>", listEntry.join(""))
- );
-
- const headers = new Headers();
- headers.set("content-type", "text/html");
-
- const res = {
- status: 200,
- body: page,
- headers
- };
- setContentLength(res);
- return res;
- }
-
- async function serveFile(req: ServerRequest, filename: string) {
- const file = await open(filename);
- const fileInfo = await stat(filename);
- const headers = new Headers();
- headers.set("content-length", fileInfo.len.toString());
-
- const res = {
- status: 200,
- body: file,
- headers
- };
- return res;
- }
-
- async function serveFallback(req: ServerRequest, e: Error) {
- if (
- e instanceof DenoError &&
- (e as DenoError<any>).kind === ErrorKind.NotFound
- ) {
- return {
- status: 404,
- body: encoder.encode("Not found")
- };
- } else {
- return {
- status: 500,
- body: encoder.encode("Internal server error")
- };
- }
- }
-
- function serverLog(req: ServerRequest, res: Response) {
- const d = new Date().toISOString();
- const dateFmt = `[${d.slice(0, 10)} ${d.slice(11, 19)}]`;
- const s = `${dateFmt} "${req.method} ${req.url} ${req.proto}" ${res.status}`;
- console.log(s);
- }
-
- function setCORS(res: Response) {
- if (!res.headers) {
- res.headers = new Headers();
- }
- res.headers!.append("access-control-allow-origin", "*");
- res.headers!.append(
- "access-control-allow-headers",
- "Origin, X-Requested-With, Content-Type, Accept, Range"
- );
- }
-
- listenAndServe(addr, async req => {
- const fileName = req.url.replace(/\/$/, "");
- const filePath = currentDir + fileName;
-
- let response: Response;
-
- try {
- const fileInfo = await stat(filePath);
- if (fileInfo.isDirectory()) {
- // Bug with deno.stat: name and path not populated
- // Yuck!
- response = await serveDir(req, filePath, fileName);
- } else {
- response = await serveFile(req, filePath);
- }
- } catch (e) {
- response = await serveFallback(req, e);
- } finally {
- if (CORSEnabled) {
- setCORS(response);
- }
- serverLog(req, response);
- req.respond(response);
- }
- });
-
- console.log(`HTTP server listening on http://${addr}/`);
运行&&效果
- 运行
- docker-compose up -d
- 效果
说明
deno 的安全控制上做的挺不错,因为使用了net ,所以需要在运行的时候指定 --allow-net
参考资料
https://github.com/rongfengliang/deno-docker-compose
https://deno.land/
deno学习四 docker 运行官方的一个http file server的更多相关文章
- docker 运行jenkins及vue项目与springboot项目(四.docker运行nginx)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- Singer 学习五 docker 运行说明
介绍过一个工具knots ,方便Singer 可视化开发的工具,但是默认这个工具包含的tap 以及target 比较少(可以自己扩展) 同时这个工具就是基于docker 运行的 docker 运行的几 ...
- ICE学习笔记一----运行官方的java版demo程序
建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...
- OpenGL学习——搭建OpenGL运行环境——生成一个空白视口——基于GLFW&GLEW
最近学习OpenGL,读OpenGL宝典一头蒙,各种gl函数不知所云.逐决定先搭OpenGL运行环境,详细如下. 1.首先OpenGL是什么?是一个标准规范,是一个巨大的状态机,并无具体实现,大多数实 ...
- docker学习(四) - docker构建redis主从结构
此文章假设你已经安装了docker,如果没有安装请查询本博客docker安装章节 容器网络 docker network ls 查看默认的网络 Docker安装后,默认会创建下面三种网络类型 在启动 ...
- JBPM学习(四):运行流程实例
概念: ProcessInstance,流程实例:代表流程定义的一次执行.如:张三昨天按请假流程请了一次假.一个流程实例包含了全部执行阶段,当中最典型的属性就是跟踪当前节点的指针,例如以下图. Exe ...
- docker 运行jenkins及vue项目与springboot项目(三.jenkins的使用及自动打包vue项目)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- benchmarkdotnet docker 运行
使用docker 运行基准测试是一个不错的选择,可以减少我们环境搭建的时间,同时也可以加速ci/cd 环境准备 docker-compose 文件 version: "3" ser ...
- docker 运行jenkins及vue项目与springboot项目(一.安装docker)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
随机推荐
- 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法
Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...
- TypeError: write() argument must be str, not bytes报错原因及Python3写入二进制文件方法
Python2随机写入二进制文件: with open('/python2/random.bin','w') as f: f.write(os.urandom(10)) 但使用Python3会报错: ...
- Invalid MEX-file: caffe.mexa64 的解决方案
http://blog.csdn.net/iamzhangzhuping/article/details/53105708
- 深入理解java虚拟机---jdk8新特性(二)
1.jdk8新特性 1.新特性 2.lambda函数表达式的作用 A: 替换内部类 B:对集合的操作并行化
- spring源码研究2 自定义标签实现及使用
1.自定义标签实现及使用参考: http://blog.csdn.net/fighterandknight/article/details/50112701 1)创建一个需要扩展的组件 User.ja ...
- SharePoint Framework 配置你的SharePoint客户端web部件开发环境
博客地址:http://blog.csdn.net/FoxDave 你可以使用Visual Studio或者是你自己的开发环境来构建SharePoint客户端web部件.你可以使用Mac.PC或是 ...
- 基于.NET Core 框架搭建WebApi项目
一 什么是.NET Core? 随着2014年 Xamarin和微软发起.NET基金会,微软在2014年11月份开放.NET框架源代码.在.NET开源基金会的统一规划下诞生了.NET Core .也就 ...
- Oracle 一些注意点
number精度问题 Number(p,s): p和s都是可选的. p指精度(precision),即总位数.默认情况下精度为38.精度的取值范围为1~38. s指小数位(scale),小数点右边的位 ...
- <Maven><Dependency><Conflict><Could not resolve>
maven conflict solution: scenerio: Runtime Error: ``` java.lang.SecurityException: class "javax ...
- L314 单音节词读音规则(二)-元音字母发音规则
1 单个元音发音尽量拖音一下(2S),发音会饱满一些. 2开音节: 辅音(辅组)(没有)+元音+辅音+e 的单词其中:元音发字母本身音,辅音字母不为r , 字母e不发音. 相对开音节:第一个元音都发字 ...