[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
posted @ 2022-12-07 11:12  花酒锄作田  阅读(743)  评论(0编辑  收藏  举报