1. 程式人生 > 其它 >[golang]簡單的檔案上傳下載

[golang]簡單的檔案上傳下載

前言

某次在客戶內網傳輸資料的時候,防火牆攔截了SSH的資料包,導致沒法使用scp命令傳輸檔案,tcp協議和http協議也只放開了指定埠,因此想了個用http傳輸的“曲線救國”方案。

假設要從192.168.1.23傳輸到192.168.2.34,因防火牆限制,只能從1.23訪問2.34,不能從2.34訪問1.23,且1.23只能訪問2.34的12345埠,也不能使用基於ssh的檔案傳輸。

在2.34建立一個api,監聽12345埠,處理http的post請求和get請求,實現檔案上傳和檔案下載功能。

基於gin框架,編譯成二進位制檔案,丟到伺服器就能執行,無需處理依賴問題。

示例程式碼

package main

import (
	"fmt"
	"log"
	"net/http"
	"flag"
	"strconv"

	"github.com/gin-gonic/gin"
)

func main() {
	upload := flag.String("u","./","-u 指定檔案上傳目錄")
	download := flag.String("d","./","-d 指定檔案下載目錄")
	port := flag.Int("p",12345,"-p 指定監聽埠號")
	size := flag.Int64("s", 100, "-s 指定請求體檔案大小, 單位: MB")
	flag.Parse()

	r := gin.Default()

	r.Static("/download", *download)
	// 為 multipart forms 設定檔案大小限制, 預設是32MB
	// 此處為左移位運算子, << 20 表示1MiB,8 << 20就是8MiB
	r.MaxMultipartMemory = *size << 20 // 8 MiB
	r.POST("/upload", func(c *gin.Context) {
		// 單檔案
		file, _ := c.FormFile("file")
		log.Println(file.Filename)

		// 上傳檔案至指定的完整檔案路徑
		dst := *upload + file.Filename
		c.SaveUploadedFile(file, dst)

		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
	})
	listenAddr := "0.0.0.0:" + strconv.Itoa(*port)
	r.Run(listenAddr)
}

示例使用

# 在192.168.2.34先執行,設定請求體限制大小為1G
./appname -s 1000

# 上傳當前目錄下的test.tar.gz
curl -X POST 'http://192.168.2.34:12345/upload' -H "Content-Type: multipart/form-data" -F "file=@./test.tar.gz"
# 在其它能訪問到192.168.2.34的伺服器下載
curl -O http://192.168.2.34:12345/download/test.tar.gz