summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorsilverwind <me@silverwind.io>2020-12-23 20:09:54 +0100
committerGitHub <noreply@github.com>2020-12-23 19:09:54 +0000
commitcd5278a44c45ad4f763b7142674c956576561d43 (patch)
tree66e62f583b58c03862f8cd5bd7d37668c69e12ca /modules
parente0c753e770a64cda5e3900aa1da3d7e1f3263c9a (diff)
downloadgitea-cd5278a44c45ad4f763b7142674c956576561d43.tar.gz
gitea-cd5278a44c45ad4f763b7142674c956576561d43.zip
Fix manifest encoding (#14114)
The previous URL encoding would encode spaces to '+' for the app name which is incorrect. Use base64 encoding instead which does not have such issues.
Diffstat (limited to 'modules')
-rw-r--r--modules/setting/setting.go84
-rw-r--r--modules/setting/setting_test.go29
2 files changed, 104 insertions, 9 deletions
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 290ec94c44..8a4d7acc4d 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -7,8 +7,8 @@ package setting
import (
"encoding/base64"
+ "encoding/json"
"fmt"
- "html/template"
"io"
"io/ioutil"
"math"
@@ -104,6 +104,7 @@ var (
GracefulHammerTime time.Duration
StartupTimeout time.Duration
StaticURLPrefix string
+ AbsoluteAssetURL string
SSH = struct {
Disabled bool `ini:"DISABLE_SSH"`
@@ -294,7 +295,7 @@ var (
CSRFCookieName = "_csrf"
CSRFCookieHTTPOnly = true
- ManifestData template.URL
+ ManifestData string
// Mirror settings
Mirror struct {
@@ -600,6 +601,11 @@ func NewContext() {
Domain = urlHostname
}
+ AbsoluteAssetURL = MakeAbsoluteAssetURL(AppURL, StaticURLPrefix)
+
+ manifestBytes := MakeManifestData(AppName, AppURL, AbsoluteAssetURL)
+ ManifestData = `application/json;base64,` + base64.StdEncoding.EncodeToString(manifestBytes)
+
var defaultLocalURL string
switch Protocol {
case UnixSocket:
@@ -645,8 +651,6 @@ func NewContext() {
LandingPageURL = LandingPageHome
}
- ManifestData = makeManifestData()
-
if len(SSH.Domain) == 0 {
SSH.Domain = Domain
}
@@ -1045,12 +1049,74 @@ func loadOrGenerateInternalToken(sec *ini.Section) string {
return token
}
-func makeManifestData() template.URL {
- name := url.QueryEscape(AppName)
- prefix := url.QueryEscape(StaticURLPrefix)
- subURL := url.QueryEscape(AppSubURL) + "/"
+// MakeAbsoluteAssetURL returns the absolute asset url prefix without a trailing slash
+func MakeAbsoluteAssetURL(appURL string, staticURLPrefix string) string {
+ parsedPrefix, err := url.Parse(strings.TrimSuffix(staticURLPrefix, "/"))
+ if err != nil {
+ log.Fatal("Unable to parse STATIC_URL_PREFIX: %v", err)
+ }
+
+ if err == nil && parsedPrefix.Hostname() == "" {
+ if staticURLPrefix == "" {
+ return strings.TrimSuffix(appURL, "/")
+ }
+
+ // StaticURLPrefix is just a path
+ return strings.TrimSuffix(appURL, "/") + strings.TrimSuffix(staticURLPrefix, "/")
+ }
+
+ return strings.TrimSuffix(staticURLPrefix, "/")
+}
+
+// MakeManifestData generates web app manifest JSON
+func MakeManifestData(appName string, appURL string, absoluteAssetURL string) []byte {
+ type manifestIcon struct {
+ Src string `json:"src"`
+ Type string `json:"type"`
+ Sizes string `json:"sizes"`
+ }
+
+ type manifestJSON struct {
+ Name string `json:"name"`
+ ShortName string `json:"short_name"`
+ StartURL string `json:"start_url"`
+ Icons []manifestIcon `json:"icons"`
+ }
+
+ bytes, err := json.Marshal(&manifestJSON{
+ Name: appName,
+ ShortName: appName,
+ StartURL: appURL,
+ Icons: []manifestIcon{
+ {
+ Src: absoluteAssetURL + "/img/logo-lg.png",
+ Type: "image/png",
+ Sizes: "880x880",
+ },
+ {
+ Src: absoluteAssetURL + "/img/logo-512.png",
+ Type: "image/png",
+ Sizes: "512x512",
+ },
+ {
+ Src: absoluteAssetURL + "/img/logo-192.png",
+ Type: "image/png",
+ Sizes: "192x192",
+ },
+ {
+ Src: absoluteAssetURL + "/img/logo-sm.png",
+ Type: "image/png",
+ Sizes: "120x120",
+ },
+ },
+ })
+
+ if err != nil {
+ log.Error("unable to marshal manifest JSON. Error: %v", err)
+ return make([]byte, 0)
+ }
- return template.URL(`data:application/json,{"short_name":"` + name + `","name":"` + name + `","icons":[{"src":"` + prefix + `/img/logo-lg.png","type":"image/png","sizes":"880x880"},{"src":"` + prefix + `/img/logo-sm.png","type":"image/png","sizes":"120x120"},{"src":"` + prefix + `/img/logo-512.png","type":"image/png","sizes":"512x512"},{"src":"` + prefix + `/img/logo-192.png","type":"image/png","sizes":"192x192"}],"start_url":"` + subURL + `","scope":"` + subURL + `","background_color":"%23FAFAFA","display":"standalone"}`)
+ return bytes
}
// NewServices initializes the services
diff --git a/modules/setting/setting_test.go b/modules/setting/setting_test.go
new file mode 100644
index 0000000000..f12fd8843a
--- /dev/null
+++ b/modules/setting/setting_test.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package setting
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMakeAbsoluteAssetURL(t *testing.T) {
+ assert.Equal(t, "https://localhost:2345", MakeAbsoluteAssetURL("https://localhost:1234", "https://localhost:2345"))
+ assert.Equal(t, "https://localhost:2345", MakeAbsoluteAssetURL("https://localhost:1234/", "https://localhost:2345"))
+ assert.Equal(t, "https://localhost:2345", MakeAbsoluteAssetURL("https://localhost:1234/", "https://localhost:2345/"))
+ assert.Equal(t, "https://localhost:1234/foo", MakeAbsoluteAssetURL("https://localhost:1234", "/foo"))
+ assert.Equal(t, "https://localhost:1234/foo", MakeAbsoluteAssetURL("https://localhost:1234/", "/foo"))
+ assert.Equal(t, "https://localhost:1234/foo", MakeAbsoluteAssetURL("https://localhost:1234/", "/foo/"))
+ assert.Equal(t, "https://localhost:1234/foo/bar", MakeAbsoluteAssetURL("https://localhost:1234/foo", "/bar"))
+ assert.Equal(t, "https://localhost:1234/foo/bar", MakeAbsoluteAssetURL("https://localhost:1234/foo/", "/bar"))
+ assert.Equal(t, "https://localhost:1234/foo/bar", MakeAbsoluteAssetURL("https://localhost:1234/foo/", "/bar/"))
+}
+
+func TestMakeManifestData(t *testing.T) {
+ jsonBytes := MakeManifestData(`Example App '\"`, "https://example.com", "https://example.com/foo/bar")
+ assert.True(t, json.Valid(jsonBytes))
+}