diff --git a/rest/dav/xml.go b/rest/dav/xml.go index 375dab0..9281ff6 100644 --- a/rest/dav/xml.go +++ b/rest/dav/xml.go @@ -168,6 +168,7 @@ func (pn *PropfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) } // http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind +// type Propfind struct { XMLName ixml.Name `xml:"DAV: propfind"` Allprop *struct{} `xml:"DAV: allprop"` @@ -177,9 +178,9 @@ type Propfind struct { } //从request中读出需要的属性。比如:getcontentlength 大小 creationdate 创建时间 -func ReadPropfind(r io.Reader) (pf Propfind, status int, err error) { +func ReadPropfind(r io.Reader) (propfind Propfind, status int, err error) { c := CountingReader{r: r} - if err = ixml.NewDecoder(&c).Decode(&pf); err != nil { + if err = ixml.NewDecoder(&c).Decode(&propfind); err != nil { if err == io.EOF { if c.n == 0 { // An empty body means to propfind allprop. @@ -191,19 +192,19 @@ func ReadPropfind(r io.Reader) (pf Propfind, status int, err error) { return Propfind{}, http.StatusBadRequest, err } - if pf.Allprop == nil && pf.Include != nil { + if propfind.Allprop == nil && propfind.Include != nil { return Propfind{}, http.StatusBadRequest, errInvalidPropfind } - if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) { + if propfind.Allprop != nil && (propfind.Prop != nil || propfind.Propname != nil) { return Propfind{}, http.StatusBadRequest, errInvalidPropfind } - if pf.Prop != nil && pf.Propname != nil { + if propfind.Prop != nil && propfind.Propname != nil { return Propfind{}, http.StatusBadRequest, errInvalidPropfind } - if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil { + if propfind.Propname == nil && propfind.Allprop == nil && propfind.Prop == nil { return Propfind{}, http.StatusBadRequest, errInvalidPropfind } - return pf, 0, nil + return propfind, 0, nil } // Property represents a single DAV resource property as defined in RFC 4918. diff --git a/rest/dav_service.go b/rest/dav_service.go index 7f2cc86..c9dee92 100644 --- a/rest/dav_service.go +++ b/rest/dav_service.go @@ -58,6 +58,53 @@ func (this *DavService) PropNames(matter *Matter) []xml.Name { } +//从一个matter中获取其 []dav.Propstat +func (this *DavService) PropstatsFromXmlNames(matter *Matter, xmlNames []xml.Name) []dav.Propstat { + + propstats := make([]dav.Propstat, 0) + + var properties []dav.Property + + for _, xmlName := range xmlNames { + //TODO: deadprops尚未考虑 + + // Otherwise, it must either be a live property or we don't know it. + if liveProp := LivePropMap[xmlName]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) { + innerXML := liveProp.findFn(matter) + + properties = append(properties, dav.Property{ + XMLName: xmlName, + InnerXML: []byte(innerXML), + }) + } else { + this.logger.Info("%s的%s无法完成", matter.Path, xmlName.Local) + } + } + + if len(properties) == 0 { + this.PanicBadRequest("请求的属性项无法解析!") + } + + okPropstat := dav.Propstat{Status: http.StatusOK, Props: properties} + + propstats = append(propstats, okPropstat) + + return propstats + +} + +//从一个matter中获取所有的propsNames +func (this *DavService) AllPropXmlNames(matter *Matter) []xml.Name { + + pnames := make([]xml.Name, 0) + for pn, prop := range LivePropMap { + if prop.findFn != nil && (prop.dir || !matter.Dir) { + pnames = append(pnames, pn) + } + } + + return pnames +} //从一个matter中获取其 []dav.Propstat func (this *DavService) Propstats(matter *Matter, propfind dav.Propfind) []dav.Propstat { @@ -66,34 +113,14 @@ func (this *DavService) Propstats(matter *Matter, propfind dav.Propfind) []dav.P if propfind.Propname != nil { this.PanicBadRequest("propfind.Propname != nil 尚未处理") } else if propfind.Allprop != nil { - this.PanicBadRequest("propfind.Allprop != nil 尚未处理") + + //TODO: 如果include中还有内容,那么包含进去。 + xmlNames := this.AllPropXmlNames(matter) + + propstats = this.PropstatsFromXmlNames(matter, xmlNames) + } else { - - var properties []dav.Property - - for _, prop := range propfind.Prop { - //TODO: deadprops尚未考虑 - - // Otherwise, it must either be a live property or we don't know it. - if liveProp := LivePropMap[prop]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) { - innerXML := liveProp.findFn(matter) - - properties = append(properties, dav.Property{ - XMLName: prop, - InnerXML: []byte(innerXML), - }) - } else { - //TODO: 某一项请求的prop没有对应的结果 - } - } - - if len(properties) == 0 { - this.PanicBadRequest("请求的属性项无法解析!") - } - - okPropstat := dav.Propstat{Status: http.StatusOK, Props: properties} - - propstats = append(propstats, okPropstat) + propstats = this.PropstatsFromXmlNames(matter, propfind.Prop) } return propstats @@ -108,19 +135,28 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http //获取请求者 user := this.checkUser(writer, request) - //找寻请求的目录 - matter := this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - //读取请求参数。按照用户的参数请求返回内容。 propfind, _, err := dav.ReadPropfind(request.Body) this.PanicError(err) //寻找符合条件的matter. - matters := this.matterDao.ListByUserUuidAndPath(user.Uuid, subPath) + var matter *Matter + //如果是空或者/就是请求根目录 + if subPath == "" || subPath == "/" { + matter = NewRootMatter(user) + } else { + matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) + } + + matters := this.matterDao.List(matter.Uuid, user.Uuid, nil) + if len(matters) == 0 { this.PanicNotFound("%s不存在", subPath) } + //将当前的matter添加到头部 + matters = append([]*Matter{matter}, matters...) + //准备一个输出结果的Writer multiStatusWriter := dav.MultiStatusWriter{Writer: writer} @@ -140,6 +176,6 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http err = multiStatusWriter.Close() this.PanicError(err) - fmt.Printf("%v %v \n", matter.Name, propfind.Prop) + fmt.Printf("%v %v \n", subPath, propfind.Prop) } diff --git a/rest/matter_dao.go b/rest/matter_dao.go index 72ec197..b813275 100644 --- a/rest/matter_dao.go +++ b/rest/matter_dao.go @@ -132,31 +132,6 @@ func (this *MatterDao) ListByUserUuidAndPuuidAndDirAndName(userUuid string, puui return matters } -//获取某个用户的某个文件夹下的某个名字的文件(或文件夹)列表 -func (this *MatterDao) ListByUserUuidAndPath(userUuid string, path string) []*Matter { - - var wp = &WherePair{} - - if userUuid == "" { - this.PanicBadRequest("userUuid必填!") - } - - if path == "" { - this.PanicBadRequest("path必填!") - } - - wp = wp.And(&WherePair{Query: "user_uuid = ?", Args: []interface{}{userUuid}}) - - wp = wp.And(&WherePair{Query: "path = ?", Args: []interface{}{path}}) - - var matters []*Matter - db := CONTEXT.DB.Model(&Matter{}).Where(wp.Query, wp.Args...).Find(&matters) - - this.PanicError(db.Error) - - return matters -} - //获取某个文件夹下所有的文件和子文件 func (this *MatterDao) List(puuid string, userUuid string, sortArray []OrderPair) []*Matter { var matters []*Matter diff --git a/rest/matter_model.go b/rest/matter_model.go index 3948039..bc858bf 100644 --- a/rest/matter_model.go +++ b/rest/matter_model.go @@ -29,13 +29,11 @@ func (Matter) TableName() string { return TABLE_PREFIX + "matter" } - // 获取该Matter的绝对路径。path代表的是相对路径。 func (this *Matter) AbsolutePath() string { return GetUserFileRootDir(this.Username) + this.Path } - // 获取该Matter的MimeType func (this *Matter) MimeType() string { return GetMimeType(GetExtension(this.Name)) @@ -50,6 +48,8 @@ func NewRootMatter(user *User) *Matter { matter.Username = user.Username matter.Dir = true matter.Path = "" + matter.CreateTime = user.CreateTime + matter.UpdateTime = user.UpdateTime return matter }