From 791a81a11808691775a647d134cd357d9219b6b5 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 14 Oct 2021 11:51:52 +0200 Subject: [PATCH 1/4] Handle propfind requests for existing files --- changelog/unreleased/propfind-files.md | 1 + .../http/services/owncloud/ocdav/propfind.go | 35 +++++++++++++++++-- pkg/app/provider/wopi/wopi.go | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 changelog/unreleased/propfind-files.md diff --git a/changelog/unreleased/propfind-files.md b/changelog/unreleased/propfind-files.md new file mode 100644 index 0000000000..ce154a7fc2 --- /dev/null +++ b/changelog/unreleased/propfind-files.md @@ -0,0 +1 @@ +Enhancement: Handle propfind requests for existing files \ No newline at end of file diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go index c94ae56e46..65521353e2 100644 --- a/internal/http/services/owncloud/ocdav/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind.go @@ -223,7 +223,37 @@ func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *ht parentInfo := res.Info resourceInfos := []*provider.ResourceInfo{parentInfo} - if parentInfo.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER && depth == "1" { + + switch { + case parentInfo.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER: + // The propfind is requested for a file that exists + // In this case, we can stat the parent directory and return both + resourceInfos = append(resourceInfos, parentInfo) + parentRes, err := client.Stat(ctx, &provider.StatRequest{ + Ref: &provider.Reference{Path: path.Dir(parentInfo.Path)}, + ArbitraryMetadataKeys: metadataKeys, + }) + if err != nil { + log.Error().Err(err).Interface("req", req).Msg("error sending a grpc stat request") + w.WriteHeader(http.StatusInternalServerError) + return nil, nil, false + } else if res.Status.Code != rpc.Code_CODE_OK { + if res.Status.Code == rpc.Code_CODE_NOT_FOUND { + w.WriteHeader(http.StatusNotFound) + m := fmt.Sprintf("Resource %v not found", ref.Path) + b, err := Marshal(exception{ + code: SabredavNotFound, + message: m, + }) + HandleWebdavError(&log, w, b, err) + return nil, nil, false + } + HandleErrorStatus(&log, w, res.Status) + return nil, nil, false + } + parentInfo = parentRes.Info + + case parentInfo.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER && depth == "1": req := &provider.ListContainerRequest{ Ref: ref, ArbitraryMetadataKeys: metadataKeys, @@ -240,7 +270,8 @@ func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *ht return nil, nil, false } resourceInfos = append(resourceInfos, res.Infos...) - } else if depth == "infinity" { + + case depth == "infinity": // FIXME: doesn't work cross-storage as the results will have the wrong paths! // use a stack to explore sub-containers breadth-first stack := []string{parentInfo.Path} diff --git a/pkg/app/provider/wopi/wopi.go b/pkg/app/provider/wopi/wopi.go index 2ac83647e2..77e49817e4 100644 --- a/pkg/app/provider/wopi/wopi.go +++ b/pkg/app/provider/wopi/wopi.go @@ -196,7 +196,7 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc if body != nil { sbody = string(body) } - log.Warn().Msg(fmt.Sprintf("wopi: WOPI server returned HTTP %s, error was: %s", openRes.Status, sbody)) + log.Warn().Msg(fmt.Sprintf("wopi: WOPI server returned HTTP %s to request %s, error was: %s", openRes.Status, httpReq.URL.String(), sbody)) return nil, errors.New(sbody) } From 82b91acf168c338d82b32b2d53596eaaea3ebe06 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 14 Oct 2021 11:55:31 +0200 Subject: [PATCH 2/4] Add PR URL to changelog --- changelog/unreleased/propfind-files.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog/unreleased/propfind-files.md b/changelog/unreleased/propfind-files.md index ce154a7fc2..2375be45c5 100644 --- a/changelog/unreleased/propfind-files.md +++ b/changelog/unreleased/propfind-files.md @@ -1 +1,3 @@ -Enhancement: Handle propfind requests for existing files \ No newline at end of file +Enhancement: Handle propfind requests for existing files + +https://github.com/cs3org/reva/pull/2170 \ No newline at end of file From 4ca9f7b07639435732d9e2354063e99b980a26d9 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 14 Oct 2021 11:57:47 +0200 Subject: [PATCH 3/4] Fixes --- internal/http/services/owncloud/ocdav/propfind.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go index 65521353e2..64a5e766cb 100644 --- a/internal/http/services/owncloud/ocdav/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind.go @@ -228,19 +228,20 @@ func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *ht case parentInfo.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER: // The propfind is requested for a file that exists // In this case, we can stat the parent directory and return both + parentPath := path.Dir(parentInfo.Path) resourceInfos = append(resourceInfos, parentInfo) parentRes, err := client.Stat(ctx, &provider.StatRequest{ - Ref: &provider.Reference{Path: path.Dir(parentInfo.Path)}, + Ref: &provider.Reference{Path: parentPath}, ArbitraryMetadataKeys: metadataKeys, }) if err != nil { log.Error().Err(err).Interface("req", req).Msg("error sending a grpc stat request") w.WriteHeader(http.StatusInternalServerError) return nil, nil, false - } else if res.Status.Code != rpc.Code_CODE_OK { - if res.Status.Code == rpc.Code_CODE_NOT_FOUND { + } else if parentRes.Status.Code != rpc.Code_CODE_OK { + if parentRes.Status.Code == rpc.Code_CODE_NOT_FOUND { w.WriteHeader(http.StatusNotFound) - m := fmt.Sprintf("Resource %v not found", ref.Path) + m := fmt.Sprintf("Resource %v not found", parentPath) b, err := Marshal(exception{ code: SabredavNotFound, message: m, @@ -248,7 +249,7 @@ func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *ht HandleWebdavError(&log, w, b, err) return nil, nil, false } - HandleErrorStatus(&log, w, res.Status) + HandleErrorStatus(&log, w, parentRes.Status) return nil, nil, false } parentInfo = parentRes.Info From 3418013581856f1f9a21eca0aa56222a2fbcd717 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 14 Oct 2021 12:16:31 +0200 Subject: [PATCH 4/4] Handle the case of only path propfinds --- internal/http/services/owncloud/ocdav/propfind.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go index 64a5e766cb..90600e393e 100644 --- a/internal/http/services/owncloud/ocdav/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind.go @@ -81,7 +81,7 @@ func (s *svc) handlePathPropfind(w http.ResponseWriter, r *http.Request, ns stri ref := &provider.Reference{Path: fn} - parentInfo, resourceInfos, ok := s.getResourceInfos(ctx, w, r, pf, ref, sublog) + parentInfo, resourceInfos, ok := s.getResourceInfos(ctx, w, r, pf, ref, false, sublog) if !ok { // getResourceInfos handles responses in case of an error so we can just return here. return @@ -115,7 +115,7 @@ func (s *svc) handleSpacesPropfind(w http.ResponseWriter, r *http.Request, space return } - parentInfo, resourceInfos, ok := s.getResourceInfos(ctx, w, r, pf, ref, sublog) + parentInfo, resourceInfos, ok := s.getResourceInfos(ctx, w, r, pf, ref, true, sublog) if !ok { // getResourceInfos handles responses in case of an error so we can just return here. return @@ -162,7 +162,7 @@ func (s *svc) propfindResponse(ctx context.Context, w http.ResponseWriter, r *ht } } -func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *http.Request, pf propfindXML, ref *provider.Reference, log zerolog.Logger) (*provider.ResourceInfo, []*provider.ResourceInfo, bool) { +func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *http.Request, pf propfindXML, ref *provider.Reference, spacesPropfind bool, log zerolog.Logger) (*provider.ResourceInfo, []*provider.ResourceInfo, bool) { depth := r.Header.Get(HeaderDepth) if depth == "" { depth = "1" @@ -225,7 +225,7 @@ func (s *svc) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *ht resourceInfos := []*provider.ResourceInfo{parentInfo} switch { - case parentInfo.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER: + case !spacesPropfind && parentInfo.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER: // The propfind is requested for a file that exists // In this case, we can stat the parent directory and return both parentPath := path.Dir(parentInfo.Path)