@@ -19,6 +19,9 @@ import (
1919 "code.gitea.io/gitea/modules/log"
2020)
2121
22+ var javascriptTypes = []string {"application/ecmascript" , "application/javascript" , "text/ecmascript" , "text/javascript" ,
23+ "text/jscript" , "text/livescript" }
24+
2225// ServeData download file from io.Reader
2326func ServeData (ctx * context.Context , name string , size int64 , reader io.Reader ) error {
2427 buf := make ([]byte , 1024 )
@@ -41,26 +44,44 @@ func ServeData(ctx *context.Context, name string, size int64, reader io.Reader)
4144 // Google Chrome dislike commas in filenames, so let's change it to a space
4245 name = strings .ReplaceAll (name , "," , " " )
4346
44- if base .IsTextFile (buf ) || ctx .QueryBool ("render" ) {
45- cs , err := charset .DetectEncoding (buf )
46- if err != nil {
47- log .Error ("Detect raw file %s charset failed: %v, using by default utf-8" , name , err )
48- cs = "utf-8"
47+ ct := base .DetectContentType (buf )
48+ matches := func (mimes []string ) bool {
49+ for _ , mime := range mimes {
50+ if strings .Contains (ct , mime ) {
51+ return true
52+ }
4953 }
50- ctx .Resp .Header ().Set ("Content-Type" , "text/plain; charset=" + strings .ToLower (cs ))
51- } else if base .IsImageFile (buf ) || base .IsPDFFile (buf ) {
54+ return false
55+ }
56+ if ct == "" {
57+ log .Error ("Detect raw file %s content type failed: %v, using by default text/plain" , name , err )
58+ ct = "text/plain"
59+ } else if matches (javascriptTypes ) {
60+ // Serve JavaScript files as plain text to prevent XSS attacks
61+ ct = "text/plain"
62+ }
63+
64+ if matches ([]string {"text/" }) || ctx .QueryBool ("render" ) {
65+ if ! strings .Contains (ct , "charset=" ) {
66+ cs , err := charset .DetectEncoding (buf )
67+ if err != nil {
68+ log .Error ("Detect raw file %s charset failed: %v, using by default utf-8" , name , err )
69+ cs = "utf-8"
70+ }
71+ ct += "; charset=" + cs
72+ }
73+ } else if matches ([]string {"image/" , "application/pdf" }) {
5274 ctx .Resp .Header ().Set ("Content-Disposition" , fmt .Sprintf (`inline; filename="%s"` , name ))
5375 ctx .Resp .Header ().Set ("Access-Control-Expose-Headers" , "Content-Disposition" )
54- if base .IsSVGImageFile (buf ) {
55- ctx .Resp .Header ().Set ("Content-Security-Policy" , "default-src 'none'; style-src 'unsafe-inline'; sandbox" )
56- ctx .Resp .Header ().Set ("X-Content-Type-Options" , "nosniff" )
57- ctx .Resp .Header ().Set ("Content-Type" , base .SVGMimeType )
58- }
5976 } else {
6077 ctx .Resp .Header ().Set ("Content-Disposition" , fmt .Sprintf (`attachment; filename="%s"` , name ))
6178 ctx .Resp .Header ().Set ("Access-Control-Expose-Headers" , "Content-Disposition" )
6279 }
6380
81+ ctx .Resp .Header ().Set ("Content-Type" , strings .ToLower (ct ))
82+ ctx .Resp .Header ().Set ("X-Content-Type-Options" , "nosniff" )
83+ ctx .Resp .Header ().Set ("Content-Security-Policy" , "default-src 'none'; style-src 'unsafe-inline'; sandbox" )
84+
6485 _ , err = ctx .Resp .Write (buf )
6586 if err != nil {
6687 return err
0 commit comments