code.gitea.io/gitea@v1.19.3/modules/public/serve_static.go (about)

     1  // Copyright 2016 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  //go:build bindata
     5  
     6  package public
     7  
     8  import (
     9  	"bytes"
    10  	"io"
    11  	"net/http"
    12  	"os"
    13  	"path/filepath"
    14  	"time"
    15  
    16  	"code.gitea.io/gitea/modules/timeutil"
    17  )
    18  
    19  // GlobalModTime provide a global mod time for embedded asset files
    20  func GlobalModTime(filename string) time.Time {
    21  	return timeutil.GetExecutableModTime()
    22  }
    23  
    24  func fileSystem(dir string) http.FileSystem {
    25  	return Assets
    26  }
    27  
    28  func Asset(name string) ([]byte, error) {
    29  	f, err := Assets.Open("/" + name)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	defer f.Close()
    34  	return io.ReadAll(f)
    35  }
    36  
    37  func AssetNames() []string {
    38  	realFS := Assets.(vfsgen۰FS)
    39  	results := make([]string, 0, len(realFS))
    40  	for k := range realFS {
    41  		results = append(results, k[1:])
    42  	}
    43  	return results
    44  }
    45  
    46  func AssetIsDir(name string) (bool, error) {
    47  	if f, err := Assets.Open("/" + name); err != nil {
    48  		return false, err
    49  	} else {
    50  		defer f.Close()
    51  		if fi, err := f.Stat(); err != nil {
    52  			return false, err
    53  		} else {
    54  			return fi.IsDir(), nil
    55  		}
    56  	}
    57  }
    58  
    59  // serveContent serve http content
    60  func serveContent(w http.ResponseWriter, req *http.Request, fi os.FileInfo, modtime time.Time, content io.ReadSeeker) {
    61  	encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding"))
    62  	if encodings.Contains("gzip") {
    63  		if cf, ok := fi.(*vfsgen۰CompressedFileInfo); ok {
    64  			rdGzip := bytes.NewReader(cf.GzipBytes())
    65  			// all static files are managed by Gitea, so we can make sure every file has the correct ext name
    66  			// then we can get the correct Content-Type, we do not need to do http.DetectContentType on the decompressed data
    67  			mimeType := detectWellKnownMimeType(filepath.Ext(fi.Name()))
    68  			if mimeType == "" {
    69  				mimeType = "application/octet-stream"
    70  			}
    71  			w.Header().Set("Content-Type", mimeType)
    72  			w.Header().Set("Content-Encoding", "gzip")
    73  			http.ServeContent(w, req, fi.Name(), modtime, rdGzip)
    74  			return
    75  		}
    76  	}
    77  
    78  	http.ServeContent(w, req, fi.Name(), modtime, content)
    79  	return
    80  }