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
|
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
|
||||||
|
// <!ELEMENT propfind ( propname | (allprop, include?) | prop ) >
|
||||||
type Propfind struct {
|
type Propfind struct {
|
||||||
XMLName ixml.Name `xml:"DAV: propfind"`
|
XMLName ixml.Name `xml:"DAV: propfind"`
|
||||||
Allprop *struct{} `xml:"DAV: allprop"`
|
Allprop *struct{} `xml:"DAV: allprop"`
|
||||||
@ -177,9 +178,9 @@ type Propfind struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//从request中读出需要的属性。比如:getcontentlength 大小 creationdate 创建时间
|
//从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}
|
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 err == io.EOF {
|
||||||
if c.n == 0 {
|
if c.n == 0 {
|
||||||
// An empty body means to propfind allprop.
|
// 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
|
return Propfind{}, http.StatusBadRequest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pf.Allprop == nil && pf.Include != nil {
|
if propfind.Allprop == nil && propfind.Include != nil {
|
||||||
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
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
|
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
if pf.Prop != nil && pf.Propname != nil {
|
if propfind.Prop != nil && propfind.Propname != nil {
|
||||||
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
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 Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
return pf, 0, nil
|
return propfind, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Property represents a single DAV resource property as defined in RFC 4918.
|
// 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
|
//从一个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)
|
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
|
var properties []dav.Property
|
||||||
|
|
||||||
for _, prop := range propfind.Prop {
|
for _, xmlName := range xmlNames {
|
||||||
//TODO: deadprops尚未考虑
|
//TODO: deadprops尚未考虑
|
||||||
|
|
||||||
// Otherwise, it must either be a live property or we don't know it.
|
// 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)
|
innerXML := liveProp.findFn(matter)
|
||||||
|
|
||||||
properties = append(properties, dav.Property{
|
properties = append(properties, dav.Property{
|
||||||
XMLName: prop,
|
XMLName: xmlName,
|
||||||
InnerXML: []byte(innerXML),
|
InnerXML: []byte(innerXML),
|
||||||
})
|
})
|
||||||
} else {
|
} 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}
|
okPropstat := dav.Propstat{Status: http.StatusOK, Props: properties}
|
||||||
|
|
||||||
propstats = append(propstats, okPropstat)
|
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
|
return propstats
|
||||||
@ -108,19 +135,28 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
|||||||
//获取请求者
|
//获取请求者
|
||||||
user := this.checkUser(writer, request)
|
user := this.checkUser(writer, request)
|
||||||
|
|
||||||
//找寻请求的目录
|
|
||||||
matter := this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath)
|
|
||||||
|
|
||||||
//读取请求参数。按照用户的参数请求返回内容。
|
//读取请求参数。按照用户的参数请求返回内容。
|
||||||
propfind, _, err := dav.ReadPropfind(request.Body)
|
propfind, _, err := dav.ReadPropfind(request.Body)
|
||||||
this.PanicError(err)
|
this.PanicError(err)
|
||||||
|
|
||||||
//寻找符合条件的matter.
|
//寻找符合条件的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 {
|
if len(matters) == 0 {
|
||||||
this.PanicNotFound("%s不存在", subPath)
|
this.PanicNotFound("%s不存在", subPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//将当前的matter添加到头部
|
||||||
|
matters = append([]*Matter{matter}, matters...)
|
||||||
|
|
||||||
//准备一个输出结果的Writer
|
//准备一个输出结果的Writer
|
||||||
multiStatusWriter := dav.MultiStatusWriter{Writer: writer}
|
multiStatusWriter := dav.MultiStatusWriter{Writer: writer}
|
||||||
|
|
||||||
@ -140,6 +176,6 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
|||||||
err = multiStatusWriter.Close()
|
err = multiStatusWriter.Close()
|
||||||
this.PanicError(err)
|
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
|
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 {
|
func (this *MatterDao) List(puuid string, userUuid string, sortArray []OrderPair) []*Matter {
|
||||||
var matters []*Matter
|
var matters []*Matter
|
||||||
|
@ -29,13 +29,11 @@ func (Matter) TableName() string {
|
|||||||
return TABLE_PREFIX + "matter"
|
return TABLE_PREFIX + "matter"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 获取该Matter的绝对路径。path代表的是相对路径。
|
// 获取该Matter的绝对路径。path代表的是相对路径。
|
||||||
func (this *Matter) AbsolutePath() string {
|
func (this *Matter) AbsolutePath() string {
|
||||||
return GetUserFileRootDir(this.Username) + this.Path
|
return GetUserFileRootDir(this.Username) + this.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 获取该Matter的MimeType
|
// 获取该Matter的MimeType
|
||||||
func (this *Matter) MimeType() string {
|
func (this *Matter) MimeType() string {
|
||||||
return GetMimeType(GetExtension(this.Name))
|
return GetMimeType(GetExtension(this.Name))
|
||||||
@ -50,6 +48,8 @@ func NewRootMatter(user *User) *Matter {
|
|||||||
matter.Username = user.Username
|
matter.Username = user.Username
|
||||||
matter.Dir = true
|
matter.Dir = true
|
||||||
matter.Path = ""
|
matter.Path = ""
|
||||||
|
matter.CreateTime = user.CreateTime
|
||||||
|
matter.UpdateTime = user.UpdateTime
|
||||||
|
|
||||||
return matter
|
return matter
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user