`
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"log"
"mime"
"net/http"
"path/filepath"
)
const saveDir = "./uploads"
const maxUploadSize = 1024 * 1024 * 1024 * 2
func ApiErrorResult(writer io.Writer, code int , msg string) {
s := fmt.Sprintf({"code": %d, "msg": %s}
, code, msg)
_, _ = writer.Write([]byte(s))
}
func ApiResult(writer io.Writer, code int , msg string) {
s := fmt.Sprintf({"code": %d, "msg": %s}
, code, msg)
_, _ = writer.Write([]byte(s))
}
func handleFileUpload(resp http.ResponseWriter, req *http.Request) {
// 设置最大读取
req.Body = http.MaxBytesReader(resp, req.Body, maxUploadSize)
if err := req.ParseMultipartForm(maxUploadSize); err != nil {
ApiErrorResult(resp,-1, "上传文件太大")
return
}
uploadFile, _, err := req.FormFile("file")
if err != nil {
ApiErrorResult(resp, -1, err.Error())
return
}
var fileType string
fileData, err := ioutil.ReadAll(uploadFile);
if err != nil {
ApiErrorResult(resp,-1, err.Error())
return
} else {
// 从文件中读取类型
fileType = http.DetectContentType(fileData)
}
// 检测是否支持的类型
fileEndings, err := mime.ExtensionsByType(fileType)
if err != nil {
ApiErrorResult(resp,-1, err.Error())
return
}
if len(fileEndings) == 0 {
ApiErrorResult(resp,-1, "不支持此文件类型上传")
return
}
fileMd5 := md5.New()
fileMd5.Write(fileData)
fileName := filepath.Join(saveDir,hex.EncodeToString(fileMd5.Sum(nil))+ fileEndings[0])
if err := ioutil.WriteFile(fileName, fileData, 0777); err == nil {
ApiResult(resp, 0, "上传成功")
return
} else {
ApiErrorResult(resp, -1, err.Error())
}
}
func main() {
http.HandleFunc("/upload", handleFileUpload)
http.Handle("/files/", http.StripPrefix("/files/", http.FileServer(http.Dir(saveDir))))
log.Print("正在监听:8080服务")
http.ListenAndServe(":8080", nil)
}
`