summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--custom/conf/app.example.ini10
-rw-r--r--docs/content/doc/advanced/config-cheat-sheet.en-us.md9
-rw-r--r--modules/setting/mime_type_map.go31
-rw-r--r--modules/setting/setting.go1
-rw-r--r--routers/repo/download.go8
5 files changed, 58 insertions, 1 deletions
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 54e727f940..b1fe95e6e2 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -905,6 +905,15 @@ PATH =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;[repository.mimetype_mapping]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Custom MIME type mapping for downloadable files
+;.apk=application/vnd.android.package-archive
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[project]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -912,7 +921,6 @@ PATH =
;PROJECT_BOARD_BASIC_KANBAN_TYPE = To Do, In Progress, Done
;PROJECT_BOARD_BUG_TRIAGE_TYPE = Needs Triage, High Priority, Low Priority, Closed
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cors]
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 a37d06fab6..9bb790f4c9 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -143,6 +143,15 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `LOCAL_COPY_PATH`: **tmp/local-repo**: Path for temporary local repository copies. Defaults to `tmp/local-repo`
+## Repository - MIME type mapping (`repository.mimetype_mapping`)
+
+Configuration for set the expected MIME type based on file extensions of downloadable files. Configuration presents in key-value pairs and file extensions starts with leading `.`.
+
+The following configuration set `Content-Type: application/vnd.android.package-archive` header when downloading files with `.apk` file extension.
+```ini
+.apk=application/vnd.android.package-archive
+```
+
## CORS (`cors`)
- `ENABLED`: **false**: enable cors headers (disabled by default)
diff --git a/modules/setting/mime_type_map.go b/modules/setting/mime_type_map.go
new file mode 100644
index 0000000000..5c1fc7f71a
--- /dev/null
+++ b/modules/setting/mime_type_map.go
@@ -0,0 +1,31 @@
+// Copyright 2021 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 "strings"
+
+var (
+ // MimeTypeMap defines custom mime type mapping settings
+ MimeTypeMap = struct {
+ Enabled bool
+ Map map[string]string
+ }{
+ Enabled: false,
+ Map: map[string]string{},
+ }
+)
+
+func newMimeTypeMap() {
+ sec := Cfg.Section("repository.mimetype_mapping")
+ keys := sec.Keys()
+ m := make(map[string]string, len(keys))
+ for _, key := range keys {
+ m[strings.ToLower(key.Name())] = key.Value()
+ }
+ MimeTypeMap.Map = m
+ if len(keys) > 0 {
+ MimeTypeMap.Enabled = true
+ }
+}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index aef0d86700..4244b55939 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -1177,4 +1177,5 @@ func NewServices() {
newTaskService()
NewQueueService()
newProject()
+ newMimeTypeMap()
}
diff --git a/routers/repo/download.go b/routers/repo/download.go
index dafa62d0d9..4917c233ae 100644
--- a/routers/repo/download.go
+++ b/routers/repo/download.go
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"path"
+ "path/filepath"
"strings"
"code.gitea.io/gitea/modules/base"
@@ -18,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
// ServeData download file from io.Reader
@@ -61,6 +63,12 @@ func ServeData(ctx *context.Context, name string, size int64, reader io.Reader)
} else {
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name))
ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
+ if setting.MimeTypeMap.Enabled {
+ fileExtension := strings.ToLower(filepath.Ext(name))
+ if mimetype, ok := setting.MimeTypeMap.Map[fileExtension]; ok {
+ ctx.Resp.Header().Set("Content-Type", mimetype)
+ }
+ }
}
_, err = ctx.Resp.Write(buf)