golang 使用标准库 30行代码实现 web 文件托管服务器

WFS(Web File Server) 是一个可以通过浏览器浏览本地托管目录的在线文件服务器。

http.ResponseWriter
http://127.0.0.1:8080/

在这里插入图片描述

package main

import (
	"bytes"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

func codeStarts() string {
	return `<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- UIkit CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/css/uikit.min.css"/>

    <!-- UIkit JS -->
    <script src="https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/js/uikit.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/js/uikit-icons.min.js"></script>
</head>
<body class="uk-container uk-width-2xlarge">
<div class="uk-card uk-card-default uk-card-body">
	<header class="uk-label">FileServer - 驭鲸环球</header>
    <ul class="uk-list uk-list-striped uk-list-collapse">`
}

func codeEnd() string {
	return `</ul>
</div>
</body>
</html>`
}

type ResponseBodyWriter struct {
	http.ResponseWriter
	body *bytes.Buffer
}

func (r ResponseBodyWriter) Write(b []byte) (int, error) {
	if bytes.Equal(b, []byte{60, 112, 114, 101, 62, 10} /*<pre>*/) {
		return r.ResponseWriter.Write([]byte(codeStarts()))
	} else if bytes.Equal(b, []byte{60, 47, 112, 114, 101, 62, 10} /*</pre>*/) {
		return r.ResponseWriter.Write([]byte(codeEnd()))
	} else if bytes.HasPrefix(b, []byte("<a")) || bytes.HasSuffix(b, []byte("</a>")) {
		s := append([]byte("<li>"), b...)
		s = append(s, []byte("</li>")...)
		//r.body.Write(s)
		return r.ResponseWriter.Write(s)
	}
	return r.ResponseWriter.Write(b)
}

func middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		w := &ResponseBodyWriter{ResponseWriter: writer, body: &bytes.Buffer{}}
		writer = w
		next.ServeHTTP(writer, request)
	})
}

func main() {
	path, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	//设置wfs根目录
	//path = "D:/Games/Naraka"
	fileHandler := http.FileServer(http.Dir(path))
	http.Handle("/", middleware(fileHandler))
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Println(err)
	}
}