Skip to content

Commit 48515a7

Browse files
author
Jannik Stehle
committed
feat: add folder id and etag to dav mkcol responses
Adds the `OC-FileId` and the `OC-ETag` headers to dav `mkcol` responses. This is necessary for clients that work with ids and want to fetch a folder immediately after creating.
1 parent 11ee452 commit 48515a7

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Enhancement: Folder id and etag in mkcol dav responses
2+
3+
`mkcol` dav responses now have the `OC-FileId` and the `OC-ETag` header, containing the id and the etag of the created folder.
4+
5+
https://github.com/cs3org/reva/pull/4767
6+
https://github.com/owncloud/ocis/issues/9618

internal/http/services/owncloud/ocdav/mkcol.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ import (
2727

2828
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
2929
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
30+
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net"
3031
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup"
3132
"github.com/cs3org/reva/v2/pkg/appctx"
3233
"github.com/cs3org/reva/v2/pkg/errtypes"
3334
rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status"
35+
"github.com/cs3org/reva/v2/pkg/storagespace"
3436
"github.com/cs3org/reva/v2/pkg/utils"
3537
"github.com/rs/zerolog"
3638
)
@@ -123,6 +125,15 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
123125
case err != nil:
124126
return http.StatusInternalServerError, err
125127
case res.Status.Code == rpc.Code_CODE_OK:
128+
sReq := &provider.StatRequest{
129+
Ref: childRef,
130+
}
131+
sRes, err := client.Stat(ctx, sReq)
132+
if err != nil {
133+
return http.StatusInternalServerError, err
134+
}
135+
w.Header().Set(net.HeaderOCFileID, storagespace.FormatResourceID(sRes.GetInfo().GetId()))
136+
w.Header().Set(net.HeaderOCETag, sRes.GetInfo().GetEtag())
126137
w.WriteHeader(http.StatusCreated)
127138
return 0, nil
128139
case res.Status.Code == rpc.Code_CODE_NOT_FOUND:

internal/http/services/owncloud/ocdav/ocdav_blackbox_test.go

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,21 @@ var _ = Describe("ocdav", func() {
371371
Status: status.NewOK(ctx),
372372
}, nil)
373373

374+
resourceId := &cs3storageprovider.ResourceId{StorageId: "storage", SpaceId: "provider", OpaqueId: "opaque"}
375+
resourceETag := "some-etag"
376+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
377+
Status: status.NewOK(ctx),
378+
Info: &cs3storageprovider.ResourceInfo{
379+
Id: resourceId,
380+
Etag: resourceETag,
381+
},
382+
}, nil)
383+
374384
handler.Handler().ServeHTTP(rr, req)
375385
Expect(rr).To(HaveHTTPStatus(http.StatusCreated))
376386
Expect(rr).To(HaveHTTPBody(BeEmpty()), "Body must be empty")
377-
// TODO expect fileid and etag header?
387+
Expect(rr).To(HaveHTTPHeaderWithValue(net.HeaderOCFileID, storagespace.FormatResourceID(resourceId)))
388+
Expect(rr).To(HaveHTTPHeaderWithValue(net.HeaderOCETag, resourceETag))
378389
})
379390

380391
})
@@ -1254,6 +1265,15 @@ var _ = Describe("ocdav", func() {
12541265
Status: status.NewOK(ctx),
12551266
}, nil)
12561267

1268+
if expectedStatus == http.StatusCreated {
1269+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1270+
Status: status.NewOK(ctx),
1271+
Info: &cs3storageprovider.ResourceInfo{
1272+
Id: mReq.Source.ResourceId,
1273+
},
1274+
}, nil)
1275+
}
1276+
12571277
rr := httptest.NewRecorder()
12581278
req, err := http.NewRequest("MKCOL", endpoint+"/foo", strings.NewReader(""))
12591279
Expect(err).ToNot(HaveOccurred())
@@ -1342,6 +1362,15 @@ var _ = Describe("ocdav", func() {
13421362
return utils.ResourceEqual(req.Ref, &ref)
13431363
})).Return(nil, fmt.Errorf("unexpected io error"))
13441364

1365+
if expectedStatus == http.StatusCreated {
1366+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1367+
Status: status.NewOK(ctx),
1368+
Info: &cs3storageprovider.ResourceInfo{
1369+
Id: mReq.Source.ResourceId,
1370+
},
1371+
}, nil)
1372+
}
1373+
13451374
rr := httptest.NewRecorder()
13461375
req, err := http.NewRequest("MKCOL", endpoint+"/foo", strings.NewReader(""))
13471376
Expect(err).ToNot(HaveOccurred())
@@ -1431,6 +1460,15 @@ var _ = Describe("ocdav", func() {
14311460
Status: status.NewOK(ctx),
14321461
}, nil)
14331462

1463+
if expectedStatus == http.StatusCreated {
1464+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1465+
Status: status.NewOK(ctx),
1466+
Info: &cs3storageprovider.ResourceInfo{
1467+
Id: mReq.Source.ResourceId,
1468+
},
1469+
}, nil)
1470+
}
1471+
14341472
rr := httptest.NewRecorder()
14351473
req, err := http.NewRequest("MKCOL", endpoint+"/foo", strings.NewReader(""))
14361474
Expect(err).ToNot(HaveOccurred())
@@ -1519,6 +1557,15 @@ var _ = Describe("ocdav", func() {
15191557
Status: status.NewNotFound(ctx, "not found"),
15201558
}, nil)
15211559

1560+
if expectedStatus == http.StatusCreated {
1561+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1562+
Status: status.NewOK(ctx),
1563+
Info: &cs3storageprovider.ResourceInfo{
1564+
Id: mReq.Source.ResourceId,
1565+
},
1566+
}, nil)
1567+
}
1568+
15221569
rr := httptest.NewRecorder()
15231570
req, err := http.NewRequest("MKCOL", endpoint+"/foo", strings.NewReader(""))
15241571
Expect(err).ToNot(HaveOccurred())
@@ -1672,6 +1719,15 @@ var _ = Describe("ocdav", func() {
16721719
}, nil)
16731720
}
16741721

1722+
if expectedStatus == http.StatusCreated {
1723+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1724+
Status: status.NewOK(ctx),
1725+
Info: &cs3storageprovider.ResourceInfo{
1726+
Id: mReq.Source.ResourceId,
1727+
},
1728+
}, nil)
1729+
}
1730+
16751731
parentRef := cs3storageprovider.Reference{
16761732
ResourceId: userspace.Root,
16771733
Path: utils.MakeRelativePath(path.Dir(expectedPath)),
@@ -1808,6 +1864,15 @@ var _ = Describe("ocdav", func() {
18081864
Status: status.NewOK(ctx),
18091865
}, nil)
18101866

1867+
if expectedStatus == http.StatusCreated {
1868+
client.On("Stat", mock.Anything, mock.Anything).Return(&cs3storageprovider.StatResponse{
1869+
Status: status.NewOK(ctx),
1870+
Info: &cs3storageprovider.ResourceInfo{
1871+
Id: mReq.Source.ResourceId,
1872+
},
1873+
}, nil)
1874+
}
1875+
18111876
rr := httptest.NewRecorder()
18121877
req, err := http.NewRequest("MKCOL", endpoint+"/foo", strings.NewReader(""))
18131878
req.Header.Set("If", "(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)")

0 commit comments

Comments
 (0)