使用方法:将下方文件保存为main.go,按照目录结构创建文件夹,编译运行。

// 静态文件共享服务器
// 可以将本地的文件夹共享到网页中,本代码主要实现自定义网页路径前缀(默认是"/files/")。
// 编译运行后,默认将files文件夹的内容共享到 http://127.0.0.1:8443/files/
// 日志文件存放于log目录下
/* 目录结构:
FileServer/
|-- bin 用于存放编译后的主程序文件
|-- certs 证书文件夹(用于支持STL)
|-- files 用于分享的文件夹
|-- log 日志文件夹
`-- main.go 本程序源码
*/
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
)
var filesPath string = ""
// init 初始化函数,用于初始化日志输出
func init(){
file, _ := exec.LookPath(os.Args[0])
//path, _ := filepath.Abs(filepath.Dir(filepath.Dir(file)))
path, _ := filepath.Abs(filepath.Dir(file))
logPath :=filepath.Dir(path)+"/log"
//logPath := path +"/log"
fmt.Println("$ Log Path:",logPath)
err := os.MkdirAll(logPath, os.ModePerm)
if err!=nil{
fmt.Println(err)
}
fmt.Println("$ Log File:",logPath+"/server.log")
logFile, _ := os.OpenFile(logPath+"/server.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
log.SetOutput(logFile)
}
// 程序入口
func main() {
host := "8443"
file, _ := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(filepath.Dir(file))
fmt.Println("$ File Server Start!")
filesPath =filepath.Dir(path)+"/files"
// Files目录支持
fmt.Println("$ Files Path:", filesPath)
http.HandleFunc("/files/",fileServer)
// API支持
fmt.Println("$ API URL:","/api")
http.HandleFunc("/api", apiHandler)
// 404 Page
http.HandleFunc("/", notFoundHandler)
certsPath, _ := filepath.Abs(filepath.Dir(path)+"/certs")
fmt.Println("$ Certificates Path:",certsPath)
fmt.Println("$ Listen on Port:", host)
log.Println("$ Server Start. Listen on[",host,"]")
// 如果需要支持HTTPS,则使用下面的语句
//err := http.ListenAndServeTLS(":"+host, certsPath+"/a.crt", certsPath+"/b.key", nil)
// 如果不使用证书,则使用下面的语句
err := http.ListenAndServe(":"+host, nil)
if err != nil {
fmt.Println(err)
}
}
// fileServer 文件服务器
func fileServer(w http.ResponseWriter, r *http.Request) {
logging("FileServer",r)
prefix := "/files/"
h := http.FileServer(http.Dir(filesPath))
if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
r2 := new(http.Request)
*r2 = *r
r2.URL = new(url.URL)
*r2.URL = *r.URL
r2.URL.Path = p
h.ServeHTTP(w, r2)
} else {
notFoundHandler(w, r)
}
}
// notFoundHandler 页面未找到
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
logging("HTTP/"+ strconv.Itoa(http.StatusNotFound),r)
w.WriteHeader(http.StatusNotFound)
}
// apiHandler API接口
func apiHandler(w http.ResponseWriter, r *http.Request) {
logging("HTTP/"+ strconv.Itoa(http.StatusOK),r)
w.Header().Add("Content-Type", "application/json")
_, _ = io.WriteString(w, `{"status":"ok"}`)
}
// logging 输出日志
func logging(states string,r *http.Request){
logString := "["+states+"]"+r.RemoteAddr+"->"+r.Host+r.RequestURI
fmt.Println(logString)
log.Println(logString)
}