package main
import (
"fmt"
"io/fs"
"net"
"net/http"
"os"
"path"
"sort"
)
const (
iconImg = `D:\FileRecv\MobileFile\mmexport1641207943484.jpg`
backgroundImg = `D:\FileRecv\MobileFile\Image\img157.png`
head = `
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon32.ico" type="image/x-icon"/>
<title>😁😁😁</title>
<style>
body {
font-family:Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
background-image: url("/backgroundImg");
background-size: cover;
}
</style>
</head>
`
)
var (
port = "80"
dir = `C:\迅雷下载`
)
type IconHandler struct {
}
func (i IconHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
http.ServeFile(writer, req, iconImg)
}
type ImgHandler struct {
}
func (i ImgHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
http.ServeFile(writer, req, backgroundImg)
}
type FileHandler struct {
unit []string
}
func NewFileHandler() *FileHandler {
return &FileHandler{unit: []string{"B", "KB", "MB", "GB", "TB"}}
}
func (f FileHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
p := path.Join(dir, req.URL.Path)
file, err := os.Open(p)
if err != nil {
return
}
defer file.Close()
info, _ := file.Stat()
if info.IsDir() {
f.listDir(writer, req, file)
} else {
http.ServeContent(writer, req, info.Name(), info.ModTime(), file)
}
}
func (f FileHandler) formatSize(info fs.FileInfo) string {
if info.IsDir() {
return "-"
}
var size = float64(info.Size())
for i := range f.unit {
if size < 1024 {
return fmt.Sprintf("%.2f%s", size, f.unit[i])
}
size /= 1024
}
return "-1"
}
type Writer struct {
writer http.ResponseWriter
}
func NewWriter(writer http.ResponseWriter) *Writer {
return &Writer{writer: writer}
}
func (w Writer) WriteF(format string, a ...any) {
_, _ = fmt.Fprintf(w.writer, format, a...)
}
func (f FileHandler) listDir(writer http.ResponseWriter, req *http.Request, Dir http.File) {
files, err := Dir.Readdir(-1)
if err != nil {
return
}
sort.Slice(files, func(i, j int) bool {
if files[i].IsDir() && !files[j].IsDir() {
return true
}
return false
})
w := NewWriter(writer)
w.WriteF(`<html>`)
w.WriteF(head)
w.WriteF(`<body>`)
w.WriteF(`<h1>Index of %s</h1>`, req.URL.Path)
w.WriteF(`<hr />`)
w.WriteF(`<table>`)
for _, file := range files {
name := file.Name()
if file.IsDir() {
name += "/"
}
w.WriteF(`<tr><td><a href="%s%s">%s</a></td>`, req.URL.Path, name, name)
w.WriteF(`<td style="width:300px;text-align:center;">%s</td>`, file.ModTime().Format("2006-01-02 15:04:05"))
w.WriteF(`<td style="width:80px;text-align:right;">%s</td></tr>`, f.formatSize(file))
}
w.WriteF(`</table>`)
w.WriteF(`</body>`)
w.WriteF(`</html>`)
}
func getLocalIPv4() (string, error) {
interfaces, err := net.Interfaces()
if err != nil {
return "", err
}
for _, it := range interfaces {
if it.Name == "WLAN" {
addrs, err := it.Addrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String(), nil
}
}
}
}
}
return "", fmt.Errorf("未找到IPv4地址")
}
func dealArgs() {
if len(os.Args) >= 2 {
dir = os.Args[1]
if len(os.Args) >= 3 {
port = os.Args[2]
}
}
}
func main() {
if len(os.Args) == 2 && os.Args[1] == "/?" {
fmt.Println("第一个参数改路径,第二个参数改端口")
return
}
dealArgs()
http.Handle("/backgroundImg", &ImgHandler{}) // 设置背景图片
http.Handle("/favicon32.ico", &IconHandler{}) // 设置图标
http.Handle("/", NewFileHandler())
ip, err := getLocalIPv4() // // 获取局域网IPV4地址
if err != nil {
fmt.Println(err)
ip = "127.0.0.1"
}
if port == "80" {
fmt.Printf("服务已启动,访问地址:http://%s\n", ip)
} else {
fmt.Printf("服务已启动,访问地址:http://%s:%s\n", ip, port)
}
err = http.ListenAndServe(":"+port, nil)
if err != nil {
panic(err)
}
}
go局域网共享文件夹(静态文件服务)
最新推荐文章于 2024-05-18 10:01:46 发布