Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve a WOPI bridge appProviderURL #1234

Merged
merged 2 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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=nil %}}
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 = nil
{{< /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://localhost: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:"nil;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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ready for review, and I explicitly bring the attention to this note ;-) Feedback welcome.

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