Merge pull request #3569 from NickWalters/fix/collaboration-extension-case

fix(collaboration): match WOPI app extensions without case
This commit is contained in:
Andre Duffeck authored and GitHub committed 2026-09-21 10:14:03 +02:00
commit 4e736079d9
3 files changed
+23 -5

No files matched your search

@@ -59,14 +59,17 @@ func (a *AppURLs) GetMimeTypes() []string {
}
// GetAppURLFor gets the appURL from the list of appURLs based on the
// action and file extension provided. If there is no match, an empty
// string will be returned.
// action and file extension provided. The extension is matched without
// case, so a "report.DOCX" opens in the same app as a "report.docx".
// If there is no match, an empty string will be returned.
func (a *AppURLs) GetAppURLFor(action, fileExt string) string {
currentURLs := a.urls.Load()
if currentURLs == nil {
return ""
}
fileExt = strings.ToLower(fileExt)
if actionURL, ok := (*currentURLs)[action]; ok {
if actionExtensionURL, ok := actionURL[fileExt]; ok {
return actionExtensionURL
@@ -162,7 +165,8 @@ func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) {
if _, ok := appURLs[access]; !ok {
appURLs[access] = make(map[string]string)
}
appURLs[access]["."+ext] = u.String()
// the extensions are stored in lower case, GetAppURLFor looks them up that way
appURLs[access]["."+strings.ToLower(ext)] = u.String()
}
}
}
@@ -49,6 +49,18 @@ var _ = Describe("AppURLs", func() {
Expect(appURLs.GetAppURLFor("edit", ".docx")).To(Equal("https://example.com/edit/docx"))
})
It("should find the app URL whatever case the extension has", func() {
testURLs := map[string]map[string]string{
"view": {".docx": "https://example.com/view/docx"},
"edit": {".docx": "https://example.com/edit/docx"},
}
appURLs.Store(testURLs)
Expect(appURLs.GetAppURLFor("view", ".DOCX")).To(Equal("https://example.com/view/docx"))
Expect(appURLs.GetAppURLFor("edit", ".DocX")).To(Equal("https://example.com/edit/docx"))
})
It("should return empty string for non-existent action", func() {
testURLs := map[string]map[string]string{
"view": {".pdf": "https://example.com/view/pdf"},
@@ -285,6 +297,7 @@ var _ = Describe("Discovery", func() {
<app name="Word" favIconUrl="https://cloud.opencloud.test/web-apps/apps/documenteditor/main/resources/img/favicon.ico">
<action name="view" ext="pdf" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view?&amp;&lt;rs=DC_LLCC&amp;&gt;&lt;dchat=DISABLE_CHAT&amp;&gt;&lt;embed=EMBEDDED&amp;&gt;&lt;fs=FULLSCREEN&amp;&gt;&lt;hid=HOST_SESSION_ID&amp;&gt;&lt;rec=RECORDING&amp;&gt;&lt;sc=SESSION_CONTEXT&amp;&gt;&lt;thm=THEME_ID&amp;&gt;&lt;ui=UI_LLCC&amp;&gt;&lt;wopisrc=WOPI_SOURCE&amp;&gt;&amp;"/>
<action name="embedview" ext="pdf" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view?embed=1&amp;&lt;rs=DC_LLCC&amp;&gt;&lt;dchat=DISABLE_CHAT&amp;&gt;&lt;embed=EMBEDDED&amp;&gt;&lt;fs=FULLSCREEN&amp;&gt;&lt;hid=HOST_SESSION_ID&amp;&gt;&lt;rec=RECORDING&amp;&gt;&lt;sc=SESSION_CONTEXT&amp;&gt;&lt;thm=THEME_ID&amp;&gt;&lt;ui=UI_LLCC&amp;&gt;&lt;wopisrc=WOPI_SOURCE&amp;&gt;&amp;"/>
<action name="view" ext="ODT" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view"/>
<action name="view" ext="djvu" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view?&amp;&lt;rs=DC_LLCC&amp;&gt;&lt;dchat=DISABLE_CHAT&amp;&gt;&lt;embed=EMBEDDED&amp;&gt;&lt;fs=FULLSCREEN&amp;&gt;&lt;hid=HOST_SESSION_ID&amp;&gt;&lt;rec=RECORDING&amp;&gt;&lt;sc=SESSION_CONTEXT&amp;&gt;&lt;thm=THEME_ID&amp;&gt;&lt;ui=UI_LLCC&amp;&gt;&lt;wopisrc=WOPI_SOURCE&amp;&gt;&amp;"/>
<action name="embedview" ext="djvu" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view?embed=1&amp;&lt;rs=DC_LLCC&amp;&gt;&lt;dchat=DISABLE_CHAT&amp;&gt;&lt;embed=EMBEDDED&amp;&gt;&lt;fs=FULLSCREEN&amp;&gt;&lt;hid=HOST_SESSION_ID&amp;&gt;&lt;rec=RECORDING&amp;&gt;&lt;sc=SESSION_CONTEXT&amp;&gt;&lt;thm=THEME_ID&amp;&gt;&lt;ui=UI_LLCC&amp;&gt;&lt;wopisrc=WOPI_SOURCE&amp;&gt;&amp;"/>
<action name="view" ext="docx" urlsrc="https://cloud.opencloud.test/hosting/wopi/word/view?&amp;&lt;rs=DC_LLCC&amp;&gt;&lt;dchat=DISABLE_CHAT&amp;&gt;&lt;embed=EMBEDDED&amp;&gt;&lt;fs=FULLSCREEN&amp;&gt;&lt;hid=HOST_SESSION_ID&amp;&gt;&lt;rec=RECORDING&amp;&gt;&lt;sc=SESSION_CONTEXT&amp;&gt;&lt;thm=THEME_ID&amp;&gt;&lt;ui=UI_LLCC&amp;&gt;&lt;wopisrc=WOPI_SOURCE&amp;&gt;&amp;"/>
@@ -339,6 +352,7 @@ var _ = Describe("Discovery", func() {
"view": map[string]string{
".pdf": "https://cloud.opencloud.test/hosting/wopi/word/view",
".djvu": "https://cloud.opencloud.test/hosting/wopi/word/view",
".odt": "https://cloud.opencloud.test/hosting/wopi/word/view",
".docx": "https://cloud.opencloud.test/hosting/wopi/word/view",
".xls": "https://cloud.opencloud.test/hosting/wopi/cell/view",
".xlsb": "https://cloud.opencloud.test/hosting/wopi/cell/view",
@@ -108,8 +108,8 @@ func (s *Service) OpenInApp(
// get the appURL we need to use
appURL := s.getAppUrl(fileExt, req.GetViewMode())
if appURL == "" {
logger.Error().Msg("OpenInApp: neither edit nor view app URL found")
return nil, errors.New("neither edit nor view app URL found")
logger.Error().Str("FileExtension", fileExt).Msg("OpenInApp: neither edit nor view app URL found")
return nil, errors.New("neither edit nor view app URL found for " + fileExt)
}
// append the parameters we need