Skip to content

Commit

Permalink
Resolve a WOPI bridge appProviderURL by opening it and extracting its…
Browse files Browse the repository at this point in the history
… redirect
  • Loading branch information
glpatcern committed Oct 12, 2020
1 parent fb08084 commit 7eb0fad
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/appprovider-wopibridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Resolve a WOPI bridge appProviderURL by extracting its redirect

Applications served by the WOPI bridge (CodiMD for the time being) require
an extra redirection as the WOPI bridge itself behaves like a user app.
This change returns to the client the redirected URL from the WOPI bridge,
which is the real application URL.

https://github.com/cs3org/reva/pull/1234
20 changes: 18 additions & 2 deletions docs/content/en/docs/config/grpc/services/appprovider/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,34 @@ description: >
# _struct: config_

{{% dir name="iopsecret" type="string" default="" %}}
The iopsecret used to connect to the wopiserver. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L62)
The iopsecret used to connect to the wopiserver. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L59)
{{< highlight toml >}}
[grpc.services.appprovider]
iopsecret = ""
{{< /highlight >}}
{{% /dir %}}

{{% dir name="wopiurl" type="string" default="" %}}
The wopiserver's URL. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L63)
The wopiserver's URL. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L60)
{{< highlight toml >}}
[grpc.services.appprovider]
wopiurl = ""
{{< /highlight >}}
{{% /dir %}}

{{% dir name="wopibridgeurl" type="string" default="" %}}
The wopibridge's URL. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L61)
{{< highlight toml >}}
[grpc.services.appprovider]
wopibridgeurl = ""
{{< /highlight >}}
{{% /dir %}}

{{% dir name="mimetypes" type="map[string]string" default= %}}
A list of supported mime types and corresponding file extensions. [[Ref]](https://github.com/cs3org/reva/tree/master/internal/grpc/services/appprovider/appprovider.go#L62)
{{< highlight toml >}}
[grpc.services.appprovider]
mimetypes =
{{< /highlight >}}
{{% /dir %}}

1 change: 1 addition & 0 deletions examples/ocmd/ocmd-server-1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ driver = "memory"
driver = "demo"
iopsecret = "testsecret"
wopiurl = "http://0.0.0.0:8880/"
wopibridgeurl = "http://glpdesk.cern.ch:8000/"

[grpc.services.appprovider.mimetypes]
".zmd" = "application/compressed-markdown"
Expand Down
32 changes: 30 additions & 2 deletions internal/grpc/services/appprovider/appprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ type config struct {
Demo map[string]interface{} `mapstructure:"demo"`
IopSecret string `mapstructure:"iopsecret" docs:";The iopsecret used to connect to the wopiserver."`
WopiURL string `mapstructure:"wopiurl" docs:";The wopiserver's URL."`
MimeTypes map[string]string `mapstructure:"mimetypes"`
WopiBrURL string `mapstructure:"wopibridgeurl" docs:";The wopibridge's URL."`
MimeTypes map[string]string `mapstructure:"mimetypes" docs:";A list of supported mime types and corresponding file extensions."`
}

// New creates a new AppProviderService
Expand Down Expand Up @@ -257,8 +258,35 @@ func (s *service) OpenFileInAppProvider(ctx context.Context, req *providerpb.Ope
appProviderURL += "?"
}
appProviderURL = fmt.Sprintf("%sWOPISrc=%s", appProviderURL, openResBody)
log.Info().Msg(fmt.Sprintf("Returning app provider URL %s", appProviderURL))

// In case of applications served by the WOPI bridge, resolve the URL and go to the app
// Note that URL matching is performed via string matching, not via IP resolution: may need to fix this
if strings.Contains(appProviderURL, s.conf.WopiBrURL) {
httpClient := rhttp.GetHTTPClient(
rhttp.Context(ctx),
rhttp.Timeout(time.Duration(5*int64(time.Second))),
)
httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
// do not follow a redirect
return http.ErrUseLastResponse
}

bridgeReq, err := rhttp.NewRequest(ctx, "GET", appProviderURL, nil)
if err != nil {
return nil, err
}
bridgeRes, err := httpClient.Do(bridgeReq)
if err != nil {
return nil, err
}
defer bridgeRes.Body.Close()
if bridgeRes.StatusCode != http.StatusFound {
return nil, fmt.Errorf("Request to WOPI bridge returned %d", bridgeRes.StatusCode)
}
appProviderURL = bridgeRes.Header.Get("Location")
}

log.Info().Msg(fmt.Sprintf("Returning app provider URL %s", appProviderURL))
return &providerpb.OpenFileInAppProviderResponse{
Status: status.NewOK(ctx),
AppProviderUrl: appProviderURL,
Expand Down

0 comments on commit 7eb0fad

Please sign in to comment.