package middleware import ( "bytes" "github.com/gogf/gf/net/ghttp" "github.com/nfnt/resize" "gxt-file-server/app/agent" "gxt-file-server/app/errors" "gxt-file-server/pkg/gplus" "gxt-file-server/pkg/logger" "image" "image/jpeg" "image/png" "net/url" "path" "strconv" "strings" ) // FileMiddleWare 文件服务中间件 func FileMiddleWare(skippers ...SkipperFunc) ghttp.HandlerFunc { return func(r *ghttp.Request) { if len(skippers) > 0 && skippers[0](r) { r.Middleware.Next() return } ctx := gplus.NewContext(r) filePath, err := url.PathUnescape(r.Request.URL.Path) if err != nil { logger.Errorf(ctx, err.Error()) gplus.ResError(r, err) } var ( thumb string w uint h uint ) suffix := path.Ext(filePath) contentType := getContentType(suffix) fileData, _, err := agent.DefaultAgent().Get(ctx, filePath) if err != nil { gplus.ResError(r, errors.ErrFileNotFound) } thumb = r.GetString("thumb") if thumb == "1" && (contentType == "image/png" || contentType == "image/jpeg") { w = r.GetUint("w") h = r.GetUint("h") if w > 0 || h > 0 { img, format, err := image.Decode(bytes.NewBuffer(fileData)) if err != nil { return } if origWidth := uint(img.Bounds().Dx()); w > origWidth { w = origWidth } if origHeight := uint(img.Bounds().Dy()); h > origHeight { h = origHeight } img = resize.Resize(w, h, img, resize.Lanczos3) buf := new(bytes.Buffer) if format == "png" { png.Encode(buf, img) } else { jpeg.Encode(buf, img, nil) } if l := buf.Len(); l > 0 { fileData = buf.Bytes() } } } if strings.HasPrefix(contentType, "text/html") || strings.HasPrefix(contentType, "application/javascript") { contentType = "text/plain; charset=utf-8" } r.Response.Header().Set("Content-Type", contentType) r.Response.Header().Set("Cache-Control", "max-age=31536000") r.Response.Header().Set("Content-Length", strconv.FormatInt(int64(len(fileData)), 10)) r.Response.Write(fileData) } } func getContentType(suffix string) string{ fileContentType := make(map[string]string) fileContentType[".jpg"] = "image/jpeg" fileContentType[".jpeg"] = "image/jpeg" fileContentType[".gif"] = "image/gif" fileContentType[".png"] = "image/png" fileContentType[".mp4"] = "video/mp4" fileContentType[".mpg4"] = "video/mp4" fileContentType[".pdf"] = "application/pdf" if r,ok := fileContentType[suffix];ok{ return r } return "application/octet-stream" }