Golang HTTP上传下载

Golang HTTP上传下载

代码

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
)

func main() {
	reFilename := regexp.MustCompile(`[^/]+`)
	uploadRoot, _ := filepath.Abs(".")
	downloadRoot, _ := filepath.Abs(".")
	http.HandleFunc("/upload/", func(w http.ResponseWriter, r *http.Request) {
		err := r.ParseMultipartForm(10 * 1024 * 1024)
		if err != nil {
			log.Printf("ParseMultipartFrom error: %s\n", err)
			return
		}
		for _, headers := range r.MultipartForm.File {
			for _, header := range headers {
				log.Printf("Begin upload file: %s\n", header.Filename)
				if !reFilename.MatchString(header.Filename) {
					log.Printf("Accept filename %s error: cannot cotains /\n", header.Filename)
					return
				}
				filePath := filepath.Join(uploadRoot, header.Filename)
				dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
				if err != nil {
					log.Printf("Create file %s error: %s\n", filePath, err)
					return
				}
				srcFile, err := header.Open()
				if err != nil {
					log.Printf("open header failed: %s\n", err)
				}
				_, err = io.Copy(dstFile, srcFile)
				if err != nil {
					fmt.Printf("Write file %s error: %s\n", filePath, err)
				}
				_, _ = srcFile.Close(), dstFile.Close()
			}
		}
	})


	http.Handle("/download/", http.StripPrefix(
		"/download/",
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("Begin download file: %s\n", r.URL.String())
			http.FileServer(http.Dir(downloadRoot)).ServeHTTP(w, r)
		}),
	))
	log.Println("http server start at :8080")
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

验证

Golang HTTP上传下载

HTTP上传原理

# 同时上传两个文件upload.txt 和 upload.7z
curl -v -F upload.txt=@"upload.txt" -F upload.7z=@"upload.7z" http://127.0.0.1:8080/upload/

Fiddler 抓包内容如下

参考: https://blog.csdn.net/qq_33706382/article/details/78168325

POST http://127.0.0.1:8080/upload/ HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: curl/7.58.0
Accept: */*
Connection: Keep-Alive
Content-Length: 676
Content-Type: multipart/form-data; boundary=------------------------b3729e791dc27dbc

--------------------------b3729e791dc27dbc
Content-Disposition: form-data; name="upload.txt"; filename="upload.txt"
Content-Type: text/plain

upload.txt content

--------------------------b3729e791dc27dbc
Content-Disposition: form-data; name="upload.7z"; filename="upload.7z"
Content-Type: application/octet-stream

7z'ybo]:	E#n@ѺwZnũ:DbZ_9DH
="%? N0Ĩ(^eGGKɲ(mC6ç!W3xQQ
^]
nD'[')	fGjx	E1;fm
G|Aw 	 
!!
e?
UPLOAD.TXT
dŠ 
--------------------------b3729e791dc27dbc--

上一篇:element-ui v-for循环el-upload上传图片


下一篇:element-ui upload组件手动上传 , 一次请求多张图片合并上传到PHP后台