Add mimetype mapping settings (#15133)
* Fix APK's Content-Type header * Fix case sensitive comparison * Add custom mime type mapping for downloadable files * Add documentation for MIME type mapping * Rename download.mimetype.mapping configuration to repository.mimetype_mapping Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
		
							parent
							
								
									2f65c6b2f0
								
							
						
					
					
						commit
						d86d123322
					
				| @ -903,6 +903,15 @@ PATH = | ||||
| ;; - approved: only sign when merging an approved pr to a protected branch | ||||
| ;MERGES = pubkey, twofa, basesigned, commitssigned | ||||
| 
 | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;[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] | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
							
								
								
									
										31
									
								
								modules/setting/mime_type_map.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								modules/setting/mime_type_map.go
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
| 	} | ||||
| } | ||||
| @ -1177,4 +1177,5 @@ func NewServices() { | ||||
| 	newTaskService() | ||||
| 	NewQueueService() | ||||
| 	newProject() | ||||
| 	newMimeTypeMap() | ||||
| } | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user