diff --git a/rest/dav/webdav.go b/rest/dav/webdav.go index 58d8450..a52f187 100644 --- a/rest/dav/webdav.go +++ b/rest/dav/webdav.go @@ -693,7 +693,7 @@ var ( errInvalidIfHeader = errors.New("webdav: invalid If header") errInvalidLockInfo = errors.New("webdav: invalid lock info") errInvalidLockToken = errors.New("webdav: invalid lock token") - errInvalidPropfind = errors.New("webdav: invalid propfind") + errInvalidPropfind = errors.New("webdav: invalid Propfind") errInvalidProppatch = errors.New("webdav: invalid proppatch") errInvalidResponse = errors.New("webdav: invalid response") errInvalidTimeout = errors.New("webdav: invalid timeout") diff --git a/rest/dav/xml.go b/rest/dav/xml.go index 06aac0e..11f7b0f 100644 --- a/rest/dav/xml.go +++ b/rest/dav/xml.go @@ -32,7 +32,7 @@ import ( // In the long term, this package should use the standard library's version // only, and the internal fork deleted, once // https://github.com/golang/go/issues/13400 is resolved. - ixml "tank/rest/dav/internal/xml" + ixml "tank/rest/dav/xml" ) // http://www.webdav.org/specs/rfc4918.html#ELEMENT_lockinfo @@ -134,13 +134,13 @@ func next(d *ixml.Decoder) (ixml.Token, error) { } // http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind) -type propfindProps []xml.Name +type PropfindProps []xml.Name // UnmarshalXML appends the property names enclosed within start to pn. // // It returns an error if start does not contain any properties or if // properties contain values. Character data between properties is ignored. -func (pn *propfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error { +func (pn *PropfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error { for { t, err := next(d) if err != nil { @@ -167,39 +167,39 @@ 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"` +type Propfind struct { + XMLName ixml.Name `xml:"DAV: Propfind"` Allprop *struct{} `xml:"DAV: allprop"` Propname *struct{} `xml:"DAV: propname"` - Prop propfindProps `xml:"DAV: prop"` - Include propfindProps `xml:"DAV: include"` + Prop PropfindProps `xml:"DAV: prop"` + Include PropfindProps `xml:"DAV: include"` } -func readPropfind(r io.Reader) (pf propfind, status int, err error) { +func readPropfind(r io.Reader) (pf Propfind, status int, err error) { c := countingReader{r: r} if err = ixml.NewDecoder(&c).Decode(&pf); 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{})}, 0, nil } err = errInvalidPropfind } - return propfind{}, http.StatusBadRequest, err + return Propfind{}, http.StatusBadRequest, err } if pf.Allprop == nil && pf.Include != nil { - return propfind{}, http.StatusBadRequest, errInvalidPropfind + return Propfind{}, http.StatusBadRequest, errInvalidPropfind } if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) { - return propfind{}, http.StatusBadRequest, errInvalidPropfind + return Propfind{}, http.StatusBadRequest, errInvalidPropfind } if pf.Prop != nil && pf.Propname != nil { - return propfind{}, http.StatusBadRequest, errInvalidPropfind + return Propfind{}, http.StatusBadRequest, errInvalidPropfind } if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil { - return propfind{}, http.StatusBadRequest, errInvalidPropfind + return Propfind{}, http.StatusBadRequest, errInvalidPropfind } return pf, 0, nil } diff --git a/rest/dav/internal/xml/marshal.go b/rest/dav/xml/marshal.go similarity index 100% rename from rest/dav/internal/xml/marshal.go rename to rest/dav/xml/marshal.go diff --git a/rest/dav/internal/xml/read.go b/rest/dav/xml/read.go similarity index 100% rename from rest/dav/internal/xml/read.go rename to rest/dav/xml/read.go diff --git a/rest/dav/internal/xml/typeinfo.go b/rest/dav/xml/typeinfo.go similarity index 100% rename from rest/dav/internal/xml/typeinfo.go rename to rest/dav/xml/typeinfo.go diff --git a/rest/dav/internal/xml/xml.go b/rest/dav/xml/xml.go similarity index 100% rename from rest/dav/internal/xml/xml.go rename to rest/dav/xml/xml.go diff --git a/rest/dav_controller.go b/rest/dav_controller.go index fefcc17..455ae47 100644 --- a/rest/dav_controller.go +++ b/rest/dav_controller.go @@ -77,7 +77,7 @@ func (this *DavController) HandleRoutes(writer http.ResponseWriter, request *htt path := request.URL.Path - //匹配 /api/webdav{subPath} + //匹配 /api/dav{subPath} reg := regexp.MustCompile(`^/api/dav(.*)$`) strs := reg.FindStringSubmatch(path) if len(strs) == 2 { @@ -90,16 +90,25 @@ func (this *DavController) HandleRoutes(writer http.ResponseWriter, request *htt return nil, false } + //完成系统安装 func (this *DavController) Index(writer http.ResponseWriter, request *http.Request, subPath string) { this.logger.Info("请求访问来了:%s %s", request.RequestURI, subPath) - handler := &dav.Handler{ - FileSystem: dav.Dir("/Users/fusu/d/group/golang/src/tank/tmp/dav"), - LockSystem: dav.NewMemLS(), - } + if request.Method == "PROPFIND1" { + + this.davService.HandlePropfind(writer, request) + + } else { - handler.ServeHTTP(writer, request) + handler := &dav.Handler{ + FileSystem: dav.Dir("/Users/fusu/d/group/golang/src/tank/tmp/dav"), + LockSystem: dav.NewMemLS(), + } + + handler.ServeHTTP(writer, request) + + } } diff --git a/rest/dav_service.go b/rest/dav_service.go index 7170220..8944e0b 100644 --- a/rest/dav_service.go +++ b/rest/dav_service.go @@ -1,13 +1,15 @@ package rest +import ( + "net/http" +) //@Service type DavService struct { Bean - matterDao *MatterDao + matterDao *MatterDao } - //初始化方法 func (this *DavService) Init() { this.Bean.Init() @@ -17,6 +19,102 @@ func (this *DavService) Init() { if b, ok := b.(*MatterDao); ok { this.matterDao = b } +} + +const ( + infiniteDepth = -1 + invalidDepth = -2 +) + +// parseDepth maps the strings "0", "1" and "infinity" to 0, 1 and +// infiniteDepth. Parsing any other string returns invalidDepth. +// +// Different WebDAV methods have further constraints on valid depths: +// - PROPFIND has no further restrictions, as per section 9.1. +// - COPY accepts only "0" or "infinity", as per section 9.8.3. +// - MOVE accepts only "infinity", as per section 9.9.2. +// - LOCK accepts only "0" or "infinity", as per section 9.10.3. +// These constraints are enforced by the handleXxx methods. +func parseDepth(s string) int { + switch s { + case "0": + return 0 + case "1": + return 1 + case "infinity": + return infiniteDepth + } + return invalidDepth +} + + +//处理 方法 +func (this *DavService) HandlePropfind(w http.ResponseWriter, r *http.Request) { + //basePath := "/Users/fusu/d/group/golang/src/tank/tmp/dav" + // + //reqPath := r.URL.Path + // + //ctx := r.Context() + // + //fi, err := os.Stat(basePath + reqPath) + //if err != nil { + // this.PanicError(err) + //} + // + //depth := infiniteDepth + //if hdr := r.Header.Get("Depth"); hdr != "" { + // depth = parseDepth(hdr) + // if depth == invalidDepth { + // this.PanicBadRequest("Depth指定错误!") + // } + //} + // + //pf, status, err := readPropfind(r.Body) + //if err != nil { + // return status, err + //} + // + //mw := multistatusWriter{w: w} + // + //walkFn := func(reqPath string, info os.FileInfo, err error) error { + // if err != nil { + // return err + // } + // var pstats []Propstat + // if pf.Propname != nil { + // pnames, err := propnames(ctx, h.FileSystem, h.LockSystem, reqPath) + // if err != nil { + // return err + // } + // pstat := Propstat{Status: http.StatusOK} + // for _, xmlname := range pnames { + // pstat.Props = append(pstat.Props, Property{XMLName: xmlname}) + // } + // pstats = append(pstats, pstat) + // } else if pf.Allprop != nil { + // pstats, err = allprop(ctx, h.FileSystem, h.LockSystem, reqPath, pf.Prop) + // } else { + // pstats, err = props(ctx, h.FileSystem, h.LockSystem, reqPath, pf.Prop) + // } + // if err != nil { + // return err + // } + // href := path.Join(h.Prefix, reqPath) + // if info.IsDir() { + // href += "/" + // } + // return mw.write(makePropstatResponse(href, pstats)) + //} + // + //walkErr := walkFS(ctx, h.FileSystem, depth, reqPath, fi, walkFn) + //closeErr := mw.close() + //if walkErr != nil { + // return http.StatusInternalServerError, walkErr + //} + //if closeErr != nil { + // return http.StatusInternalServerError, closeErr + //} + //return 0, nil }