golang开发静态文件服务器

最近发现以前常用的两个静态文件服务器的程序有点抽风,很可能是因为Nodejs升级的缘故导致一些兼容问题,同时惊奇的发现,两个程序在linux上表现极为糟糕,一个彻底无法运行,一个运行出现很多问题,为了自己方便索性花费一些时间自己搞一个,同时满足一直以来一个小小的需求。

在golang中建立一个静态文件服务器非常简单,你只需要使用神奇的http.FileServer即可快速的搭建一个文件服务器,其使用的语句加起来不超过两行(核心代码)。我在此功能之中加入了守护进程的支持。

加入守护进程后,golang会再次呼叫自身,并以子进程方式运行,同时父进程关闭,此时子进程将托管给PID为1的系统进程,这样就不会阻塞我的终端输入了。

启动子进程可以借助exec.Command来完成,同时将父进程所接受到的命令参数传递给子进程即可。

代码如下:

package main

import (
    "flag"
    "fmt"
    "net/http"
    "os"
    "os/exec"
    "path/filepath"
)

var godaemon = flag.Bool("d", false, "run app as a daemon with -d .")
var port = flag.String("p", ":8080", "set server port, -p=:8899 or -p :8899")
var close = flag.Bool("c", false, "close server")
var pid = flag.String("i", "0", "server pid")

func init() {
    if !flag.Parsed() {
        flag.Parse()
    }

    if *close {
        if *pid == "0" {
            fmt.Println("you must set -i, this is server pid")
            os.Exit(0)
        }
        cmd := exec.Command("kill", "-9", *pid)
        cmd.Start()
        os.Exit(0)
    }

    if *godaemon {
        args := os.Args[1:]
        for i := 0; i < len(args); i++ {
            if args[i] == "-d" {
                args = append(args[:i], args[i+1:]...)
                break
            }
        }
        cmd := exec.Command(os.Args[0], args...)
        cmd.Start()
        fmt.Printf("Server running...\nClose server: kill -9 %d\n", cmd.Process.Pid)
        fmt.Printf("http://localhost%s \n", *port)
        *godaemon = false
        os.Exit(0)
    }
}

func main() {
    fmt.Printf("http://localhost%s \n", *port)
    dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
    http.Handle("/", http.FileServer(http.Dir(dir)))
    err := http.ListenAndServe(*port, nil)
    if err != nil {
        fmt.Printf("%s\n", err)
    }
}

系统运行后,你也可以根据当前服务器的PID来关闭它,如果PID为12345的话,则使用fs -c -i 12345即可快速关闭服务器。

我将项目放到了github中,你可以查看我的static-file-server仓。