splitted the go1.16 featured function to its own file and added an Wrapper for phuslu/log for pgx
Dieser Commit ist enthalten in:
Ursprung
dceb47069e
Commit
9e63f58de6
|
@ -1,77 +1,36 @@
|
||||||
package funcs
|
package funcs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"context"
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v4"
|
||||||
"github.com/phuslu/log"
|
"github.com/phuslu/log"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func headheader(f fs.File, c *gin.Context) (nocontent bool) {
|
//PGXLogger is an struct to intergrate the Logger Interface of pgx
|
||||||
stats, err := f.Stat()
|
type PGXLogger struct{}
|
||||||
if c.Request.Method == "HEAD" {
|
|
||||||
nocontent = true
|
// Log sends the logging data to phuslu/log
|
||||||
|
func (PGXLogger) Log(ctx context.Context, level pgx.LogLevel, msg string, data map[string]interface{}) {
|
||||||
|
var entry *log.Entry
|
||||||
|
switch level {
|
||||||
|
case pgx.LogLevelDebug:
|
||||||
|
entry = log.Debug()
|
||||||
|
case pgx.LogLevelError:
|
||||||
|
entry = log.Error()
|
||||||
|
case pgx.LogLevelInfo:
|
||||||
|
entry = log.Info()
|
||||||
|
case pgx.LogLevelTrace:
|
||||||
|
entry = log.Trace()
|
||||||
|
case pgx.LogLevelWarn:
|
||||||
|
entry = log.Warn()
|
||||||
|
default:
|
||||||
|
entry = log.Info()
|
||||||
}
|
}
|
||||||
if err != nil {
|
for key, value := range data {
|
||||||
log.Error().Err(err).Msg("Cant get info of file")
|
entry = entry.Interface(key, value)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
c.Writer.Header().Set("Last-Modified", stats.ModTime().Format(time.RFC1123))
|
entry.Msg(msg)
|
||||||
if t, err := time.Parse(time.RFC1123, c.GetHeader("If-Modified-Since")); stats.ModTime().After(t) && err == nil {
|
|
||||||
nocontent = true
|
|
||||||
}
|
|
||||||
if nocontent {
|
|
||||||
c.Status(http.StatusNotModified)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHandler(f fs.FS, name string) gin.HandlerFunc {
|
var _ pgx.Logger = PGXLogger{}
|
||||||
return func(c *gin.Context) {
|
|
||||||
content, err := f.Open(name)
|
|
||||||
if err != nil {
|
|
||||||
switch err {
|
|
||||||
case fs.ErrNotExist:
|
|
||||||
c.AbortWithStatus(404)
|
|
||||||
default:
|
|
||||||
c.AbortWithError(500, err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if headheader(content, c) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Status(200)
|
|
||||||
io.Copy(c.Writer, content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticFS is an Handler for Staticfiles that doesn't use globs and uses a fs.FS
|
|
||||||
func StaticFS(r gin.IRouter, files fs.FS) {
|
|
||||||
if files == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fns, err := fs.ReadDir(files, ".")
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("Error while reading this file.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, fn := range fns {
|
|
||||||
if fn.IsDir() {
|
|
||||||
sub, _ := fs.Sub(files, fn.Name())
|
|
||||||
StaticFS(r.Group("/"+fn.Name()), sub)
|
|
||||||
} else {
|
|
||||||
h := makeHandler(files, fn.Name())
|
|
||||||
if fn.Name() == "index.html" {
|
|
||||||
r.GET("/", h)
|
|
||||||
r.HEAD("/", h)
|
|
||||||
}
|
|
||||||
r.GET("/"+fn.Name(), h)
|
|
||||||
r.HEAD("/"+fn.Name(), h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// +build go1.16
|
||||||
|
|
||||||
|
package funcs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/phuslu/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func headheader(f fs.File, c *gin.Context) (nocontent bool) {
|
||||||
|
stats, err := f.Stat()
|
||||||
|
if c.Request.Method == "HEAD" {
|
||||||
|
nocontent = true
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Cant get info of file")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Writer.Header().Set("Last-Modified", stats.ModTime().Format(time.RFC1123))
|
||||||
|
if t, err := time.Parse(time.RFC1123, c.GetHeader("If-Modified-Since")); stats.ModTime().After(t) && err == nil {
|
||||||
|
nocontent = true
|
||||||
|
}
|
||||||
|
if nocontent {
|
||||||
|
c.Status(http.StatusNotModified)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeHandler(f fs.FS, name string) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
content, err := f.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
switch err {
|
||||||
|
case fs.ErrNotExist:
|
||||||
|
c.AbortWithStatus(404)
|
||||||
|
default:
|
||||||
|
c.AbortWithError(500, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if headheader(content, c) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Status(200)
|
||||||
|
io.Copy(c.Writer, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticFS is an Handler for Staticfiles that doesn't use globs and uses a fs.FS
|
||||||
|
func StaticFS(r gin.IRouter, files fs.FS) {
|
||||||
|
if files == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fns, err := fs.ReadDir(files, ".")
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error while reading this file.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, fn := range fns {
|
||||||
|
if fn.IsDir() {
|
||||||
|
sub, _ := fs.Sub(files, fn.Name())
|
||||||
|
StaticFS(r.Group("/"+fn.Name()), sub)
|
||||||
|
} else {
|
||||||
|
h := makeHandler(files, fn.Name())
|
||||||
|
if fn.Name() == "index.html" {
|
||||||
|
r.GET("/", h)
|
||||||
|
r.HEAD("/", h)
|
||||||
|
}
|
||||||
|
r.GET("/"+fn.Name(), h)
|
||||||
|
r.HEAD("/"+fn.Name(), h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build go1.16
|
||||||
|
|
||||||
package funcs_test
|
package funcs_test
|
||||||
|
|
||||||
import (
|
import (
|
Laden…
In neuem Issue referenzieren