Support custom mime type mapping for text files (#16304)
* Support custom mime type mapping for text files * Apply suggested change to routers/common/repo.go Co-authored-by: KN4CK3R <admin@oldschoolhack.me> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
This commit is contained in:
		
							parent
							
								
									9979983283
								
							
						
					
					
						commit
						ce286f9d9c
					
				
					 6 changed files with 43 additions and 9 deletions
				
			
		|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -62,3 +63,30 @@ func TestDownloadByIDMediaForSVGUsesSecureHeaders(t *testing.T) { | ||||||
| 	assert.Equal(t, "image/svg+xml", resp.HeaderMap.Get("Content-Type")) | 	assert.Equal(t, "image/svg+xml", resp.HeaderMap.Get("Content-Type")) | ||||||
| 	assert.Equal(t, "nosniff", resp.HeaderMap.Get("X-Content-Type-Options")) | 	assert.Equal(t, "nosniff", resp.HeaderMap.Get("X-Content-Type-Options")) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestDownloadRawTextFileWithoutMimeTypeMapping(t *testing.T) { | ||||||
|  | 	defer prepareTestEnv(t)() | ||||||
|  | 
 | ||||||
|  | 	session := loginUser(t, "user2") | ||||||
|  | 
 | ||||||
|  | 	req := NewRequest(t, "GET", "/user2/repo2/raw/branch/master/test.xml") | ||||||
|  | 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "text/plain; charset=utf-8", resp.HeaderMap.Get("Content-Type")) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestDownloadRawTextFileWithMimeTypeMapping(t *testing.T) { | ||||||
|  | 	defer prepareTestEnv(t)() | ||||||
|  | 	setting.MimeTypeMap.Map[".xml"] = "text/xml" | ||||||
|  | 	setting.MimeTypeMap.Enabled = true | ||||||
|  | 
 | ||||||
|  | 	session := loginUser(t, "user2") | ||||||
|  | 
 | ||||||
|  | 	req := NewRequest(t, "GET", "/user2/repo2/raw/branch/master/test.xml") | ||||||
|  | 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "text/xml; charset=utf-8", resp.HeaderMap.Get("Content-Type")) | ||||||
|  | 
 | ||||||
|  | 	delete(setting.MimeTypeMap.Map, ".xml") | ||||||
|  | 	setting.MimeTypeMap.Enabled = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | x<01>ŽK | ||||||
|  | Â0Eg™%Ÿ×":uä’ôŠ•¦J|‚îÞê¸çpËÖQ´ó~%
Ð9Ù„<C399>à<EFBFBD>‘G6GÎ ”ͦw(êžæE4}*<2A>íÙ{Ç)`YƆƒlŒeêMî—„JO¹Üš>޵¾õ©%ˆÞ^¿ÐÝ¿°L˜!]ÆN[v#E½6ÎU~/ÿúê0Zð<5A>îU'õgpJ5 | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1 +1 @@ | ||||||
| 205ac761f3326a7ebe416e8673760016450b5cec | 1032bbf17fbc0d9c95bb5418dabe8f8c99278700 | ||||||
|  |  | ||||||
|  | @ -64,16 +64,26 @@ func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) | ||||||
| 
 | 
 | ||||||
| 	st := typesniffer.DetectContentType(buf) | 	st := typesniffer.DetectContentType(buf) | ||||||
| 
 | 
 | ||||||
|  | 	mappedMimeType := "" | ||||||
|  | 	if setting.MimeTypeMap.Enabled { | ||||||
|  | 		fileExtension := strings.ToLower(filepath.Ext(name)) | ||||||
|  | 		mappedMimeType = setting.MimeTypeMap.Map[fileExtension] | ||||||
|  | 	} | ||||||
| 	if st.IsText() || ctx.QueryBool("render") { | 	if st.IsText() || ctx.QueryBool("render") { | ||||||
| 		cs, err := charset.DetectEncoding(buf) | 		cs, err := charset.DetectEncoding(buf) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err) | 			log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err) | ||||||
| 			cs = "utf-8" | 			cs = "utf-8" | ||||||
| 		} | 		} | ||||||
| 		ctx.Resp.Header().Set("Content-Type", "text/plain; charset="+strings.ToLower(cs)) | 		if mappedMimeType == "" { | ||||||
|  | 			mappedMimeType = "text/plain" | ||||||
|  | 		} | ||||||
|  | 		ctx.Resp.Header().Set("Content-Type", mappedMimeType+"; charset="+strings.ToLower(cs)) | ||||||
| 	} else { | 	} else { | ||||||
| 		ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") | 		ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") | ||||||
| 
 | 		if mappedMimeType != "" { | ||||||
|  | 			ctx.Resp.Header().Set("Content-Type", mappedMimeType) | ||||||
|  | 		} | ||||||
| 		if (st.IsImage() || st.IsPDF()) && (setting.UI.SVG.Enabled || !st.IsSvgImage()) { | 		if (st.IsImage() || st.IsPDF()) && (setting.UI.SVG.Enabled || !st.IsSvgImage()) { | ||||||
| 			ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name)) | 			ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name)) | ||||||
| 			if st.IsSvgImage() { | 			if st.IsSvgImage() { | ||||||
|  | @ -83,12 +93,6 @@ func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) | 			ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) | ||||||
| 			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) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue