diff --git a/code/rest/dav_controller.go b/code/rest/dav_controller.go index 0d980d7..b302c7f 100644 --- a/code/rest/dav_controller.go +++ b/code/rest/dav_controller.go @@ -18,7 +18,7 @@ import ( * WebDav document * https://tools.ietf.org/html/rfc4918 * http://www.webdav.org/specs/rfc4918.html - * + * test machine: http://www.webdav.org/neon/litmus/ */ type DavController struct { @@ -145,7 +145,7 @@ func (this *DavController) debug(writer http.ResponseWriter, request *http.Reque bodyBytes, err := ioutil.ReadAll(request.Body) if err != nil { - fmt.Println("读取body时出错" + err.Error()) + fmt.Println("occur error when reading body: " + err.Error()) } fmt.Println(string(bodyBytes)) @@ -162,7 +162,8 @@ func (this *DavController) debug(writer http.ResponseWriter, request *http.Reque func (this *DavController) Index(writer http.ResponseWriter, request *http.Request, subPath string) { - //this.debug(writer, request, subPath) + //when debugging. open it. + this.debug(writer, request, subPath) user := this.CheckCurrentUser(writer, request) diff --git a/code/rest/dav_service.go b/code/rest/dav_service.go index 4106e71..eabdfee 100644 --- a/code/rest/dav_service.go +++ b/code/rest/dav_service.go @@ -7,6 +7,7 @@ import ( "github.com/eyebluecn/tank/code/tool/dav/xml" "github.com/eyebluecn/tank/code/tool/result" "github.com/eyebluecn/tank/code/tool/util" + "io/ioutil" "net/http" "net/url" "path" @@ -230,6 +231,9 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ this.matterService.Upload(request, request.Body, user, dirMatter, filename, true) + //set the status code 201 + writer.WriteHeader(http.StatusCreated) + } //delete file @@ -247,10 +251,37 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re fmt.Printf("MKCOL %s\n", subPath) + //the body of MKCOL request MUST be empty. (RFC2518:8.3.1) + bodyBytes, err := ioutil.ReadAll(request.Body) + if err != nil { + fmt.Println("occur error when reading body: " + err.Error()) + } else { + if len(bodyBytes) != 0 { + //throw conflict error + panic(result.CustomWebResult(result.UNSUPPORTED_MEDIA_TYPE, fmt.Sprintf("%s MKCOL should NO body", subPath))) + } + } + thisDirName := util.GetFilenameOfPath(subPath) dirPath := util.GetDirOfPath(subPath) - dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user) + dirMatter := this.matterDao.FindWithRootByPath(dirPath, user) + if dirMatter == nil { + //throw conflict error + panic(result.CustomWebResult(result.CONFLICT, fmt.Sprintf("%s not exist", dirPath))) + } + + //check whether col exists. (RFC2518:8.3.1) + dbMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, true, thisDirName) + if dbMatter != nil { + panic(result.CustomWebResult(result.METHOD_NOT_ALLOWED, fmt.Sprintf("%s already exists", dirPath))) + } + + //check whether file exists. (RFC2518:8.3.1) + fileMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, thisDirName) + if fileMatter != nil { + panic(result.CustomWebResult(result.METHOD_NOT_ALLOWED, fmt.Sprintf("%s file already exists", dirPath))) + } this.matterService.AtomicCreateDirectory(request, dirMatter, thisDirName, user) diff --git a/code/rest/matter_dao.go b/code/rest/matter_dao.go index 23ffbd2..69d91e0 100644 --- a/code/rest/matter_dao.go +++ b/code/rest/matter_dao.go @@ -92,6 +92,24 @@ func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter { return matter } +// find by path. if path=/, then return the Root Matter +func (this *MatterDao) FindWithRootByPath(path string, user *User) *Matter { + + var matter *Matter + + if user == nil { + panic(result.BadRequest("user cannot be null.")) + } + + if path == "" || path == "/" { + matter = NewRootMatter(user) + } else { + matter = this.findByUserUuidAndPath(user.Uuid, path) + } + + return matter +} + func (this *MatterDao) FindByUserUuidAndPuuidAndNameAndDirTrue(userUuid string, puuid string, name string) *Matter { var wp = &builder.WherePair{} @@ -417,6 +435,7 @@ func (this *MatterDao) SizeBetweenTime(startTime time.Time, endTime time.Time) i return size } +//find by userUuid and path. if not found, return nil func (this *MatterDao) findByUserUuidAndPath(userUuid string, path string) *Matter { var wp = &builder.WherePair{Query: "user_uuid = ? AND path = ?", Args: []interface{}{userUuid, path}} @@ -435,6 +454,7 @@ func (this *MatterDao) findByUserUuidAndPath(userUuid string, path string) *Matt return matter } +//find by userUuid and path. if not found, panic func (this *MatterDao) checkByUserUuidAndPath(userUuid string, path string) *Matter { if path == "" { diff --git a/code/tool/result/web_result.go b/code/tool/result/web_result.go index d989862..13ed050 100644 --- a/code/tool/result/web_result.go +++ b/code/tool/result/web_result.go @@ -23,18 +23,21 @@ type CodeWrapper struct { } var ( - OK = &CodeWrapper{Code: "OK", HttpStatus: http.StatusOK, Description: "ok"} - BAD_REQUEST = &CodeWrapper{Code: "BAD_REQUEST", HttpStatus: http.StatusBadRequest, Description: "bad request"} - NEED_SHARE_CODE = &CodeWrapper{Code: "NEED_SHARE_CODE", HttpStatus: http.StatusUnauthorized, Description: "share code required"} - SHARE_CODE_ERROR = &CodeWrapper{Code: "SHARE_CODE_ERROR", HttpStatus: http.StatusUnauthorized, Description: "share code error"} - LOGIN = &CodeWrapper{Code: "LOGIN", HttpStatus: http.StatusUnauthorized, Description: "not login"} - USER_DISABLED = &CodeWrapper{Code: "USER_DISABLED", HttpStatus: http.StatusForbidden, Description: "user disabled"} - UNAUTHORIZED = &CodeWrapper{Code: "UNAUTHORIZED", HttpStatus: http.StatusUnauthorized, Description: "unauthorized"} - NOT_FOUND = &CodeWrapper{Code: "NOT_FOUND", HttpStatus: http.StatusNotFound, Description: "404 not found"} - RANGE_NOT_SATISFIABLE = &CodeWrapper{Code: "RANGE_NOT_SATISFIABLE", HttpStatus: http.StatusRequestedRangeNotSatisfiable, Description: "range not satisfiable"} - NOT_INSTALLED = &CodeWrapper{Code: "NOT_INSTALLED", HttpStatus: http.StatusInternalServerError, Description: "application not installed"} - SERVER = &CodeWrapper{Code: "SERVER", HttpStatus: http.StatusInternalServerError, Description: "server error"} - UNKNOWN = &CodeWrapper{Code: "UNKNOWN", HttpStatus: http.StatusInternalServerError, Description: "server unknow error"} + OK = &CodeWrapper{Code: "OK", HttpStatus: http.StatusOK, Description: "ok"} + BAD_REQUEST = &CodeWrapper{Code: "BAD_REQUEST", HttpStatus: http.StatusBadRequest, Description: "bad request"} + NEED_SHARE_CODE = &CodeWrapper{Code: "NEED_SHARE_CODE", HttpStatus: http.StatusUnauthorized, Description: "share code required"} + SHARE_CODE_ERROR = &CodeWrapper{Code: "SHARE_CODE_ERROR", HttpStatus: http.StatusUnauthorized, Description: "share code error"} + LOGIN = &CodeWrapper{Code: "LOGIN", HttpStatus: http.StatusUnauthorized, Description: "not login"} + USER_DISABLED = &CodeWrapper{Code: "USER_DISABLED", HttpStatus: http.StatusForbidden, Description: "user disabled"} + UNAUTHORIZED = &CodeWrapper{Code: "UNAUTHORIZED", HttpStatus: http.StatusUnauthorized, Description: "unauthorized"} + NOT_FOUND = &CodeWrapper{Code: "NOT_FOUND", HttpStatus: http.StatusNotFound, Description: "404 not found"} + METHOD_NOT_ALLOWED = &CodeWrapper{Code: "METHOD_NOT_ALLOWED", HttpStatus: http.StatusMethodNotAllowed, Description: "405 method not allowed"} + CONFLICT = &CodeWrapper{Code: "CONFLICT", HttpStatus: http.StatusConflict, Description: "409 conflict"} + UNSUPPORTED_MEDIA_TYPE = &CodeWrapper{Code: "UNSUPPORTED_MEDIA_TYPE", HttpStatus: http.StatusUnsupportedMediaType, Description: "415 conflict"} + RANGE_NOT_SATISFIABLE = &CodeWrapper{Code: "RANGE_NOT_SATISFIABLE", HttpStatus: http.StatusRequestedRangeNotSatisfiable, Description: "range not satisfiable"} + NOT_INSTALLED = &CodeWrapper{Code: "NOT_INSTALLED", HttpStatus: http.StatusInternalServerError, Description: "application not installed"} + SERVER = &CodeWrapper{Code: "SERVER", HttpStatus: http.StatusInternalServerError, Description: "server error"} + UNKNOWN = &CodeWrapper{Code: "UNKNOWN", HttpStatus: http.StatusInternalServerError, Description: "server unknow error"} ) func FetchHttpStatus(code string) int { @@ -54,6 +57,12 @@ func FetchHttpStatus(code string) int { return UNAUTHORIZED.HttpStatus } else if code == NOT_FOUND.Code { return NOT_FOUND.HttpStatus + } else if code == METHOD_NOT_ALLOWED.Code { + return METHOD_NOT_ALLOWED.HttpStatus + } else if code == CONFLICT.Code { + return CONFLICT.HttpStatus + } else if code == UNSUPPORTED_MEDIA_TYPE.Code { + return UNSUPPORTED_MEDIA_TYPE.HttpStatus } else if code == RANGE_NOT_SATISFIABLE.Code { return RANGE_NOT_SATISFIABLE.HttpStatus } else if code == NOT_INSTALLED.Code {