diff --git a/rest/bean.go b/rest/bean.go index bd9cd6c..4635c3f 100644 --- a/rest/bean.go +++ b/rest/bean.go @@ -1,6 +1,7 @@ package rest import ( + "fmt" "net/http" ) @@ -33,37 +34,35 @@ func (this *Bean) PanicError(err error) { } //请求参数有问题 -func (this *Bean) PanicBadRequest(msg string) { - panic(CustomWebResult(CODE_WRAPPER_BAD_REQUEST, msg)) +func (this *Bean) PanicBadRequest(format string, v ...interface{}) { + panic(CustomWebResult(CODE_WRAPPER_BAD_REQUEST, fmt.Sprintf(format, v...))) } //没有权限 -func (this *Bean) PanicUnauthorized(msg string) { - panic(CustomWebResult(CODE_WRAPPER_UNAUTHORIZED, msg)) +func (this *Bean) PanicUnauthorized(format string, v ...interface{}) { + panic(CustomWebResult(CODE_WRAPPER_UNAUTHORIZED, fmt.Sprintf(format, v...))) } //没有找到 -func (this *Bean) PanicNotFound(msg string) { - panic(CustomWebResult(CODE_WRAPPER_NOT_FOUND, msg)) +func (this *Bean) PanicNotFound(format string, v ...interface{}) { + panic(CustomWebResult(CODE_WRAPPER_NOT_FOUND, fmt.Sprintf(format, v...))) } //服务器内部出问题 -func (this *Bean) PanicServer(msg string) { - panic(CustomWebResult(CODE_WRAPPER_UNKNOWN, msg)) +func (this *Bean) PanicServer(format string, v ...interface{}) { + panic(CustomWebResult(CODE_WRAPPER_SERVER, fmt.Sprintf(format, v...))) } //能找到一个user就找到一个 func (this *Bean) findUser(writer http.ResponseWriter, request *http.Request) *User { //验证用户是否已经登录。 - sessionCookie, err := request.Cookie(COOKIE_AUTH_KEY) - if err != nil { - this.logger.Warn("cookie 信息不存在~") + //登录身份有效期以数据库中记录的为准 + sessionId := GetSessionUuidFromRequest(request) + if sessionId == "" { return nil } - sessionId := sessionCookie.Value - //去缓存中捞取看看 cacheItem, err := CONTEXT.SessionCache.Value(sessionId) if err != nil { diff --git a/rest/image_cache_service.go b/rest/image_cache_service.go index 5bc346a..b23a554 100644 --- a/rest/image_cache_service.go +++ b/rest/image_cache_service.go @@ -119,7 +119,10 @@ func (this *ImageCacheService) ResizeImage(request *http.Request, filePath strin diskFile, err := os.Open(filePath) this.PanicError(err) - defer diskFile.Close() + defer func() { + e := diskFile.Close() + this.PanicError(e) + }() _, imageResizeM, imageResizeW, imageResizeH := this.ResizeParams(request) @@ -190,13 +193,16 @@ func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *h user := this.userDao.FindByUuid(matter.UserUuid) //获取文件应该存放在的物理路径的绝对路径和相对路径。 - absolutePath, relativePath := GetUserFilePath(user.Username, true) + absolutePath, relativePath := GetUserFileDir(user.Username, true) absolutePath = absolutePath + "/" + matter.Name relativePath = relativePath + "/" + matter.Name fileWriter, err := os.Create(absolutePath) this.PanicError(err) - defer fileWriter.Close() + defer func() { + e := fileWriter.Close() + this.PanicError(e) + }() //处理后的图片存放在本地 err = imaging.Encode(fileWriter, dstImage, format) diff --git a/rest/matter_controller.go b/rest/matter_controller.go index 7c51343..d0f0618 100644 --- a/rest/matter_controller.go +++ b/rest/matter_controller.go @@ -151,7 +151,6 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques dirPath := MakeDirAll(CONFIG.MatterPath + path) this.logger.Info("Create Directory: %s", dirPath) - //数据库中创建文件夹。 matter := &Matter{ Puuid: puuid, @@ -162,7 +161,6 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques } matter = this.matterDao.Create(matter) - return this.Success(matter) } @@ -291,7 +289,11 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R file, handler, err := request.FormFile("file") this.PanicError(err) - defer file.Close() + + defer func() { + err := file.Close() + this.PanicError(err) + }() //对于IE浏览器,filename可能包含了路径。 fileName := handler.Filename diff --git a/rest/matter_service.go b/rest/matter_service.go index 83a30c2..f873735 100644 --- a/rest/matter_service.go +++ b/rest/matter_service.go @@ -124,16 +124,34 @@ func (this *MatterService) Upload(file multipart.File, user *User, puuid string, panic("文件名不能超过200") } + //查找文件夹下面是否有同名文件。 + matters := this.matterDao.ListByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, false, filename) + //如果有同名的文件,那么我们直接覆盖同名文件。 + for _, dbFile := range matters { + this.PanicBadRequest("该目录下%s已经存在了", dbFile.Name) + } //获取文件应该存放在的物理路径的绝对路径和相对路径。 - absolutePath, relativePath := GetUserFilePath(user.Username, false) + absolutePath, relativePath := GetUserFileDir(user.Username, false) absolutePath = absolutePath + "/" + filename relativePath = relativePath + "/" + filename + //如果文件已经存在了,那么直接覆盖。 + exist, err := PathExists(absolutePath) + this.PanicError(err) + if exist { + this.logger.Error("%s已经存在,将其删除", absolutePath) + removeError := os.Remove(absolutePath) + this.PanicError(removeError) + } + distFile, err := os.OpenFile(absolutePath, os.O_WRONLY|os.O_CREATE, 0777) this.PanicError(err) - defer distFile.Close() + defer func() { + err := distFile.Close() + this.PanicError(err) + }() written, err := io.Copy(distFile, file) this.PanicError(err) @@ -145,12 +163,7 @@ func (this *MatterService) Upload(file multipart.File, user *User, puuid string, } } - //查找文件夹下面是否有同名文件。 - matters := this.matterDao.ListByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, false, filename) - //如果有同名的文件,那么我们直接覆盖同名文件。 - for _, dbFile := range matters { - this.matterDao.Delete(dbFile) - } + //将文件信息存入数据库中。 matter := &Matter{ @@ -178,14 +191,20 @@ func (this *MatterService) httpDownloadFile(filepath string, url string) (int64, if err != nil { return 0, err } - defer out.Close() + defer func() { + e := out.Close() + this.PanicError(e) + }() // Get the data resp, err := http.Get(url) if err != nil { return 0, err } - defer resp.Body.Close() + defer func() { + e := resp.Body.Close() + this.PanicError(e) + }() // Write the body to file size, err := io.Copy(out, resp.Body) @@ -205,7 +224,7 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid } //获取文件应该存放在的物理路径的绝对路径和相对路径。 - absolutePath, relativePath := GetUserFilePath(user.Username, false) + absolutePath, relativePath := GetUserFileDir(user.Username, false) absolutePath = absolutePath + "/" + filename relativePath = relativePath + "/" + filename @@ -415,10 +434,13 @@ func (this *MatterService) rangesMIMESize(ranges []httpRange, contentType string var w countingWriter mw := multipart.NewWriter(&w) for _, ra := range ranges { - mw.CreatePart(ra.mimeHeader(contentType, contentSize)) + _, e := mw.CreatePart(ra.mimeHeader(contentType, contentSize)) + this.PanicError(e) + encSize += ra.length } - mw.Close() + e := mw.Close() + this.PanicError(e) encSize += int64(w) return } @@ -441,7 +463,10 @@ func (this *MatterService) DownloadFile( diskFile, err := os.Open(filePath) this.PanicError(err) - defer diskFile.Close() + defer func() { + e := diskFile.Close() + this.PanicError(e) + }() //如果是图片或者文本或者视频就直接打开。其余的一律以下载形式返回。 if withContentDisposition { diff --git a/rest/util_network.go b/rest/util_network.go index 4bb9e3c..d0ef0f2 100644 --- a/rest/util_network.go +++ b/rest/util_network.go @@ -30,4 +30,37 @@ func GetHostFromRequest(r *http.Request) string { return r.Host -} \ No newline at end of file +} + +//根据一个请求,获取authenticationId +func GetSessionUuidFromRequest(request *http.Request) string { + + //验证用户是否已经登录。 + sessionCookie, err := request.Cookie(COOKIE_AUTH_KEY) + var sessionId string + if err != nil { + //从入参中捞取 + sessionId = request.FormValue(COOKIE_AUTH_KEY) + } else { + sessionId = sessionCookie.Value + } + + return sessionId + +} + +//允许跨域请求 +func AllowCORS(writer http.ResponseWriter) { + writer.Header().Add("Access-Control-Allow-Origin", "*") + writer.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE") + writer.Header().Add("Access-Control-Max-Age", "3600") + writer.Header().Add("Access-Control-Allow-Headers", "content-type") +} + +//禁用缓存 +func DisableCache(writer http.ResponseWriter) { + //对于IE浏览器,会自动缓存,因此设置不缓存Header. + writer.Header().Set("Pragma", "No-cache") + writer.Header().Set("Cache-Control", "no-cache") + writer.Header().Set("Expires", "0") +} diff --git a/rest/util_path.go b/rest/util_path.go index 7beddf2..a6d2648 100644 --- a/rest/util_path.go +++ b/rest/util_path.go @@ -151,21 +151,28 @@ func GetLogPath() string { } //获取某个用户文件应该存放的位置。这个是相对GetFilePath的路径 -//例如:/zicla/2006-01-02/1510122428000 -func GetUserFilePath(username string, cache bool) (string, string) { +//例如:/zicla/root +func GetUserFileDir(username string, cache bool) (absolutePath string, relativePath string) { - now := time.Now() - datePath := now.Format("2006-01-02") - //毫秒时间戳 - timestamp := now.UnixNano() / 1e6 - - //如果是缓存文件夹,那么统一放在cache这个文件夹下面 - if cache { - datePath = fmt.Sprintf("cache/%s", datePath) - } filePath := CONFIG.MatterPath - absolutePath := fmt.Sprintf("%s/%s/%s/%d", filePath, username, datePath, timestamp) - relativePath := fmt.Sprintf("/%s/%s/%d", username, datePath, timestamp) + + if cache { + //如果是缓存文件夹,那么统一放在cache这个文件夹下面 + firstDir := "cache" + + now := time.Now() + datePath := now.Format("2006-01-02") + //毫秒时间戳 + timestamp := now.UnixNano() / 1e6 + + absolutePath = fmt.Sprintf("%s/%s/%s/%s/%d", filePath, username, firstDir, datePath, timestamp) + relativePath = fmt.Sprintf("/%s/%s/%s/%d", username, firstDir, datePath, timestamp) + + } else { + firstDir := "root" + absolutePath = fmt.Sprintf("%s/%s/%s", filePath, username, firstDir) + relativePath = fmt.Sprintf("/%s/%s", username, firstDir) + } exists, err := PathExists(absolutePath) if err != nil { diff --git a/rest/web_result.go b/rest/web_result.go index 33e916a..da92487 100644 --- a/rest/web_result.go +++ b/rest/web_result.go @@ -32,6 +32,7 @@ var ( CODE_WRAPPER_NOT_FOUND = &CodeWrapper{Code: "NOT_FOUND", HttpStatus: http.StatusNotFound, Description: "内容不存在"} CODE_WRAPPER_RANGE_NOT_SATISFIABLE = &CodeWrapper{Code: "RANGE_NOT_SATISFIABLE", HttpStatus: http.StatusRequestedRangeNotSatisfiable, Description: "文件范围读取错误"} CODE_WRAPPER_NOT_INSTALLED = &CodeWrapper{Code: "NOT_INSTALLED", HttpStatus: http.StatusInternalServerError, Description: "系统尚未安装"} + CODE_WRAPPER_SERVER = &CodeWrapper{Code: "SERVER", HttpStatus: http.StatusInternalServerError, Description: "服务器出错"} CODE_WRAPPER_UNKNOWN = &CodeWrapper{Code: "UNKNOWN", HttpStatus: http.StatusInternalServerError, Description: "服务器未知错误"} ) @@ -61,6 +62,10 @@ func FetchHttpStatus(code string) int { return CODE_WRAPPER_NOT_FOUND.HttpStatus } else if code == CODE_WRAPPER_RANGE_NOT_SATISFIABLE.Code { return CODE_WRAPPER_RANGE_NOT_SATISFIABLE.HttpStatus + } else if code == CODE_WRAPPER_NOT_INSTALLED.Code { + return CODE_WRAPPER_NOT_INSTALLED.HttpStatus + } else if code == CODE_WRAPPER_SERVER.Code { + return CODE_WRAPPER_SERVER.HttpStatus } else { return CODE_WRAPPER_UNKNOWN.HttpStatus } @@ -83,3 +88,11 @@ func CustomWebResult(codeWrapper *CodeWrapper, description string) *WebResult { } return wr } + +//所有的数据库错误情况 +var ( + DB_ERROR_DUPLICATE_KEY = "Error 1062: Duplicate entry" + DB_ERROR_NOT_FOUND = "record not found" + DB_TOO_MANY_CONNECTIONS = "Error 1040: Too many connections" + DB_BAD_CONNECTION = "driver: bad connection" +)