Add the dav_test.

This commit is contained in:
zicla 2019-04-25 21:02:51 +08:00
parent dc3e570067
commit 955e7a01db
4 changed files with 78 additions and 44 deletions

View File

@ -6,12 +6,12 @@ package dav
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"
"tank/rest/dav/xml"
"tank/rest/result"
)
// Proppatch describes a property update instruction as defined in RFC 4918.
@ -100,26 +100,6 @@ func EscapeXML(s string) string {
// ContentTyper is an optional interface for the os.FileInfo
// objects returned by the FileSystem.
//
// If this interface is defined then it will be used to read the
// content type from the object.
//
// If this interface is not defined the file will be opened and the
// content type will be guessed from the initial contents of the file.
type ContentTyper interface {
// ContentType returns the content type for the file.
//
// If this returns error ErrNotImplemented then the error will
// be ignored and the base implementation will be used
// instead.
ContentType(ctx context.Context) (string, error)
}
// http://www.webdav.org/specs/rfc4918.html#status.code.extensions.to.http11
const (
StatusMulti = 207
@ -245,33 +225,37 @@ type Propfind struct {
}
//从request中读出需要的属性。比如getcontentlength 大小 creationdate 创建时间
func ReadPropfind(reader io.Reader) (propfind Propfind, status int, err error) {
func ReadPropfind(reader io.Reader) (propfind *Propfind) {
propfind = &Propfind{}
c := CountingReader{reader: reader}
if err = xml.NewDecoder(&c).Decode(&propfind); err != nil {
if err := xml.NewDecoder(&c).Decode(&propfind); err != nil {
if err == io.EOF {
if c.n == 0 {
// An empty body means to propfind allprop.
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
return Propfind{Allprop: new(struct{})}, 0, nil
return &Propfind{Allprop: new(struct{})}
}
err = errInvalidPropfind
}
return Propfind{}, http.StatusBadRequest, err
panic(result.BadRequest(err.Error()))
}
if propfind.Allprop == nil && propfind.Include != nil {
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
panic(result.BadRequest(errInvalidPropfind.Error()))
}
if propfind.Allprop != nil && (propfind.Prop != nil || propfind.Propname != nil) {
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
panic(result.BadRequest(errInvalidPropfind.Error()))
}
if propfind.Prop != nil && propfind.Propname != nil {
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
panic(result.BadRequest(errInvalidPropfind.Error()))
}
if propfind.Propname == nil && propfind.Allprop == nil && propfind.Prop == nil {
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
panic(result.BadRequest(errInvalidPropfind.Error()))
}
return propfind, 0, nil
return propfind
}
// Property represents a single DAV resource property as defined in RFC 4918.
@ -395,16 +379,16 @@ type MultiStatusWriter struct {
// first, valid response to be written, Write prepends the XML representation
// of r with a multistatus tag. Callers must call close after the last response
// has been written.
func (this *MultiStatusWriter) Write(r *Response) error {
switch len(r.Href) {
func (this *MultiStatusWriter) Write(response *Response) error {
switch len(response.Href) {
case 0:
return errInvalidResponse
case 1:
if len(r.Propstat) > 0 != (r.Status == "") {
if len(response.Propstat) > 0 != (response.Status == "") {
return errInvalidResponse
}
default:
if len(r.Propstat) > 0 || r.Status == "" {
if len(response.Propstat) > 0 || response.Status == "" {
return errInvalidResponse
}
}
@ -412,7 +396,7 @@ func (this *MultiStatusWriter) Write(r *Response) error {
if err != nil {
return err
}
return this.Encoder.Encode(r)
return this.Encoder.Encode(response)
}
// writeHeader writes a XML multistatus start element on w's underlying

View File

@ -11,11 +11,13 @@ import (
"tank/rest/dav/xml"
)
/**
*
* WebDav协议文档
* https://tools.ietf.org/html/rfc4918
* 主要参考 golang.org/x/net/webdav
* 测试机http://www.webdav.org/neon/litmus/
*/
//@Service
type DavService struct {
@ -129,7 +131,7 @@ func (this *DavService) AllPropXmlNames(matter *Matter) []xml.Name {
}
//从一个matter中获取其 []dav.Propstat
func (this *DavService) Propstats(user *User, matter *Matter, propfind dav.Propfind) []dav.Propstat {
func (this *DavService) Propstats(user *User, matter *Matter, propfind *dav.Propfind) []dav.Propstat {
propstats := make([]dav.Propstat, 0)
if propfind.Propname != nil {
@ -158,8 +160,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
depth := this.ParseDepth(request)
//读取请求参数。按照用户的参数请求返回内容。
propfind, _, err := dav.ReadPropfind(request.Body)
this.PanicError(err)
propfind := dav.ReadPropfind(request.Body)
//寻找符合条件的matter.
//如果是空或者/就是请求根目录
@ -177,7 +178,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
}
//准备一个输出结果的Writer
multiStatusWriter := dav.MultiStatusWriter{Writer: writer}
multiStatusWriter := &dav.MultiStatusWriter{Writer: writer}
for _, matter := range matters {
@ -187,12 +188,12 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
path := fmt.Sprintf("%s%s", WEBDAV_PREFFIX, matter.Path)
response := this.makePropstatResponse(path, propstats)
err = multiStatusWriter.Write(response)
err := multiStatusWriter.Write(response)
this.PanicError(err)
}
//闭合
err = multiStatusWriter.Close()
err := multiStatusWriter.Close()
this.PanicError(err)
fmt.Printf("%v %v \n", subPath, propfind.Prop)

View File

@ -122,7 +122,8 @@ func (this *Logger) openFile() {
panic("日志文件无法正常打开: " + err.Error())
}
this.goLogger = log.New(f, "", log.Ltime)
this.goLogger = log.New(f, "", log.LstdFlags|log.Lshortfile)
this.file = f
}

View File

@ -8,7 +8,7 @@ import (
"time"
)
func TestReadPropfind(t *testing.T) {
func TestXmlDecoder(t *testing.T) {
propfind := &dav.Propfind{}
@ -46,7 +46,55 @@ func TestReadPropfind(t *testing.T) {
for k, v := range resultMap {
if !v {
t.Errorf("index = %s error", k)
t.Errorf(" %s error", k)
}
}
t.Logf("[%v] pass!", time.Now())
}
func TestXmlEncoder(t *testing.T) {
writer := &bytes.Buffer{}
response := &dav.Response{
XMLName: xml.Name{Space: "DAV:", Local: "response"},
Href: []string{"/api/dav"},
Propstat: []dav.SubPropstat{
{
Prop: []dav.Property{
{
XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"},
InnerXML: []byte(`<D:collection xmlns:D="DAV:"/>`),
},
{
XMLName: xml.Name{Space: "DAV:", Local: "getlastmodified"},
InnerXML: []byte(`Mon, 22 Apr 2019 06:38:36 GMT`),
},
},
Status: "HTTP/1.1 200 OK",
},
},
}
err := xml.NewEncoder(writer).Encode(response)
if err != nil {
t.Error(err.Error())
}
bs := writer.Bytes()
str := string(bs)
resultMap := make(map[string]bool)
resultMap["equal"] = str == `<D:response><D:href>/api/dav</D:href><D:propstat><D:prop><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:getlastmodified>Mon, 22 Apr 2019 06:38:36 GMT</D:getlastmodified></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>`
for k, v := range resultMap {
if !v {
t.Errorf("%s error", k)
}
}