<wbr id="9qp22"><legend id="9qp22"><rt id="9qp22"></rt></legend></wbr>
<th id="9qp22"><noframes id="9qp22"><form id="9qp22"></form></noframes></th>

      <dd id="9qp22"><big id="9qp22"><video id="9qp22"></video></big></dd>
      <th id="9qp22"></th>
        <rp id="9qp22"><acronym id="9qp22"></acronym></rp>
        <dd id="9qp22"><pre id="9qp22"></pre></dd>

        1. <dd id="9qp22"><pre id="9qp22"></pre></dd>
          1. 打印

            golang的一個文件服務器

            [復制鏈接]
            2584|10
            跳轉到指定樓層
            樓主
            可以顯示指定目錄,進入子目錄,下載文件,上傳文件等等

            @sherwin @海中水 @gaoyang9992006

            1. go run fileserver.go -p=1234
            復制代碼



            顯示指定目錄:





            進入子目錄:



            上傳文件:





            fileserver.go
            代碼如下:


            1. package main

            2. import (
            3.         "flag"
            4.         "fmt"
            5.         "io"
            6.         "io/ioutil"
            7.         "log"
            8.         "net/http"
            9.         "os"
            10.         "path"
            11.         "strconv"
            12.         "strings"
            13.         "time"
            14. )

            15. var defaultPath string

            16. var baseURL string
            17. var upload_path string

            18. func Logger(req *http.Request, statusCode int) {
            19.         const layout = "[ 2/Jan/2006 15:04:05 ]"
            20.         fmt.Println(baseURL + " --- " + time.Now().Format(layout) + " " + req.Method + "  " + strconv.Itoa(statusCode) + "  " + req.URL.Path)
            21. }

            22. func Handler(w http.ResponseWriter, req *http.Request) {


            23.         filename := defaultPath + req.URL.Path[1:]
            24.         fmt.Println("=+=== file name: ",filename)
            25.         if last := len(filename) - 1; last >= 0 && filename[last] == '/' && len(filename) != 1 {
            26.                 filename = filename[:last]
            27.         }

            28.         if req.Method == "POST" {
            29.                 file, head, err := req.FormFile("file")
            30.                 if err != nil {
            31.                         fmt.Println(err)
            32.                         return
            33.                 }

            34.                 defer file.Close()


            35.                 //創建文件
            36.                 fW, err := os.Create(upload_path + head.Filename)
            37.                 if err != nil {
            38.                         fmt.Println("文件創建失敗")
            39.                         return
            40.                 }
            41.                 defer fW.Close()

            42.                 _, err = io.Copy(fW, file)
            43.                 if err != nil {
            44.                         fmt.Println("文件保存失敗")
            45.                         return
            46.                 }
            47.         }

            48.         // Empty request (Root)
            49.         if filename == "" {
            50.                 filename = "./"
            51.         }

            52.         file, err := os.Stat(filename)

            53.         // 404 if file doesn't exist
            54.         if os.IsNotExist(err) {
            55.                 _, err = io.WriteString(w, "404 Not Found")
            56.                 Logger(req, http.StatusNotFound)
            57.                 return
            58.         }

            59.         // Serve directory
            60.         if file.IsDir() {

            61.                 slashCheck := ""

            62.                 files, err := ioutil.ReadDir(filename)
            63.                 // Catch the Error in reading from directory
            64.                 if err != nil {
            65.                         http.Redirect(w, req, "", http.StatusInternalServerError)
            66.                         Logger(req, http.StatusInternalServerError)
            67.                 }
            68.                 // Checking for Root Directory
            69.                 if filename != "./" {
            70.                         if filename[len(filename)-1] != '/' {
            71.                                 slashCheck = "/"
            72.                         }
            73.                 }

            74.                 fmt.Println("=+=== slashCheck: ",slashCheck)
            75.                 fmt.Println("=+=== req.URL.Path[0:]: ",req.URL.Path[0:])

            76.                 responseString := "<html><body> <h3> Directory Listing for " + req.URL.Path[1:] + "/ </h3> <br/> <hr> <ul>"
            77.                 for _, f := range files {
            78.                         if f.Name()[0] != '.' {
            79.                                 if f.IsDir() {
            80.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "/" + "</a></li>"
            81.                                 } else {
            82.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "</a></li>"
            83.                                 }
            84.                         }
            85.                 }

            86.                 //Ending the list
            87.                 responseString += "</ul><br/><hr/>"

            88.                 p := req.URL.Path

            89.                 // Display link to parent directory
            90.                 if len(p) > 1 {
            91.                         base := path.Base(p)

            92.                         slice := len(p) - len(base) - 1

            93.                         url := "/"

            94.                         if slice > 1 {
            95.                                 url = req.URL.Path[:slice]
            96.                                 url = strings.TrimRight(url, "/") // Remove extra / at the end
            97.                         }

            98.                         responseString += "<br/><a href=\"" + url + "\">Parent directory</a>"
            99.                 }

            100.                 uploadStr := "<form action='#' method=\"post\" enctype=\"multipart/form-data\"> <label> </label><input type=\"file\" name='file'  /><br/><br/> <label><input type=\"submit\" value=\"上傳文件\"/></label> </form>"

            101.                 responseString = responseString + uploadStr + "</body></html>"
            102.                 //fmt.Println("      =+=== responseString: ",responseString)
            103.                 _, err = io.WriteString(w, responseString)
            104.                 if err != nil {
            105.                         // panic(err)
            106.                         http.Redirect(w, req, "", http.StatusInternalServerError)
            107.                         Logger(req, http.StatusInternalServerError)
            108.                 } else {
            109.                         Logger(req, http.StatusOK)
            110.                 }

            111.                 upload_path = "./" + req.URL.Path[0:] + "/"

            112.                 return
            113.         }

            114.         // File exists and is no directory; Serve the file

            115.         b, err := ioutil.ReadFile(filename)
            116.         if err != nil {
            117.                 http.Redirect(w, req, "", http.StatusInternalServerError)
            118.                 Logger(req, http.StatusInternalServerError)
            119.                 return
            120.         }

            121.         str := string(b)
            122.         extension := path.Ext(filename)

            123.         if extension == ".css" {
            124.                 w.Header().Set("Content-Type", "text/css; charset=utf-8")
            125.         } else if extension == ".js" {
            126.                 w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
            127.         }
            128.         _, err = io.WriteString(w, str)
            129.         if err != nil {
            130.                 // panic(err)
            131.                 http.Redirect(w, req, "", http.StatusInternalServerError)
            132.         } else {
            133.                 Logger(req, http.StatusOK)
            134.         }

            135. }

            136. func main() {

            137.         defaultPortPtr := flag.String("p", "", "Port Number")
            138.         defaultPathPtr := flag.String("d", "", "Root Directory")
            139.         flag.Parse()

            140.         portNum := "8080"

            141.         // Handling the command line flags

            142.         // Directory
            143.         if *defaultPathPtr != "" {
            144.                 defaultPath = "./" + *defaultPathPtr + "/"
            145.         } else {
            146.                 defaultPath = ""
            147.         }
            148.         // Port Number
            149.         if *defaultPortPtr != "" {
            150.                 portNum = *defaultPortPtr
            151.         } else {
            152.                 portNum = "8080"
            153.         }

            154.         baseURL = "http://localhost:" + portNum

            155.         fmt.Println("Serving on ", baseURL, " subdirectory ", defaultPath)

            156.         http.HandleFunc("/", Handler)
            157.         err := http.ListenAndServe(":"+portNum, nil)
            158.         if err != nil {
            159.                 log.Fatal("ListenAndServe: ", err)
            160.         }
            161. }
            復制代碼


            使用特權

            評論回復
            沙發
            | 2019-9-20 09:14 | 只看該作者
            不錯的東西。給你點個贊。

            使用特權

            評論回復
            板凳
             樓主 | 2019-9-20 09:26 | 只看該作者
            海中水 發表于 2019-9-20 09:14
            不錯的東西。給你點個贊。

            可以交叉編譯到嵌入式linux環境里:
            env GOOS=linux GOARCH=arm go build -v fileserver.go

            這樣可以很方便為嵌入式環境增加遠程查看,更新,下載功能

            使用特權

            評論回復
            地板
            | 2019-9-20 10:29 | 只看該作者
            相當于一個NAS么?

            使用特權

            評論回復
            5
             樓主 | 2019-9-20 13:23 | 只看該作者
            sherwin 發表于 2019-9-20 10:29
            相當于一個NAS么?

            可以的

            使用特權

            評論回復
            6
            | 2019-9-23 09:18 | 只看該作者
            keer_zu 發表于 2019-9-20 09:26
            可以交叉編譯到嵌入式linux環境里:
            env GOOS=linux GOARCH=arm go build -v fileserver.go

            ok!有空研究一下。

            使用特權

            評論回復
            7
            | 2019-9-23 16:27 | 只看該作者
            為啥不用gin....可以少些不少代碼...

            使用特權

            評論回復
            8
             樓主 | 2019-9-24 11:42 | 只看該作者
            icecut 發表于 2019-9-23 16:27
            為啥不用gin....可以少些不少代碼...

            關鍵還是文件和路徑的問題

            使用特權

            評論回復
            9
            | 2019-9-25 09:45 | 只看該作者
            keer_zu 發表于 2019-9-24 11:42
            關鍵還是文件和路徑的問題

            這個可以修改的. 你想啊. 很多網頁服務器必須對上傳的文件進行改名.否則會出現安全問題...改個路徑還不簡單...

            使用特權

            評論回復
            10
             樓主 | 2019-10-4 13:21 | 只看該作者
            icecut 發表于 2019-9-25 09:45
            這個可以修改的. 你想啊. 很多網頁服務器必須對上傳的文件進行改名.否則會出現安全問題...改個路徑還不簡 ...

            也用過gin做了webserver,但是沒有仔細了解過gin額外提供了那些東西,比如安全方面的。

            使用特權

            評論回復
            11
            | 2019-10-5 19:00 | 只看該作者
            keer_zu 發表于 2019-10-4 13:21
            也用過gin做了webserver,但是沒有仔細了解過gin額外提供了那些東西,比如安全方面的。 ...

            你想的太多了...僅僅是個支持中間件的框架

            使用特權

            評論回復
            掃描二維碼,隨時隨地手機跟帖
            您需要登錄后才可以回帖 登錄 | 注冊

            本版積分規則

            我要發帖 投訴建議 創建版塊 申請版主

            快速回復

            您需要登錄后才可以回帖
            登錄 | 注冊
            高級模式

            論壇熱帖

            關閉

            熱門推薦上一條 /6 下一條

            在線客服 快速回復 返回頂部 返回列表
            成人短片线上看