Implement the propfind method in tank.
This commit is contained in:
parent
50c025bd09
commit
74ee6c1bba
@ -168,6 +168,7 @@ func (pn *PropfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement)
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
|
||||
// <!ELEMENT propfind ( propname | (allprop, include?) | prop ) >
|
||||
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.
|
||||
|
@ -58,32 +58,26 @@ func (this *DavService) PropNames(matter *Matter) []xml.Name {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//从一个matter中获取其 []dav.Propstat
|
||||
func (this *DavService) Propstats(matter *Matter, propfind dav.Propfind) []dav.Propstat {
|
||||
func (this *DavService) PropstatsFromXmlNames(matter *Matter, xmlNames []xml.Name) []dav.Propstat {
|
||||
|
||||
propstats := make([]dav.Propstat, 0)
|
||||
if propfind.Propname != nil {
|
||||
this.PanicBadRequest("propfind.Propname != nil 尚未处理")
|
||||
} else if propfind.Allprop != nil {
|
||||
this.PanicBadRequest("propfind.Allprop != nil 尚未处理")
|
||||
} else {
|
||||
|
||||
var properties []dav.Property
|
||||
|
||||
for _, prop := range propfind.Prop {
|
||||
for _, xmlName := range xmlNames {
|
||||
//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) {
|
||||
if liveProp := LivePropMap[xmlName]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) {
|
||||
innerXML := liveProp.findFn(matter)
|
||||
|
||||
properties = append(properties, dav.Property{
|
||||
XMLName: prop,
|
||||
XMLName: xmlName,
|
||||
InnerXML: []byte(innerXML),
|
||||
})
|
||||
} else {
|
||||
//TODO: 某一项请求的prop没有对应的结果
|
||||
this.logger.Info("%s的%s无法完成", matter.Path, xmlName.Local)
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,6 +88,39 @@ func (this *DavService) Propstats(matter *Matter, propfind dav.Propfind) []dav.P
|
||||
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 {
|
||||
|
||||
propstats := make([]dav.Propstat, 0)
|
||||
if propfind.Propname != nil {
|
||||
this.PanicBadRequest("propfind.Propname != nil 尚未处理")
|
||||
} else if propfind.Allprop != nil {
|
||||
|
||||
//TODO: 如果include中还有内容,那么包含进去。
|
||||
xmlNames := this.AllPropXmlNames(matter)
|
||||
|
||||
propstats = this.PropstatsFromXmlNames(matter, xmlNames)
|
||||
|
||||
} else {
|
||||
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)
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user