2.5goweb原生实现HTTP文件上传功能

在Go语言中,使用原生net/http包实现HTTP文件上传功能,主要依赖multipart/form-data编码解析和文件流处理。

package main

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

func main() {
	_, err := os.Stat(".\\uploads")
	if err == nil {

	}
	if os.IsNotExist(err) {
		// 文件夹不存在,创建文件夹
		err := os.MkdirAll(".\\uploads", 0755)
		if err != nil {
			fmt.Errorf("创建文件夹失败: %w", err)
		}

	}
	// 其他错误
	fmt.Errorf("检查文件夹时出错: %w", err)

	http.HandleFunc("/upload", uploadHandler)


	log.Fatalln(http.ListenAndServe(":80", nil))
}

// 支持多文件/大文件上传
func uploadHandler(w http.ResponseWriter, r *http.Request) {
	// 1. 安全校验
	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	// 2. 限制上传大小(10GB)
	r.Body = http.MaxBytesReader(w, r.Body, 10<<30)

	// 3. 多文件处理
	if err := r.ParseMultipartForm(32 << 20); err != nil {
		log.Printf("Upload failed: %v", err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	// 4. 遍历处理文件
	files := r.MultipartForm.File["files"]
	fmt.Println(files)
	for _, fileHeader := range files {
		file, err := fileHeader.Open()
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer file.Close()

		// 5. 安全存储
		safePath := filepath.Join("uploads", filepath.Base(fileHeader.Filename))
		fmt.Println(filepath.Base(fileHeader.Filename))
		if strings.Contains(safePath, "..") {
			http.Error(w, "Invalid file path", http.StatusBadRequest)
			return
		}
		fmt.Println(safePath)
		dst, err := os.Create(safePath)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer dst.Close()

		if _, err := io.Copy(dst, file); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	w.Write([]byte("Upload successful"))
}


使用curl 测试:

D:

echo "hello world,file test upload" >> file.txt

curl -H "Content-Type: multipart/form-data" -F "[email protected]" http://localhost/upload

你可能感兴趣的:(go语言,#,go高级部分,go)