Skip to content

Commit

Permalink
feat: support encoding fs static serve
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Feb 28, 2024
1 parent 0fd7cd5 commit e6b84bc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
16 changes: 12 additions & 4 deletions middleware/static_embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"bytes"
"embed"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -109,20 +110,27 @@ type tarFS struct {
Prefix string
// tar file
File string
// embed fs
Embed *embed.FS
}

var _ StaticFile = (*tarFS)(nil)

// NewTarFS returns a new tar static fs
func NewTarFS(file string, prefix string) *tarFS {
func NewTarFS(file string) *tarFS {
return &tarFS{
Prefix: prefix,
File: file,
File: file,
}
}

func (t *tarFS) get(file string, includeContent bool) (bool, []byte, error) {
f, err := os.Open(t.File)
var f fs.File
var err error
if t.Embed != nil {
f, err = t.Embed.Open(t.File)
} else {
f, err = os.Open(t.File)
}
if err != nil {
return false, nil, err
}
Expand Down
32 changes: 25 additions & 7 deletions middleware/static_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ type (
}
)

type EncodingFsSelector func(*elton.Context) (string, StaticFile)

const (
// ErrStaticServeCategory static serve error category
ErrStaticServeCategory = "elton-static-serve"
Expand All @@ -93,6 +95,8 @@ const (
var (
// ErrStaticServeNotAllowQueryString not all query string
ErrStaticServeNotAllowQueryString = getStaticServeError("static serve not allow query string", http.StatusBadRequest)
// ErrStaticServeFsIsNil static fs is nil
ErrStaticServeFsIsNil = getStaticServeError("static fs is nil", http.StatusBadRequest)
// ErrStaticServeNotFound static file not found
ErrStaticServeNotFound = getStaticServeError("static file not found", http.StatusNotFound)
// ErrStaticServeOutOfPath file out of path
Expand Down Expand Up @@ -149,7 +153,7 @@ func generateETag(buf []byte) string {
return fmt.Sprintf(`"%x-%s"`, size, hash)
}

// NewDefaultStaticServe returns a new default static server milldeware using FS
// NewDefaultStaticServe returns a new default static server middleware using FS
func NewDefaultStaticServe(config StaticServeConfig) elton.Handler {
return NewStaticServe(&FS{}, config)
}
Expand All @@ -158,10 +162,7 @@ func toSeconds(d time.Duration) string {
return strconv.Itoa(int(d.Seconds()))
}

// NewStaticServe returns a new static serve middleware, suggest to set the MaxAge and SMaxAge for cache control for better performance.
// It will return an error if DenyDot is true and filename is start with '.'.
// It will return an error if DenyQueryString is true and the querystring is not empty.
func NewStaticServe(staticFile StaticFile, config StaticServeConfig) elton.Handler {
func NewEncodingStaticServe(config StaticServeConfig, selector EncodingFsSelector) elton.Handler {
cacheArr := []string{
"public",
}
Expand Down Expand Up @@ -221,6 +222,10 @@ func NewStaticServe(staticFile StaticFile, config StaticServeConfig) elton.Handl
if config.DenyQueryString && url.RawQuery != "" {
return ErrStaticServeNotAllowQueryString
}
encoding, staticFile := selector(c)
if staticFile == nil {
return ErrStaticServeFsIsNil
}
// 如果有配置目录的index文件
if config.IndexFile != "" {
fileInfo := staticFile.Stat(file)
Expand Down Expand Up @@ -284,11 +289,15 @@ func NewStaticServe(staticFile StaticFile, config StaticServeConfig) elton.Handl
}
fileBuf = buf
}
// set content encoding
if encoding != "" {
c.SetHeader(elton.HeaderContentEncoding, encoding)
}
for k, v := range config.Header {
c.AddHeader(k, v)
}
// 未设置cache control
// 或文件符合正则
// not set cache control
// or the file match no cache
if cacheControl == "" ||
(noCacheRegexp != nil && noCacheRegexp.MatchString(file)) {
c.NoCache()
Expand All @@ -309,3 +318,12 @@ func NewStaticServe(staticFile StaticFile, config StaticServeConfig) elton.Handl
return c.Next()
}
}

// NewStaticServe returns a new static serve middleware, suggest to set the MaxAge and SMaxAge for cache control for better performance.
// It will return an error if DenyDot is true and filename is start with '.'.
// It will return an error if DenyQueryString is true and the query string is not empty.
func NewStaticServe(staticFile StaticFile, config StaticServeConfig) elton.Handler {
return NewEncodingStaticServe(config, func(ctx *elton.Context) (string, StaticFile) {
return "", staticFile
})
}

0 comments on commit e6b84bc

Please sign in to comment.