@@ -23,7 +23,7 @@ import (
23
23
"fmt"
24
24
"mime"
25
25
"net/http"
26
- "path/filepath "
26
+ "net/url "
27
27
"strings"
28
28
"time"
29
29
@@ -63,8 +63,7 @@ func (h *sharesHandler) init(c *config) error {
63
63
return nil
64
64
}
65
65
66
- // CreateShare sends all the informations to the consumer needed to start
67
- // synchronization between the two services.
66
+ // CreateShare implements the OCM /shares call.
68
67
func (h * sharesHandler ) CreateShare (w http.ResponseWriter , r * http.Request ) {
69
68
ctx := r .Context ()
70
69
log := appctx .GetLogger (ctx )
@@ -73,6 +72,7 @@ func (h *sharesHandler) CreateShare(w http.ResponseWriter, r *http.Request) {
73
72
reqres .WriteError (w , r , reqres .APIErrorInvalidParameter , err .Error (), nil )
74
73
return
75
74
}
75
+ log .Info ().Any ("req" , req ).Msg ("OCM /shares request received" )
76
76
77
77
_ , meshProvider , err := getIDAndMeshProvider (req .Sender )
78
78
log .Debug ().Msgf ("Determined Mesh Provider '%s' from req.Sender '%s'" , meshProvider , req .Sender )
@@ -161,6 +161,7 @@ func (h *sharesHandler) CreateShare(w http.ResponseWriter, r *http.Request) {
161
161
}
162
162
}
163
163
164
+ log .Info ().Any ("req" , createShareReq ).Msg ("CreateOCMCoreShare payload" )
164
165
createShareResp , err := h .gatewayClient .CreateOCMCoreShare (ctx , createShareReq )
165
166
if err != nil {
166
167
reqres .WriteError (w , r , reqres .APIErrorServerError , "error creating ocm share" , err )
@@ -210,10 +211,10 @@ func getCreateShareRequest(r *http.Request) (*NewShareRequest, error) {
210
211
contentType , _ , err := mime .ParseMediaType (r .Header .Get ("Content-Type" ))
211
212
if err == nil && contentType == "application/json" {
212
213
if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
213
- return nil , err
214
+ return nil , errors . Wrap ( err , "malformed OCM /shares request" )
214
215
}
215
216
} else {
216
- return nil , errors .New ("OCM /share request payload not recognised " )
217
+ return nil , errors .New ("malformed OCM /shares request payload" )
217
218
}
218
219
// validate the request
219
220
if err := validate .Struct (req ); err != nil {
@@ -249,40 +250,77 @@ func getAndResolveProtocols(p Protocols, r *http.Request) ([]*ocm.Protocol, erro
249
250
protos := make ([]* ocm.Protocol , 0 , len (p ))
250
251
for _ , data := range p {
251
252
ocmProto := data .ToOCMProtocol ()
253
+ protocolName := GetProtocolName (data )
254
+ var uri string
255
+ var isLocalhost bool
256
+
257
+ switch protocolName {
258
+ case "webdav" :
259
+ uri = ocmProto .GetWebdavOptions ().Uri
260
+ isLocalhost = strings .Contains (uri , "localhost" )
261
+ case "webapp" :
262
+ uri = ocmProto .GetWebappOptions ().UriTemplate
263
+ isLocalhost = strings .Contains (uri , "localhost" )
264
+ }
265
+
252
266
// Irrespective from the presence of a full `uri` in the payload (deprecated), resolve the remote root
253
- remoteRoot , err := discoverOcmRoot (r , GetProtocolName (data ))
267
+ // yet skip this if the remote is localhost (for integration tests)
268
+ if isLocalhost {
269
+ protos = append (protos , ocmProto )
270
+ continue
271
+ }
272
+ remoteRoot , err := discoverOcmRoot (r , protocolName )
254
273
if err != nil {
255
274
return nil , err
256
275
}
257
- if GetProtocolName (data ) == "webdav" {
258
- ocmProto .GetWebdavOptions ().Uri = filepath .Join (remoteRoot , ocmProto .GetWebdavOptions ().SharedSecret )
259
- } else if GetProtocolName (data ) == "webapp" {
260
- // ocmProto.GetWebappOptions().Uri = filepath.Join(remoteRoot, ocmProto.GetWebappOptions().SharedSecret) -> this is OCM 1.2
276
+ uri , _ = url .JoinPath (remoteRoot , uri [strings .LastIndex (uri , "/" )+ 1 :])
277
+
278
+ switch protocolName {
279
+ case "webdav" :
280
+ ocmProto .GetWebdavOptions ().Uri = uri
281
+ case "webapp" :
282
+ ocmProto .GetWebappOptions ().UriTemplate = uri
261
283
}
262
284
protos = append (protos , ocmProto )
263
285
}
286
+
264
287
return protos , nil
265
288
}
266
289
290
+
267
291
func discoverOcmRoot (r * http.Request , proto string ) (string , error ) {
268
292
// implements the OCM discovery logic to fetch the root at the remote host that sent the share for the given proto, see
269
293
// https://cs3org.github.io/OCM-API/docs.html?branch=v1.1.0&repo=OCM-API&user=cs3org#/paths/~1ocm-provider/get
270
294
ctx := r .Context ()
271
295
log := appctx .GetLogger (ctx )
272
- log .Debug ().Str ("sender" , r .Host ).Msg ("received OCM share, attempting to discover sender endpoint" )
296
+
297
+ // assume the sender host is either given in the usual reverse proxy headers or as RemoteAddr, and that the
298
+ // remote end listens on https regardless if the incoming connection got its TLS terminated upstream of us
299
+ senderURL := r .Header .Get ("X-Real-Ip" )
300
+ if senderURL == "" {
301
+ senderURL = r .Header .Get ("X-Forwarded-For" )
302
+ }
303
+ if senderURL == "" {
304
+ senderURL = r .RemoteAddr
305
+ }
306
+ senderURL = "https://" + senderURL [:strings .LastIndex (senderURL , ":" )]
307
+ log .Debug ().Str ("sender" , senderURL ).Msg ("received OCM share, attempting to discover sender endpoint" )
273
308
274
309
ocmClient := NewClient (time .Duration (10 )* time .Second , true )
275
- ocmCaps , err := ocmClient .Discover (ctx , r . Host )
310
+ ocmCaps , err := ocmClient .Discover (ctx , senderURL )
276
311
if err != nil {
277
- log .Warn ().Str ("sender" , r . Host ).Err (err ).Msg ("failed to discover OCM sender" )
312
+ log .Warn ().Str ("sender" , senderURL ).Err (err ).Msg ("failed to discover OCM sender" )
278
313
return "" , err
279
314
}
280
315
for _ , t := range ocmCaps .ResourceTypes {
281
316
protoRoot , ok := t .Protocols [proto ]
282
317
if ok {
283
318
// assume the first resourceType that exposes a root is OK to use: as a matter of fact,
284
319
// no implementation exists yet that exposes multiple resource types with different roots.
285
- return filepath .Join (ocmCaps .Endpoint , protoRoot ), nil
320
+ u , _ := url .Parse (ocmCaps .Endpoint )
321
+ u .Path = protoRoot
322
+ u .RawQuery = ""
323
+ return u .String (), nil
286
324
}
287
325
}
288
326
0 commit comments