From c559a9f824abc060bebf4855c4e833a749a48749 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Thu, 14 Mar 2019 10:20:40 +0800
Subject: [PATCH 1/9] static url

---
 custom/conf/app.ini.sample         |  2 ++
 modules/setting/setting.go         |  4 ++-
 modules/templates/helper.go        | 15 ++++++----
 templates/base/footer.tmpl         | 42 +++++++++++++--------------
 templates/base/footer_content.tmpl |  2 +-
 templates/base/head.tmpl           | 46 +++++++++++++++---------------
 templates/base/head_navbar.tmpl    |  2 +-
 templates/home.tmpl                |  2 +-
 8 files changed, 61 insertions(+), 54 deletions(-)

diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample
index 0212964750592..832e6cf2e8175 100644
--- a/custom/conf/app.ini.sample
+++ b/custom/conf/app.ini.sample
@@ -151,6 +151,8 @@ FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
 PROTOCOL = http
 DOMAIN = localhost
 ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
+; when STATIC_URL_PREFIX is empty it will follow APP_URL
+STATIC_URL_PREFIX = 
 ; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
 HTTP_ADDR = 0.0.0.0
 HTTP_PORT = 3000
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 6a5c5a36d7064..005f756b32703 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -104,6 +104,7 @@ var (
 	LetsEncryptTOS       bool
 	LetsEncryptDirectory string
 	LetsEncryptEmail     string
+	StaticURLPrefix      string
 
 	SSH = struct {
 		Disabled                 bool           `ini:"DISABLE_SSH"`
@@ -582,7 +583,7 @@ func NewContext() {
 		defaultAppURL += ":" + HTTPPort
 	}
 	AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
-	AppURL = strings.TrimRight(AppURL, "/") + "/"
+	AppURL = strings.TrimSuffix(AppURL, "/") + "/"
 
 	// Check if has app suburl.
 	appURL, err := url.Parse(AppURL)
@@ -592,6 +593,7 @@ func NewContext() {
 	// Suburl should start with '/' and end without '/', such as '/{subpath}'.
 	// This value is empty if site does not have sub-url.
 	AppSubURL = strings.TrimSuffix(appURL.Path, "/")
+	StaticURLPrefix = strings.TrimSuffix(sec.Key("STATIC_URL_PREFIX").MustString(AppSubURL), "/")
 	AppSubURLDepth = strings.Count(AppSubURL, "/")
 	// Check if Domain differs from AppURL domain than update it to AppURL's domain
 	// TODO: Can be replaced with url.Hostname() when minimal GoLang version is 1.8
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 5a3969c098f83..dc2865254cf57 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -48,6 +48,9 @@ func NewFuncMap() []template.FuncMap {
 		"AppSubUrl": func() string {
 			return setting.AppSubURL
 		},
+		"StaticUrlPrefix": func() string {
+			return setting.StaticURLPrefix
+		},
 		"AppUrl": func() string {
 			return setting.AppURL
 		},
@@ -110,12 +113,12 @@ func NewFuncMap() []template.FuncMap {
 			}
 			return str[start:end]
 		},
-		"EllipsisString":        base.EllipsisString,
-		"DiffTypeToStr":         DiffTypeToStr,
-		"DiffLineTypeToStr":     DiffLineTypeToStr,
-		"Sha1":                  Sha1,
-		"ShortSha":              base.ShortSha,
-		"MD5":                   base.EncodeMD5,
+		"EllipsisString":    base.EllipsisString,
+		"DiffTypeToStr":     DiffTypeToStr,
+		"DiffLineTypeToStr": DiffLineTypeToStr,
+		"Sha1":              Sha1,
+		"ShortSha":          base.ShortSha,
+		"MD5":               base.EncodeMD5,
 		"ActionContent2Commits": ActionContent2Commits,
 		"PathEscape":            url.PathEscape,
 		"EscapePound": func(str string) string {
diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl
index 13718620da0ec..802175ce7e6c9 100644
--- a/templates/base/footer.tmpl
+++ b/templates/base/footer.tmpl
@@ -12,38 +12,38 @@
 
 	{{template "base/footer_content" .}}
 
-	<script src="{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js"></script>
 {{if .RequireSimpleMDE}}
-	<script src="{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/codemirror/addon/mode/loadmode.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/codemirror/mode/meta.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js"></script>
 	<script>
-		CodeMirror.modeURL =  "{{AppSubUrl}}/vendor/plugins/codemirror/mode/%N/%N.js";
+		CodeMirror.modeURL =  "{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/%N/%N.js";
 	</script>
 {{end}}
 {{if .RequireGitGraph}}
 	<!-- graph -->
-	<script src="{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js"></script>
 	<script src="{{AppSubUrl}}/js/draw.js"></script>
 {{end}}
 
 <!-- Third-party libraries -->
 {{if .RequireHighlightJS}}
-	<script src="{{AppSubUrl}}/vendor/plugins/highlight/highlight.pack.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/highlight/highlight.pack.js"></script>
 {{end}}
 {{if .RequireMinicolors}}
-	<script src="{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js"></script>
 {{end}}
 {{if .RequireDatetimepicker}}
-	<script src="{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.js"></script>
 {{end}}
 {{if .RequireDropzone}}
-	<script src="{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js"></script>
 {{end}}
 {{if .RequireU2F}}
-	<script src="{{AppSubUrl}}/vendor/plugins/u2f/index.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/u2f/index.js"></script>
 {{end}}
 {{if .EnableCaptcha}}
 	{{if eq .CaptchaType "recaptcha"}}
@@ -51,7 +51,7 @@
 	{{end}}
 {{end}}
 {{if .RequireTribute}}
-	<script src="{{AppSubUrl}}/vendor/plugins/tribute/tribute.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.min.js"></script>
 	<script>
 		var issuesTribute = new Tribute({
 			values: [
@@ -101,7 +101,7 @@
 					return ':' + item.original + ':';
 				},
 				menuItemTemplate: function (item) {
-					return '<img class="emoji" src="{{AppSubUrl}}/vendor/plugins/emojify/images/' + item.original + '.png"/>' + item.original;
+					return '<img class="emoji" src="{{StaticUrlPrefix}}/vendor/plugins/emojify/images/' + item.original + '.png"/>' + item.original;
 				}
 			}]
 		});
@@ -115,16 +115,16 @@
 		}
 	</script>
 {{end}}
-	<script src="{{AppSubUrl}}/vendor/plugins/emojify/emojify.min.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/clipboard/clipboard.min.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/vue/vue.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js"></script>
 
 	<!-- JavaScript -->
-	<script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js"></script>
 	<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
 {{if .EnableHeatmap}}
-	<script src="{{AppSubUrl}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
 	<script type="text/javascript">
 		initHeatmap('user-heatmap', '{{.HeatmapUser}}');
 	</script>
diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl
index 6f680d4cb893d..364e58a3d03df 100644
--- a/templates/base/footer_content.tmpl
+++ b/templates/base/footer_content.tmpl
@@ -16,7 +16,7 @@
 					{{end}}
 				</div>
 			</div>
-			<a href="{{AppSubUrl}}/vendor/librejs.html" data-jslicense="1">JavaScript licenses</a>
+			<a href="{{StaticUrlPrefix}}/vendor/librejs.html" data-jslicense="1">JavaScript licenses</a>
 			{{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}}
 			<a target="_blank" rel="noopener noreferrer" href="https://gitea.io">{{.i18n.Tr "website"}}</a>
 			{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index 7cdfdd34bea85..658fb33a788d7 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -5,7 +5,7 @@
 	<meta name="viewport" content="width=device-width, initial-scale=1">
 	<meta http-equiv="x-ua-compatible" content="ie=edge">
 	<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
-	<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
+	<link rel="manifest" href="{{StaticUrlPrefix}}/manifest.json" crossorigin="use-credentials">
 
 	<script>
 		if ('serviceWorker' in navigator) {
@@ -70,35 +70,35 @@
 	THE SOFTWARE.
 	---
 	Licensing information for additional javascript libraries can be found at:
-	  {{AppSubUrl}}/vendor/librejs.html
+	  {{StaticUrlPrefix}}/vendor/librejs.html
 
 	@licend  The above is the entire license notice
         for the JavaScript code in this page.
 	*/`}}
 	</script>
 
-	<link rel="shortcut icon" href="{{AppSubUrl}}/img/favicon.png" />
-	<link rel="mask-icon" href="{{AppSubUrl}}/img/gitea-safari.svg" color="#609926">
-	<link rel="preload" href="{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css" as="style" onload="this.rel='stylesheet'">
-	<noscript><link rel="stylesheet" href="{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css"></noscript>
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/assets/octicons/octicons.min.css">
+	<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png" />
+	<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/gitea-safari.svg" color="#609926">
+	<link rel="preload" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css" as="style" onload="this.rel='stylesheet'">
+	<noscript><link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css"></noscript>
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/octicons/octicons.min.css">
 
 {{if .RequireSimpleMDE}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
 {{end}}
 
 {{if .RequireGitGraph}}
 	<!-- graph -->
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.css">
 {{end}}
 
 {{if .RequireTribute}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/tribute/tribute.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
 {{end}}
 
 	<!-- Stylesheet -->
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.css">
-	<link rel="stylesheet" href="{{AppSubUrl}}/css/index.css?v={{MD5 AppVer}}">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
 	<noscript>
 		<style>
 			.dropdown:hover > .menu { display: block; }
@@ -107,25 +107,25 @@
 	</noscript>
 
 {{if .RequireHighlightJS}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/highlight/github.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/highlight/github.css">
 {{end}}
 {{if .RequireMinicolors}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
 {{end}}
 {{if .RequireDatetimepicker}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css">
 {{end}}
 {{if .RequireDropzone}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.css">
 {{end}}
 {{if .EnableHeatmap}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.css">
 {{end}}
 	<style class="list-search-style"></style>
 
-	<script src="{{AppSubUrl}}/vendor/plugins/promise-polyfill/polyfill.min.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/cssrelpreload/loadCSS.min.js"></script>
-	<script src="{{AppSubUrl}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/promise-polyfill/polyfill.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js"></script>
+	<script src="{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js"></script>
 {{if .PageIsUserProfile}}
 	<meta property="og:title" content="{{.Owner.Name}}" />
 	<meta property="og:type" content="profile" />
@@ -144,16 +144,16 @@
 {{else}}
 	<meta property="og:title" content="{{AppName}}">
 	<meta property="og:type" content="website" />
-	<meta property="og:image" content="{{AppUrl}}img/gitea-lg.png" />
+	<meta property="og:image" content="{{StaticUrlPrefix}}img/gitea-lg.png" />
 	<meta property="og:url" content="{{AppUrl}}" />
 	<meta property="og:description" content="{{MetaDescription}}">
 {{end}}
 {{if .IsSigned }}
 	{{ if ne .SignedUser.Theme "gitea" }}
-		<link rel="stylesheet" href="{{AppSubUrl}}/css/theme-{{.SignedUser.Theme}}.css">
+		<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{.SignedUser.Theme}}.css">
 	{{end}}
 {{else if ne DefaultTheme "gitea"}}
-	<link rel="stylesheet" href="{{AppSubUrl}}/css/theme-{{DefaultTheme}}.css">
+	<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css">
 {{end}}
 {{template "custom/header" .}}
 </head>
diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl
index 30316e7e5b074..2db2594422bf4 100644
--- a/templates/base/head_navbar.tmpl
+++ b/templates/base/head_navbar.tmpl
@@ -1,7 +1,7 @@
 <div class="ui container" id="navbar">
 	<div class="item brand" style="justify-content: space-between;">
 		<a href="{{AppSubUrl}}/">
-			<img class="ui mini image" src="{{AppSubUrl}}/img/gitea-sm.png">
+			<img class="ui mini image" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 		</a>
 		<div class="ui basic icon button mobile-only" id="navbar-expand-toggle">
 			<i class="sidebar icon"></i>
diff --git a/templates/home.tmpl b/templates/home.tmpl
index fa48cdc1b60ba..6fbc7678e919b 100644
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -3,7 +3,7 @@
 	<div class="ui stackable middle very relaxed page grid">
 		<div class="sixteen wide center aligned centered column">
 			<div>
-				<img class="logo" src="{{AppSubUrl}}/img/gitea-lg.png" />
+				<img class="logo" src="{{StaticUrlPrefix}}/img/gitea-lg.png" />
 			</div>
 			<div class="hero">
 				<h1 class="ui icon header title">

From 42f964fd181dbb8b139808b9be623470d4f0e40f Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Sun, 14 Jul 2019 21:29:50 +0800
Subject: [PATCH 2/9] add cors support for static resources

---
 routers/routes/routes.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index c81d56064c3d1..27260baf0461f 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -38,6 +38,7 @@ import (
 	"github.com/go-macaron/binding"
 	"github.com/go-macaron/cache"
 	"github.com/go-macaron/captcha"
+	"github.com/go-macaron/cors"
 	"github.com/go-macaron/csrf"
 	"github.com/go-macaron/i18n"
 	"github.com/go-macaron/session"
@@ -131,6 +132,9 @@ func NewMacaron() *macaron.Macaron {
 	if setting.Protocol == setting.FCGI {
 		m.SetURLPrefix(setting.AppSubURL)
 	}
+	if setting.EnableCORS {
+		m.Use(cors.CORS(setting.CORSConfig))
+	}
 	m.Use(public.Custom(
 		&public.Options{
 			SkipLogging:  setting.DisableRouterLog,

From 219cec500d6c462c4c50473c28d58676c6504ef1 Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Mon, 19 Aug 2019 01:00:16 +0200
Subject: [PATCH 3/9] [assets] work on the migration to configurable url for
 assets

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 templates/admin/hook_new.tmpl             | 12 ++--
 templates/base/footer.tmpl                |  4 +-
 templates/org/settings/hook_new.tmpl      | 14 ++---
 templates/pwa/manifest_json.tmpl          | 10 +--
 templates/pwa/serviceworker_js.tmpl       | 76 +++++++++++------------
 templates/repo/settings/webhook/list.tmpl | 14 ++---
 templates/repo/settings/webhook/new.tmpl  | 14 ++---
 templates/repo/view_file.tmpl             |  2 +-
 templates/status/404.tmpl                 |  2 +-
 templates/status/500.tmpl                 |  2 +-
 templates/swagger/ui.tmpl                 | 10 +--
 11 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/templates/admin/hook_new.tmpl b/templates/admin/hook_new.tmpl
index 457c9cde45397..3c0fc17826a91 100644
--- a/templates/admin/hook_new.tmpl
+++ b/templates/admin/hook_new.tmpl
@@ -11,17 +11,17 @@
 			{{end}}
 			<div class="ui right">
 				{{if eq .HookType "gitea"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/gitea-sm.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 				{{else if eq .HookType "gogs"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/gogs.ico">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
 				{{else if eq .HookType "slack"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/slack.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
 				{{else if eq .HookType "discord"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/discord.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
 				{{else if eq .HookType "dingtalk"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/dingtalk.ico">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
 				{{else if eq .HookType "msteams"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/msteams.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
 				{{end}}
 			</div>
 		</h4>
diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl
index 802175ce7e6c9..7185b20377796 100644
--- a/templates/base/footer.tmpl
+++ b/templates/base/footer.tmpl
@@ -26,7 +26,7 @@
 {{if .RequireGitGraph}}
 	<!-- graph -->
 	<script src="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js"></script>
-	<script src="{{AppSubUrl}}/js/draw.js"></script>
+	<script src="{{StaticUrlPrefix}}/js/draw.js"></script>
 {{end}}
 
 <!-- Third-party libraries -->
@@ -121,7 +121,7 @@
 
 	<!-- JavaScript -->
 	<script src="{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js"></script>
-	<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
+	<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>
 {{if .EnableHeatmap}}
 	<script src="{{StaticUrlPrefix}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
 	<script src="{{StaticUrlPrefix}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl
index 5db91011d8917..c83957dc6ad2b 100644
--- a/templates/org/settings/hook_new.tmpl
+++ b/templates/org/settings/hook_new.tmpl
@@ -10,19 +10,19 @@
 					{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}}
 					<div class="ui right">
 						{{if eq .HookType "gitea"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/gitea-sm.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 						{{else if eq .HookType "gogs"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/gogs.ico">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
 						{{else if eq .HookType "slack"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/slack.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
 						{{else if eq .HookType "discord"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/discord.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
 						{{else if eq .HookType "dingtalk"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/dingtalk.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.png">
 						{{else if eq .HookType "telegram"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/telegram.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/telegram.png">
 						{{else if eq .HookType "msteams"}}
-							<img class="img-13" src="{{AppSubUrl}}/img/msteams.png">
+							<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
 						{{end}}
 					</div>
 				</h4>
diff --git a/templates/pwa/manifest_json.tmpl b/templates/pwa/manifest_json.tmpl
index 557bee5d76171..793b42f2e1c89 100644
--- a/templates/pwa/manifest_json.tmpl
+++ b/templates/pwa/manifest_json.tmpl
@@ -3,22 +3,22 @@
     "name": "Gitea - Git with a cup of tea",
     "icons": [
       {
-        "src": "{{AppSubUrl}}/img/gitea-lg.png",
+        "src": "{{StaticUrlPrefix}}/img/gitea-lg.png",
         "type": "image/png",
         "sizes": "880x880"
       },
       {
-        "src": "{{AppSubUrl}}/img/gitea-sm.png",
+        "src": "{{StaticUrlPrefix}}/img/gitea-sm.png",
         "type": "image/png",
         "sizes": "120x120"
       },
       {
-        "src": "{{AppSubUrl}}/img/gitea-512.png",
+        "src": "{{StaticUrlPrefix}}/img/gitea-512.png",
         "type": "image/png",
         "sizes": "512x512"
       },
       {
-        "src": "{{AppSubUrl}}/img/gitea-192.png",
+        "src": "{{StaticUrlPrefix}}/img/gitea-192.png",
         "type": "image/png",
         "sizes": "192x192"
       }
@@ -28,4 +28,4 @@
     "background_color": "#FAFAFA",
     "display": "standalone",
     "theme_color": "{{ThemeColorMetaTag}}"
-  }
\ No newline at end of file
+  }
diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl
index ee96cd5f6832f..5a2756cf24392 100644
--- a/templates/pwa/serviceworker_js.tmpl
+++ b/templates/pwa/serviceworker_js.tmpl
@@ -1,55 +1,55 @@
 var STATIC_CACHE = 'static-cache-v1';
 var urlsToCache = [
   // js
-  '{{AppSubUrl}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js',
-  '{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1',
-  '{{AppSubUrl}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
-  '{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js',
-  '{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}',
-  '{{AppSubUrl}}/js/draw.js',
-  '{{AppSubUrl}}/vendor/plugins/clipboard/clipboard.min.js',
-  '{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.js',
-  '{{AppSubUrl}}/vendor/plugins/vue/vue.min.js',
-  '{{AppSubUrl}}/vendor/plugins/emojify/emojify.min.js',
-  '{{AppSubUrl}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
-  '{{AppSubUrl}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js',
-  '{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.js',
-  '{{AppSubUrl}}/vendor/plugins/highlight/highlight.pack.js',
-  '{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.js',
-  '{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js',
-  '{{AppSubUrl}}/vendor/plugins/codemirror/addon/mode/loadmode.js',
-  '{{AppSubUrl}}/vendor/plugins/codemirror/mode/meta.js',
-  '{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
+  '{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js',
+  '{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
+  '{{StaticUrlPrefix}}/js/draw.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/highlight/highlight.pack.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js',
+  '{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js',
 
   // css
-  '{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css',
-  '{{AppSubUrl}}/vendor/assets/octicons/octicons.min.css',
-  '{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.css',
-  '{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.css',
-  '{{AppSubUrl}}/vendor/plugins/tribute/tribute.css',
-  '{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.css',
-  '{{AppSubUrl}}/css/index.css?v={{MD5 AppVer}}',
-  '{{AppSubUrl}}/vendor/plugins/highlight/github.css',
-  '{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css',
-  '{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css',
-  '{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.css',
+  '{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css',
+  '{{StaticUrlPrefix}}/vendor/assets/octicons/octicons.min.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.css',
+  '{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}',
+  '{{StaticUrlPrefix}}/vendor/plugins/highlight/github.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css',
+  '{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.css',
 {{if .IsSigned }}
 	{{ if ne .SignedUser.Theme "gitea" }}
-		'{{AppSubUrl}}/css/theme-{{.SignedUser.Theme}}.css',
+		'{{StaticUrlPrefix}}/css/theme-{{.SignedUser.Theme}}.css',
 	{{end}}
 {{else if ne DefaultTheme "gitea"}}
-	'{{AppSubUrl}}/css/theme-{{DefaultTheme}}.css',
+	'{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css',
 {{end}}
 
   // img
-  '{{AppSubUrl}}/img/gitea-sm.png',
-  '{{AppSubUrl}}/img/gitea-lg.png',
+  '{{StaticUrlPrefix}}/img/gitea-sm.png',
+  '{{StaticUrlPrefix}}/img/gitea-lg.png',
 
   // fonts
-  '{{AppSubUrl}}/vendor/plugins/semantic/themes/default/assets/fonts/icons.woff2',
-  '{{AppSubUrl}}/vendor/assets/octicons/octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6',
-  '{{AppSubUrl}}/vendor/assets/lato-fonts/lato-v14-latin-regular.woff2',
-  '{{AppSubUrl}}/vendor/assets/lato-fonts/lato-v14-latin-700.woff2'
+  '{{StaticUrlPrefix}}/vendor/plugins/semantic/themes/default/assets/fonts/icons.woff2',
+  '{{StaticUrlPrefix}}/vendor/assets/octicons/octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6',
+  '{{StaticUrlPrefix}}/vendor/assets/lato-fonts/lato-v14-latin-regular.woff2',
+  '{{StaticUrlPrefix}}/vendor/assets/lato-fonts/lato-v14-latin-700.woff2'
 ];
 
 self.addEventListener('install', function (event) {
diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl
index 8fdae45b1b1ba..d1784564dc5b0 100644
--- a/templates/repo/settings/webhook/list.tmpl
+++ b/templates/repo/settings/webhook/list.tmpl
@@ -6,25 +6,25 @@
 			<div class="ui blue tiny button">{{.i18n.Tr "repo.settings.add_webhook"}}</div>
 			<div class="menu">
 				<a class="item" href="{{.BaseLink}}/gitea/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/gitea-sm.png">Gitea
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/gitea-sm.png">Gitea
 				</a>
 				<a class="item" href="{{.BaseLink}}/gogs/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/gogs.ico">Gogs
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/gogs.ico">Gogs
 				</a>
 				<a class="item" href="{{.BaseLink}}/slack/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/slack.png">Slack
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/slack.png">Slack
 				</a>
 				<a class="item" href="{{.BaseLink}}/discord/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/discord.png">Discord
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/discord.png">Discord
 				</a>
 				<a class="item" href="{{.BaseLink}}/dingtalk/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/dingtalk.ico">Dingtalk
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/dingtalk.ico">Dingtalk
 				</a>
 				<a class="item" href="{{.BaseLink}}/telegram/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/telegram.png">Telegram
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/telegram.png">Telegram
 				</a>
 				<a class="item" href="{{.BaseLink}}/msteams/new">
-					<img class="img-10" src="{{AppSubUrl}}/img/msteams.png">Microsoft Teams
+					<img class="img-10" src="{{StaticUrlPrefix}}/img/msteams.png">Microsoft Teams
 				</a>
 			</div>
 		</div>
diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl
index 358827c0f8222..1d5d849738e9d 100644
--- a/templates/repo/settings/webhook/new.tmpl
+++ b/templates/repo/settings/webhook/new.tmpl
@@ -8,19 +8,19 @@
 			{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}}
 			<div class="ui right">
 				{{if eq .HookType "gitea"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/gitea-sm.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 				{{else if eq .HookType "gogs"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/gogs.ico">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
 				{{else if eq .HookType "slack"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/slack.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
 				{{else if eq .HookType "discord"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/discord.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
 				{{else if eq .HookType "dingtalk"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/dingtalk.ico">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
 				{{else if eq .HookType "telegram"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/telegram.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/telegram.png">
 				{{else if eq .HookType "msteams"}}
-					<img class="img-13" src="{{AppSubUrl}}/img/msteams.png">
+					<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
 				{{end}}
 			</div>
 		</h4>
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl
index 895a72aaee5b0..7085228c69848 100644
--- a/templates/repo/view_file.tmpl
+++ b/templates/repo/view_file.tmpl
@@ -63,7 +63,7 @@
 							<strong>{{.i18n.Tr "repo.audio_not_supported_in_browser"}}</strong>
 						</audio>
 					{{else if .IsPDFFile}}
-						<iframe width="100%" height="600px" src="{{AppSubUrl}}/vendor/plugins/pdfjs/web/viewer.html?file={{EscapePound $.RawFileLink}}"></iframe>
+						<iframe width="100%" height="600px" src="{{StaticUrlPrefix}}/vendor/plugins/pdfjs/web/viewer.html?file={{EscapePound $.RawFileLink}}"></iframe>
 					{{else}}
 						<a href="{{EscapePound $.RawFileLink}}" rel="nofollow" class="btn btn-gray btn-radius">{{.i18n.Tr "repo.file_view_raw"}}</a>
 					{{end}}
diff --git a/templates/status/404.tmpl b/templates/status/404.tmpl
index 8e6a013f03d14..f947602bf2c9d 100644
--- a/templates/status/404.tmpl
+++ b/templates/status/404.tmpl
@@ -1,7 +1,7 @@
 {{template "base/head" .}}
 {{if .IsRepo}}<div class="repository">{{template "repo/header" .}}</div>{{end}}
 <div class="ui container center">
-	<p style="margin-top: 100px"><img src="{{AppSubUrl}}/img/404.png" alt="404"/></p>
+	<p style="margin-top: 100px"><img src="{{StaticUrlPrefix}}/img/404.png" alt="404"/></p>
 	<div class="ui divider"></div>
 	<br>
 	{{if .ShowFooterVersion}}<p>Application Version: {{AppVer}}</p>{{end}}
diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl
index 2e01e8ac742c4..191e5929d8799 100644
--- a/templates/status/500.tmpl
+++ b/templates/status/500.tmpl
@@ -1,6 +1,6 @@
 {{template "base/head" .}}
 <div class="ui container center">
-	<p style="margin-top: 100px"><img src="{{AppSubUrl}}/img/500.png" alt="500"/></p>
+	<p style="margin-top: 100px"><img src="{{StaticUrlPrefix}}/img/500.png" alt="500"/></p>
 	<div class="ui divider"></div>
 	<br>
 	{{if .ErrorMsg}}<p>An error has occurred :</p>
diff --git a/templates/swagger/ui.tmpl b/templates/swagger/ui.tmpl
index 20d4f7f63ba58..0125ee4a19969 100644
--- a/templates/swagger/ui.tmpl
+++ b/templates/swagger/ui.tmpl
@@ -4,9 +4,9 @@
 <head>
 	<meta charset="UTF-8">
 	<title>Swagger UI</title>
-	<link rel="stylesheet" type="text/css" href="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui.css" >
-	<link rel="icon" type="image/png" href="{{AppSubUrl}}/vendor/assets/swagger-ui/favicon-32x32.png" sizes="32x32" />
-	<link rel="icon" type="image/png" href="{{AppSubUrl}}/vendor/assets/swagger-ui/favicon-16x16.png" sizes="16x16" />
+	<link rel="stylesheet" type="text/css" href="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui.css" >
+	<link rel="icon" type="image/png" href="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/favicon-32x32.png" sizes="32x32" />
+	<link rel="icon" type="image/png" href="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/favicon-16x16.png" sizes="16x16" />
 	<style>
 	html
 	{
@@ -65,8 +65,8 @@
 
 <div id="swagger-ui"></div>
 
-<script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script>
-<script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-standalone-preset.js"> </script>
+<script src="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script>
+<script src="{{StaticUrlPrefix}}/vendor/assets/swagger-ui/swagger-ui-standalone-preset.js"> </script>
 <script>
 
 window.onload = function() {

From f219cacd96c1d2ae3e9a393c2651a17ada48df0d Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Mon, 19 Aug 2019 01:35:50 +0200
Subject: [PATCH 4/9] [misc] fix whitespace

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 modules/templates/helper.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 9e1c2ab5e3a3b..e07725460ff47 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -109,12 +109,12 @@ func NewFuncMap() []template.FuncMap {
 			}
 			return str[start:end]
 		},
-		"EllipsisString":    base.EllipsisString,
-		"DiffTypeToStr":     DiffTypeToStr,
-		"DiffLineTypeToStr": DiffLineTypeToStr,
-		"Sha1":              Sha1,
-		"ShortSha":          base.ShortSha,
-		"MD5":               base.EncodeMD5,
+		"EllipsisString":        base.EllipsisString,
+		"DiffTypeToStr":         DiffTypeToStr,
+		"DiffLineTypeToStr":     DiffLineTypeToStr,
+		"Sha1":                  Sha1,
+		"ShortSha":              base.ShortSha,
+		"MD5":                   base.EncodeMD5,
 		"ActionContent2Commits": ActionContent2Commits,
 		"PathEscape":            url.PathEscape,
 		"EscapePound": func(str string) string {

From afd9218e5680f0091b20f9ee9ec74cadaa4d74ba Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Mon, 19 Aug 2019 13:06:30 +0200
Subject: [PATCH 5/9] [assets] fix the loading of the manifest.json

It is generated dynamically, and as such can not be served by the cdn.

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 templates/base/head.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index 658fb33a788d7..ae2b6b954d601 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -5,7 +5,7 @@
 	<meta name="viewport" content="width=device-width, initial-scale=1">
 	<meta http-equiv="x-ua-compatible" content="ie=edge">
 	<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
-	<link rel="manifest" href="{{StaticUrlPrefix}}/manifest.json" crossorigin="use-credentials">
+	<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
 
 	<script>
 		if ('serviceWorker' in navigator) {

From 743b2f769600a983f1698cdb9338a617d9136b98 Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Wed, 28 Aug 2019 12:12:07 +0200
Subject: [PATCH 6/9] Revert "add cors support for static resources"

This reverts commit 42f964fd181dbb8b139808b9be623470d4f0e40f

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 routers/routes/routes.go | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 1a577f46c69a9..2afd0dcce9fb7 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -135,9 +135,6 @@ func NewMacaron() *macaron.Macaron {
 	if setting.Protocol == setting.FCGI {
 		m.SetURLPrefix(setting.AppSubURL)
 	}
-	if setting.EnableCORS {
-		m.Use(cors.CORS(setting.CORSConfig))
-	}
 	m.Use(public.Custom(
 		&public.Options{
 			SkipLogging:  setting.DisableRouterLog,

From 4b1e3d82830cdc854ac795232933fdc47bde8ef1 Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Wed, 28 Aug 2019 12:50:23 +0200
Subject: [PATCH 7/9] [docs] add the STATIC_URL_PREFIX option

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 docs/content/doc/advanced/config-cheat-sheet.en-us.md | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index 252ceee733b2a..d2b50e2e1d222 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -116,6 +116,13 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
 - `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**:
    Overwrite the automatically generated public URL.
    This is useful if the internal and the external URL don't match (e.g. in Docker).
+- `STATIC_URL_PREFIX`: **\<empty\>**:
+   Overwrite this option to request static resources from a different URL.
+   This includes CSS files, images, JS files and web fonts.
+   Avatar images are dynamic resources and still served by gitea.
+   The option can be just a different path, as in `/static`, or another domain, as in `https://cdn.example.com`.
+   Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective.
+   The static files are located in the `public/` directory of the gitea source repository.
 - `HTTP_ADDR`: **0.0.0.0**: HTTP listen address.
    - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
      defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
@@ -515,4 +522,4 @@ Two special environment variables are passed to the render command:
 
 - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.
 - `SHOW_FOOTER_VERSION`: **true**: Show Gitea version information in the footer.
-- `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer.
\ No newline at end of file
+- `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer.

From 36e661e210d672e640e3c72a3667fafc0aab3cc0 Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Wed, 28 Aug 2019 15:28:21 +0200
Subject: [PATCH 8/9] [docs] reverse-proxy: nginx: add two setups for
 STATIC_URL_PREFIX

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 .../doc/usage/reverse-proxies.en-us.md        | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/docs/content/doc/usage/reverse-proxies.en-us.md b/docs/content/doc/usage/reverse-proxies.en-us.md
index 47a5b955729d5..55c8bb9710f79 100644
--- a/docs/content/doc/usage/reverse-proxies.en-us.md
+++ b/docs/content/doc/usage/reverse-proxies.en-us.md
@@ -44,6 +44,74 @@ server {
 
 Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
 
+##  Using Nginx as a reverse proxy and serve static resources directly
+We can tune the performance in splitting requests into categories static and dynamic. 
+
+CSS files, JavaScript files, images and web fonts are static content.
+The front page, a repository view or issue list is dynamic content.
+
+Nginx can serve static resources directly and proxy only the dynamic requests to gitea.
+Nginx is optimized for serving static content, while the proxying of large responses might be the opposite of that
+ (see https://serverfault.com/q/587386).
+
+Download a snap shot of the gitea source repository to `/path/to/gitea/`.
+
+We are only interested in the `public/` directory and you can delete the rest.
+
+Depending on the scale of your user base, you might want to split the traffic to two distinct servers,
+ or use a cdn for the static files.
+
+### using a single node and a single domain
+
+Set `[server] STATIC_URL_PREFIX = /_/static` in your configuration.
+
+```
+server {
+    listen 80;
+    server_name git.example.com;
+
+    location /_/static {
+        alias /path/to/gitea/public;
+    }
+
+    location / {
+        proxy_pass http://localhost:3000;
+    }
+}
+```
+
+### using two nodes and two domains
+
+Set `[server] STATIC_URL_PREFIX = http://cdn.example.com/gitea` in your configuration.
+
+```
+# application server running gitea
+server {
+    listen 80;
+    server_name git.example.com;
+
+    location / {
+        proxy_pass http://localhost:3000;
+    }
+}
+```
+
+```
+# static content delivery server
+server {
+    listen 80;
+    server_name cdn.example.com;
+
+    location /gitea {
+        alias /path/to/gitea/public;
+    }
+
+    location / {
+        return 404;
+    }
+}
+```
+
 ## Using Apache HTTPD as a reverse proxy
 
 If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):

From 6b625a0466d592d33ec960640e96aeb7b4d83513 Mon Sep 17 00:00:00 2001
From: Jakob Ackermann <das7pad@outlook.com>
Date: Wed, 16 Oct 2019 13:40:30 +0200
Subject: [PATCH 9/9] [assets] migrate the url of a new asset to the static url
 prefix

REF: f2a3abc683ad4b2177b7c7c6160a2c0b4316120a
Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
---
 templates/repo/migrating.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/repo/migrating.tmpl b/templates/repo/migrating.tmpl
index 34031d5653efc..0057325e914da 100644
--- a/templates/repo/migrating.tmpl
+++ b/templates/repo/migrating.tmpl
@@ -9,7 +9,7 @@
 					<div class="ui stackable middle very relaxed page grid">
 						<div id="repo_migrating" class="sixteen wide center aligned centered column" repo="{{.Repo.Repository.FullName}}">
 							<div>
-								<img src="{{AppSubUrl}}/img/loading.png"/>
+								<img src="{{StaticUrlPrefix}}/img/loading.png"/>
 							</div>
 						</div>
 					</div>