Abstract the file download things.
This commit is contained in:
@ -17,6 +17,7 @@ type AlienController struct {
|
|||||||
matterService *MatterService
|
matterService *MatterService
|
||||||
imageCacheDao *ImageCacheDao
|
imageCacheDao *ImageCacheDao
|
||||||
imageCacheService *ImageCacheService
|
imageCacheService *ImageCacheService
|
||||||
|
alienService *AlienService
|
||||||
}
|
}
|
||||||
|
|
||||||
//初始化方法
|
//初始化方法
|
||||||
@ -54,6 +55,11 @@ func (this *AlienController) Init(context *Context) {
|
|||||||
this.imageCacheService = c
|
this.imageCacheService = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.alienService)
|
||||||
|
if c, ok := b.(*AlienService); ok {
|
||||||
|
this.alienService = c
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//注册自己的路由。
|
//注册自己的路由。
|
||||||
@ -77,17 +83,27 @@ func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *h
|
|||||||
|
|
||||||
path := request.URL.Path
|
path := request.URL.Path
|
||||||
|
|
||||||
//匹配 /api/alien/download/{uuid}/{filename}
|
//匹配 /api/alien/preview/{uuid}/{filename} (响应头不包含 content-disposition)
|
||||||
reg := regexp.MustCompile(`^/api/alien/download/([^/]+)/([^/]+)$`)
|
reg := regexp.MustCompile(`^/api/alien/preview/([^/]+)/([^/]+)$`)
|
||||||
strs := reg.FindStringSubmatch(path)
|
strs := reg.FindStringSubmatch(path)
|
||||||
if len(strs) != 3 {
|
if len(strs) == 3 {
|
||||||
return nil, false
|
var f = func(writer http.ResponseWriter, request *http.Request) {
|
||||||
} else {
|
this.Preview(writer, request, strs[1], strs[2])
|
||||||
|
}
|
||||||
|
return f, true
|
||||||
|
}
|
||||||
|
|
||||||
|
//匹配 /api/alien/download/{uuid}/{filename} (响应头包含 content-disposition)
|
||||||
|
reg = regexp.MustCompile(`^/api/alien/download/([^/]+)/([^/]+)$`)
|
||||||
|
strs = reg.FindStringSubmatch(path)
|
||||||
|
if len(strs) == 3 {
|
||||||
var f = func(writer http.ResponseWriter, request *http.Request) {
|
var f = func(writer http.ResponseWriter, request *http.Request) {
|
||||||
this.Download(writer, request, strs[1], strs[2])
|
this.Download(writer, request, strs[1], strs[2])
|
||||||
}
|
}
|
||||||
return f, true
|
return f, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
//直接使用邮箱和密码获取用户
|
//直接使用邮箱和密码获取用户
|
||||||
@ -385,71 +401,17 @@ func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, requ
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//下载一个文件。既可以使用登录的方式下载,也可以使用授权的方式下载。
|
|
||||||
func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
|
||||||
|
|
||||||
matter := this.matterDao.CheckByUuid(uuid)
|
//预览一个文件。既可以使用登录的方式,也可以使用授权的方式
|
||||||
|
func (this *AlienController) Preview(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||||
//判断是否是文件夹
|
|
||||||
if matter.Dir {
|
|
||||||
panic("暂不支持下载文件夹")
|
|
||||||
}
|
|
||||||
|
|
||||||
if matter.Name != filename {
|
|
||||||
panic("文件信息错误")
|
|
||||||
}
|
|
||||||
|
|
||||||
//验证用户的权限问题。
|
|
||||||
//文件如果是私有的才需要权限
|
|
||||||
if matter.Privacy {
|
|
||||||
|
|
||||||
//1.如果带有downloadTokenUuid那么就按照token的信息去获取。
|
|
||||||
downloadTokenUuid := request.FormValue("downloadTokenUuid")
|
|
||||||
if downloadTokenUuid != "" {
|
|
||||||
downloadToken := this.downloadTokenDao.CheckByUuid(downloadTokenUuid)
|
|
||||||
if downloadToken.ExpireTime.Before(time.Now()) {
|
|
||||||
panic("downloadToken已失效")
|
|
||||||
}
|
|
||||||
|
|
||||||
if downloadToken.MatterUuid != uuid {
|
|
||||||
panic("token和文件信息不一致")
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenUser := this.userDao.CheckByUuid(downloadToken.UserUuid)
|
|
||||||
if matter.UserUuid != tokenUser.Uuid {
|
|
||||||
panic(CODE_WRAPPER_UNAUTHORIZED)
|
|
||||||
}
|
|
||||||
|
|
||||||
//下载之后立即过期掉。
|
|
||||||
downloadToken.ExpireTime = time.Now().AddDate(0, 0, 1);
|
|
||||||
this.downloadTokenDao.Save(downloadToken)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//判断文件的所属人是否正确
|
|
||||||
user := this.checkUser(writer, request)
|
|
||||||
if user.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != user.Uuid {
|
|
||||||
panic(CODE_WRAPPER_UNAUTHORIZED)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//对图片处理。
|
|
||||||
needProcess, _, _, _ := this.imageCacheService.ResizeParams(request)
|
|
||||||
if needProcess {
|
|
||||||
|
|
||||||
//如果是图片,那么能用缓存就用缓存
|
|
||||||
imageCache := this.imageCacheDao.FindByUri(request.RequestURI)
|
|
||||||
if imageCache == nil {
|
|
||||||
imageCache = this.imageCacheService.cacheImage(writer, request, matter)
|
|
||||||
}
|
|
||||||
|
|
||||||
//直接使用缓存中的信息
|
|
||||||
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+imageCache.Path, matter.Name)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
operator := this.findUser(writer, request)
|
||||||
|
this.alienService.PreviewOrDownload(writer, request, uuid, filename, operator, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//下载一个文件。既可以使用登录的方式,也可以使用授权的方式
|
||||||
|
func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||||
|
operator := this.findUser(writer, request)
|
||||||
|
this.alienService.PreviewOrDownload(writer, request, uuid, filename, operator, true)
|
||||||
}
|
}
|
||||||
|
135
rest/alien_service.go
Normal file
135
rest/alien_service.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
//@Service
|
||||||
|
type AlienService struct {
|
||||||
|
Bean
|
||||||
|
matterDao *MatterDao
|
||||||
|
matterService *MatterService
|
||||||
|
userDao *UserDao
|
||||||
|
uploadTokenDao *UploadTokenDao
|
||||||
|
downloadTokenDao *DownloadTokenDao
|
||||||
|
imageCacheDao *ImageCacheDao
|
||||||
|
imageCacheService *ImageCacheService
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化方法
|
||||||
|
func (this *AlienService) Init(context *Context) {
|
||||||
|
|
||||||
|
//手动装填本实例的Bean. 这里必须要用中间变量方可。
|
||||||
|
b := context.GetBean(this.matterDao)
|
||||||
|
if b, ok := b.(*MatterDao); ok {
|
||||||
|
this.matterDao = b
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.matterService)
|
||||||
|
if b, ok := b.(*MatterService); ok {
|
||||||
|
this.matterService = b
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.userDao)
|
||||||
|
if b, ok := b.(*UserDao); ok {
|
||||||
|
this.userDao = b
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.uploadTokenDao)
|
||||||
|
if c, ok := b.(*UploadTokenDao); ok {
|
||||||
|
this.uploadTokenDao = c
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.downloadTokenDao)
|
||||||
|
if c, ok := b.(*DownloadTokenDao); ok {
|
||||||
|
this.downloadTokenDao = c
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.imageCacheDao)
|
||||||
|
if c, ok := b.(*ImageCacheDao); ok {
|
||||||
|
this.imageCacheDao = c
|
||||||
|
}
|
||||||
|
|
||||||
|
b = context.GetBean(this.imageCacheService)
|
||||||
|
if c, ok := b.(*ImageCacheService); ok {
|
||||||
|
this.imageCacheService = c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//预览或者下载的统一处理.
|
||||||
|
func (this *AlienService) PreviewOrDownload(
|
||||||
|
writer http.ResponseWriter,
|
||||||
|
request *http.Request,
|
||||||
|
uuid string,
|
||||||
|
filename string,
|
||||||
|
operator *User,
|
||||||
|
withContentDisposition bool) {
|
||||||
|
|
||||||
|
LogInfo("预览或下载文件 " + uuid + " " + filename)
|
||||||
|
|
||||||
|
matter := this.matterDao.CheckByUuid(uuid)
|
||||||
|
|
||||||
|
//判断是否是文件夹
|
||||||
|
if matter.Dir {
|
||||||
|
panic("不支持下载文件夹")
|
||||||
|
}
|
||||||
|
|
||||||
|
if matter.Name != filename {
|
||||||
|
panic("文件信息错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证用户的权限问题。
|
||||||
|
//文件如果是私有的才需要权限
|
||||||
|
if matter.Privacy {
|
||||||
|
|
||||||
|
//1.如果带有downloadTokenUuid那么就按照token的信息去获取。
|
||||||
|
downloadTokenUuid := request.FormValue("downloadTokenUuid")
|
||||||
|
if downloadTokenUuid != "" {
|
||||||
|
downloadToken := this.downloadTokenDao.CheckByUuid(downloadTokenUuid)
|
||||||
|
if downloadToken.ExpireTime.Before(time.Now()) {
|
||||||
|
panic("downloadToken已失效")
|
||||||
|
}
|
||||||
|
|
||||||
|
if downloadToken.MatterUuid != uuid {
|
||||||
|
panic("token和文件信息不一致")
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenUser := this.userDao.CheckByUuid(downloadToken.UserUuid)
|
||||||
|
if matter.UserUuid != tokenUser.Uuid {
|
||||||
|
panic(CODE_WRAPPER_UNAUTHORIZED)
|
||||||
|
}
|
||||||
|
|
||||||
|
//下载之后立即过期掉。
|
||||||
|
downloadToken.ExpireTime = time.Now().AddDate(0, 0, 1);
|
||||||
|
this.downloadTokenDao.Save(downloadToken)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//判断文件的所属人是否正确
|
||||||
|
if operator == nil || (operator.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != operator.Uuid) {
|
||||||
|
panic(CODE_WRAPPER_UNAUTHORIZED)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//对图片处理。
|
||||||
|
needProcess, imageResizeM, imageResizeW, imageResizeH := this.imageCacheService.ResizeParams(request)
|
||||||
|
if needProcess {
|
||||||
|
|
||||||
|
//如果是图片,那么能用缓存就用缓存
|
||||||
|
imageCache := this.imageCacheDao.FindByMatterUuidAndMode(matter.Uuid, fmt.Sprintf("%s_%d_%d", imageResizeM, imageResizeW, imageResizeH))
|
||||||
|
if imageCache == nil {
|
||||||
|
imageCache = this.imageCacheService.cacheImage(writer, request, matter)
|
||||||
|
}
|
||||||
|
|
||||||
|
//直接使用缓存中的信息
|
||||||
|
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+imageCache.Path, matter.Name, withContentDisposition)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name, withContentDisposition)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -131,6 +131,7 @@ func (this *BaseController) Error(err interface{}) *WebResult {
|
|||||||
return webResult
|
return webResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//能找到一个user就找到一个,遇到问题直接抛出错误
|
||||||
func (this *BaseController) checkLogin(writer http.ResponseWriter, request *http.Request) (*Session, *User) {
|
func (this *BaseController) checkLogin(writer http.ResponseWriter, request *http.Request) (*Session, *User) {
|
||||||
|
|
||||||
//验证用户是否已经登录。
|
//验证用户是否已经登录。
|
||||||
@ -159,11 +160,35 @@ func (this *BaseController) checkLogin(writer http.ResponseWriter, request *http
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BaseController) checkUser(writer http.ResponseWriter, request *http.Request) *User {
|
//能找到一个user就找到一个
|
||||||
|
func (this *BaseController) findUser(writer http.ResponseWriter, request *http.Request) *User {
|
||||||
|
|
||||||
|
//验证用户是否已经登录。
|
||||||
|
sessionCookie, err := request.Cookie(COOKIE_AUTH_KEY)
|
||||||
|
if err != nil {
|
||||||
|
LogError("找不到任何登录信息")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
session := this.sessionDao.FindByUuid(sessionCookie.Value)
|
||||||
|
if session != nil {
|
||||||
|
if session.ExpireTime.Before(time.Now()) {
|
||||||
|
LogError("登录信息已过期")
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
user := this.userDao.FindByUuid(session.UserUuid)
|
||||||
|
if user != nil {
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *BaseController) checkUser(writer http.ResponseWriter, request *http.Request) *User {
|
||||||
_, user := this.checkLogin(writer, request)
|
_, user := this.checkLogin(writer, request)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//允许跨域请求
|
//允许跨域请求
|
||||||
|
@ -95,6 +95,7 @@ func (this *Context) registerBeans() {
|
|||||||
|
|
||||||
//alien
|
//alien
|
||||||
this.registerBean(new(AlienController))
|
this.registerBean(new(AlienController))
|
||||||
|
this.registerBean(new(AlienService))
|
||||||
|
|
||||||
//downloadToken
|
//downloadToken
|
||||||
this.registerBean(new(DownloadTokenDao))
|
this.registerBean(new(DownloadTokenDao))
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/nu7hatch/gouuid"
|
"github.com/nu7hatch/gouuid"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ImageCacheDao struct {
|
type ImageCacheDao struct {
|
||||||
@ -38,11 +39,17 @@ func (this *ImageCacheDao) CheckByUuid(uuid string) *ImageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//按照名字查询文件夹
|
//按照名字查询文件夹
|
||||||
func (this *ImageCacheDao) FindByUri(uri string) *ImageCache {
|
func (this *ImageCacheDao) FindByMatterUuidAndMode(matterUuid string, mode string) *ImageCache {
|
||||||
|
|
||||||
var wp = &WherePair{}
|
var wp = &WherePair{}
|
||||||
|
|
||||||
wp = wp.And(&WherePair{Query: "uri = ?", Args: []interface{}{uri}})
|
if matterUuid != "" {
|
||||||
|
wp = wp.And(&WherePair{Query: "matter_uuid = ?", Args: []interface{}{matterUuid}})
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode != "" {
|
||||||
|
wp = wp.And(&WherePair{Query: "mode = ?", Args: []interface{}{mode}})
|
||||||
|
}
|
||||||
|
|
||||||
var imageCache = &ImageCache{}
|
var imageCache = &ImageCache{}
|
||||||
db := this.context.DB.Model(&ImageCache{}).Where(wp.Query, wp.Args...).First(imageCache)
|
db := this.context.DB.Model(&ImageCache{}).Where(wp.Query, wp.Args...).First(imageCache)
|
||||||
@ -107,6 +114,7 @@ func (this *ImageCacheDao) Page(page int, pageSize int, userUuid string, matterU
|
|||||||
return pager
|
return pager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//创建
|
//创建
|
||||||
func (this *ImageCacheDao) Create(imageCache *ImageCache) *ImageCache {
|
func (this *ImageCacheDao) Create(imageCache *ImageCache) *ImageCache {
|
||||||
|
|
||||||
@ -130,18 +138,36 @@ func (this *ImageCacheDao) Save(imageCache *ImageCache) *ImageCache {
|
|||||||
return imageCache
|
return imageCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//删除一个文件包括文件夹
|
||||||
|
func (this *ImageCacheDao) deleteFileAndDir(imageCache *ImageCache) {
|
||||||
|
|
||||||
|
filePath := CONFIG.MatterPath + imageCache.Path
|
||||||
|
//递归找寻文件的上级目录uuid. 因为是/开头的缘故
|
||||||
|
parts := strings.Split(imageCache.Path, "/")
|
||||||
|
dirPath := CONFIG.MatterPath + "/" + parts[1] + "/" + parts[2] + "/" + parts[3] + "/" + parts[4]
|
||||||
|
|
||||||
|
//删除文件
|
||||||
|
err := os.Remove(filePath)
|
||||||
|
if err != nil {
|
||||||
|
LogError(fmt.Sprintf("删除磁盘上的文件%s出错,不做任何处理 %s", filePath, err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除这一层文件夹
|
||||||
|
err = os.Remove(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
LogError(fmt.Sprintf("删除磁盘上的文件夹%s出错,不做任何处理 %s", dirPath, err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//删除一个文件,数据库中删除,物理磁盘上删除。
|
//删除一个文件,数据库中删除,物理磁盘上删除。
|
||||||
func (this *ImageCacheDao) Delete(imageCache *ImageCache) {
|
func (this *ImageCacheDao) Delete(imageCache *ImageCache) {
|
||||||
|
|
||||||
db := this.context.DB.Delete(&imageCache)
|
db := this.context.DB.Delete(&imageCache)
|
||||||
this.PanicError(db.Error)
|
this.PanicError(db.Error)
|
||||||
|
|
||||||
//删除文件
|
this.deleteFileAndDir(imageCache)
|
||||||
err := os.Remove(CONFIG.MatterPath + imageCache.Path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
LogError(fmt.Sprintf("删除磁盘上的文件出错,不做任何处理 %s", err.Error()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//删除一个matter对应的所有缓存
|
//删除一个matter对应的所有缓存
|
||||||
@ -162,10 +188,7 @@ func (this *ImageCacheDao) DeleteByMatterUuid(matterUuid string) {
|
|||||||
|
|
||||||
//删除文件实体
|
//删除文件实体
|
||||||
for _, imageCache := range imageCaches {
|
for _, imageCache := range imageCaches {
|
||||||
err := os.Remove(CONFIG.MatterPath + imageCache.Path)
|
this.deleteFileAndDir(imageCache)
|
||||||
if err != nil {
|
|
||||||
LogError(fmt.Sprintf("删除磁盘上的文件出错,不做任何处理"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ type ImageCache struct {
|
|||||||
Base
|
Base
|
||||||
UserUuid string `json:"userUuid"`
|
UserUuid string `json:"userUuid"`
|
||||||
MatterUuid string `json:"matterUuid"`
|
MatterUuid string `json:"matterUuid"`
|
||||||
Uri string `json:"uri"`
|
Mode string `json:"mode"`
|
||||||
Md5 string `json:"md5"`
|
Md5 string `json:"md5"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"net/url"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
//@Service
|
//@Service
|
||||||
@ -108,7 +108,6 @@ func (this *ImageCacheService) ResizeParams(request *http.Request) (needProcess
|
|||||||
}
|
}
|
||||||
return true, imageResizeM, imageResizeW, imageResizeH
|
return true, imageResizeM, imageResizeW, imageResizeH
|
||||||
} else {
|
} else {
|
||||||
LogInfo("没有有效的处理参数,不进行图片处理")
|
|
||||||
return false, "", 0, 0
|
return false, "", 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,11 +167,8 @@ func (this *ImageCacheService) ResizeImage(request *http.Request, filePath strin
|
|||||||
//缓存一张处理完毕了的图片
|
//缓存一张处理完毕了的图片
|
||||||
func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *http.Request, matter *Matter) *ImageCache {
|
func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *http.Request, matter *Matter) *ImageCache {
|
||||||
|
|
||||||
// 防止中文乱码
|
|
||||||
fileName := url.QueryEscape(matter.Name)
|
|
||||||
|
|
||||||
//当前的文件是否是图片,只有图片才能处理。
|
//当前的文件是否是图片,只有图片才能处理。
|
||||||
extension := GetExtension(fileName)
|
extension := GetExtension(matter.Name)
|
||||||
formats := map[string]imaging.Format{
|
formats := map[string]imaging.Format{
|
||||||
".jpg": imaging.JPEG,
|
".jpg": imaging.JPEG,
|
||||||
".jpeg": imaging.JPEG,
|
".jpeg": imaging.JPEG,
|
||||||
@ -194,8 +190,8 @@ func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *h
|
|||||||
user := this.userDao.FindByUuid(matter.UserUuid)
|
user := this.userDao.FindByUuid(matter.UserUuid)
|
||||||
//获取文件应该存放在的物理路径的绝对路径和相对路径。
|
//获取文件应该存放在的物理路径的绝对路径和相对路径。
|
||||||
absolutePath, relativePath := GetUserFilePath(user.Username, true)
|
absolutePath, relativePath := GetUserFilePath(user.Username, true)
|
||||||
absolutePath = absolutePath + "/" + fileName
|
absolutePath = absolutePath + "/" + matter.Name
|
||||||
relativePath = relativePath + "/" + fileName
|
relativePath = relativePath + "/" + matter.Name
|
||||||
|
|
||||||
fileWriter, err := os.Create(absolutePath)
|
fileWriter, err := os.Create(absolutePath)
|
||||||
this.PanicError(err)
|
this.PanicError(err)
|
||||||
@ -209,11 +205,13 @@ func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *h
|
|||||||
fileInfo, err := fileWriter.Stat()
|
fileInfo, err := fileWriter.Stat()
|
||||||
this.PanicError(err)
|
this.PanicError(err)
|
||||||
|
|
||||||
|
_, imageResizeM, imageResizeW, imageResizeH := this.ResizeParams(request)
|
||||||
|
|
||||||
//相关信息写到缓存中去
|
//相关信息写到缓存中去
|
||||||
imageCache := &ImageCache{
|
imageCache := &ImageCache{
|
||||||
UserUuid: matter.UserUuid,
|
UserUuid: matter.UserUuid,
|
||||||
MatterUuid: matter.Uuid,
|
MatterUuid: matter.Uuid,
|
||||||
Uri: request.RequestURI,
|
Mode: fmt.Sprintf("%s_%d_%d", imageResizeM, imageResizeW, imageResizeH),
|
||||||
Size: fileInfo.Size(),
|
Size: fileInfo.Size(),
|
||||||
Path: relativePath,
|
Path: relativePath,
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/nu7hatch/gouuid"
|
"github.com/nu7hatch/gouuid"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MatterDao struct {
|
type MatterDao struct {
|
||||||
@ -238,11 +239,21 @@ func (this *MatterDao) Delete(matter *Matter) {
|
|||||||
//删除对应的缓存图片。
|
//删除对应的缓存图片。
|
||||||
this.imageCacheDao.DeleteByMatterUuid(matter.Uuid)
|
this.imageCacheDao.DeleteByMatterUuid(matter.Uuid)
|
||||||
|
|
||||||
//删除文件
|
filePath := CONFIG.MatterPath + matter.Path
|
||||||
err := os.Remove(CONFIG.MatterPath + matter.Path)
|
//递归找寻文件的上级目录uuid. 因为是/开头的缘故
|
||||||
|
parts := strings.Split(matter.Path, "/")
|
||||||
|
dirPath := CONFIG.MatterPath + "/" + parts[1] + "/" + parts[2] + "/" + parts[3]
|
||||||
|
|
||||||
|
//删除文件
|
||||||
|
err := os.Remove(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError(fmt.Sprintf("删除磁盘上的文件出错,不做任何处理"))
|
LogError(fmt.Sprintf("删除磁盘上的文件出错,不做任何处理 %s", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除这一层文件夹
|
||||||
|
err = os.Remove(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
LogError(fmt.Sprintf("删除磁盘上的文件夹出错,不做任何处理 %s", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,15 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
//@Service
|
//@Service
|
||||||
@ -431,20 +430,22 @@ func (this *MatterService) sumRangesSize(ranges []httpRange) (size int64) {
|
|||||||
|
|
||||||
//文件下载。具有进度功能。
|
//文件下载。具有进度功能。
|
||||||
//下载功能参考:https://github.com/Masterminds/go-fileserver
|
//下载功能参考:https://github.com/Masterminds/go-fileserver
|
||||||
func (this *MatterService) DownloadFile(writer http.ResponseWriter, request *http.Request, filePath string, filename string) {
|
func (this *MatterService) DownloadFile(
|
||||||
|
writer http.ResponseWriter,
|
||||||
|
request *http.Request,
|
||||||
|
filePath string,
|
||||||
|
filename string,
|
||||||
|
withContentDisposition bool) {
|
||||||
|
|
||||||
diskFile, err := os.Open(filePath)
|
diskFile, err := os.Open(filePath)
|
||||||
this.PanicError(err)
|
this.PanicError(err)
|
||||||
defer diskFile.Close()
|
defer diskFile.Close()
|
||||||
|
|
||||||
//如果是图片或者文本或者视频就直接打开。其余的一律以下载形式返回。
|
//如果是图片或者文本或者视频就直接打开。其余的一律以下载形式返回。
|
||||||
//fileName := url.QueryEscape(filename)
|
if withContentDisposition {
|
||||||
//mimeType := GetMimeType(fileName)
|
fileName := url.QueryEscape(filename)
|
||||||
//if strings.Index(mimeType, "image") != 0 &&
|
writer.Header().Set("content-disposition", "attachment; filename=\""+fileName+"\"")
|
||||||
// strings.Index(mimeType, "text") != 0 &&
|
}
|
||||||
// strings.Index(mimeType, "video") != 0 {
|
|
||||||
// writer.Header().Set("content-disposition", "attachment; filename=\""+fileName+"\"")
|
|
||||||
//}
|
|
||||||
|
|
||||||
//显示文件大小。
|
//显示文件大小。
|
||||||
fileInfo, err := diskFile.Stat()
|
fileInfo, err := diskFile.Stat()
|
||||||
@ -473,7 +474,10 @@ func (this *MatterService) DownloadFile(writer http.ResponseWriter, request *htt
|
|||||||
ctypes, haveType := writer.Header()["Content-Type"]
|
ctypes, haveType := writer.Header()["Content-Type"]
|
||||||
var ctype string
|
var ctype string
|
||||||
if !haveType {
|
if !haveType {
|
||||||
ctype = mime.TypeByExtension(filepath.Ext(fileInfo.Name()))
|
//放弃原有的判断mime的方法
|
||||||
|
//ctype = mime.TypeByExtension(filepath.Ext(fileInfo.Name()))
|
||||||
|
//使用mimeUtil来获取mime
|
||||||
|
ctype = GetFallbackMimeType(filename, "")
|
||||||
if ctype == "" {
|
if ctype == "" {
|
||||||
// read a chunk to decide between utf-8 text and binary
|
// read a chunk to decide between utf-8 text and binary
|
||||||
var buf [sniffLen]byte
|
var buf [sniffLen]byte
|
||||||
|
1234
rest/util_mime.go
1234
rest/util_mime.go
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user