github.com/in4it/ecs-deploy@v0.0.42-0.20240508120354-ed77ff16df25/ngserve/static.go (about)

     1  package ngserve
     2  
     3  // modified from https://github.com/gin-contrib/static/blob/master/static.go
     4  // to redirect "404 - not found" to Angular's index.html
     5  
     6  import (
     7  	"net/http"
     8  	"os"
     9  	"path"
    10  	"strings"
    11  
    12  	"github.com/gin-gonic/gin"
    13  )
    14  
    15  type ServeFileSystem interface {
    16  	http.FileSystem
    17  	Exists(prefix string, path string) bool
    18  }
    19  
    20  type localFileSystem struct {
    21  	http.FileSystem
    22  	root    string
    23  	indexes bool
    24  }
    25  
    26  func LocalFile(root string, indexes bool) *localFileSystem {
    27  	return &localFileSystem{
    28  		FileSystem: gin.Dir(root, indexes),
    29  		root:       root,
    30  		indexes:    indexes,
    31  	}
    32  }
    33  
    34  func (l *localFileSystem) Exists(prefix string, filepath string) bool {
    35  	if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
    36  		name := path.Join(l.root, p)
    37  		stats, err := os.Stat(name)
    38  		if err != nil {
    39  			return false
    40  		}
    41  		if !l.indexes && stats.IsDir() {
    42  			return false
    43  		}
    44  		return true
    45  	}
    46  	return false
    47  }
    48  
    49  // Static returns a middleware handler that serves static files in the given directory.
    50  func ServeWithDefault(urlPrefix string, fs ServeFileSystem, defaultFile string) gin.HandlerFunc {
    51  	fileserver := http.FileServer(fs)
    52  	if urlPrefix != "" {
    53  		fileserver = http.StripPrefix(urlPrefix, fileserver)
    54  	}
    55  	return func(c *gin.Context) {
    56  		if fs.Exists(urlPrefix, c.Request.URL.Path) {
    57  			fileserver.ServeHTTP(c.Writer, c.Request)
    58  			c.Abort()
    59  		} else {
    60  			if strings.HasPrefix(c.Request.URL.Path, urlPrefix) {
    61  				// doesn't exist, but matches files in directory
    62  				// serve default
    63  				http.ServeFile(c.Writer, c.Request, defaultFile)
    64  			}
    65  		}
    66  	}
    67  }