<strong id="lmxpx"></strong>
  • <small id="lmxpx"><span id="lmxpx"><p id="lmxpx"></p></span></small>
    <rp id="lmxpx"></rp>
    <progress id="lmxpx"><track id="lmxpx"></track></progress>

    1. <ol id="lmxpx"></ol>
      <rp id="lmxpx"><ruby id="lmxpx"></ruby></rp>
    2. <button id="lmxpx"><acronym id="lmxpx"></acronym></button>
    3. 打印

      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 下一條

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