add static embed fs

This commit is contained in:
kaedwen
2023-07-07 21:30:03 +02:00
parent a6f8afbd7d
commit 17a912e7f1
6 changed files with 228 additions and 47 deletions
+1 -1
View File
@@ -27,6 +27,6 @@ jobs:
- name: Prepare
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y make gcc libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install --yes make gcc libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
- name: Build
run: make build
+104
View File
@@ -0,0 +1,104 @@
package common
import (
"fmt"
"io"
"io/fs"
"mime"
"path/filepath"
"strings"
)
type ContentEncoding int
const (
PLAIN ContentEncoding = iota
GZ
BR
)
type StaticFileInfo struct {
Size int64
Reader io.ReadCloser
ExtraHeaders map[string]string
Mime string
}
type StaticSource interface {
Open(path string) (StaticSourceFile, error)
}
type StaticSourceFile interface {
Reader() io.ReadCloser
Stat() (fs.FileInfo, error)
}
type StaticHandler struct {
source StaticSource
index string
}
func NewStaticHandler(s StaticSource, i string) *StaticHandler {
return &StaticHandler{s, i}
}
func (h *StaticHandler) get(p string, encoding string) (*StaticFileInfo, error) {
mt := mime.TypeByExtension(filepath.Ext(p))
switch true {
case strings.Contains(encoding, "br"):
lt := p + ".br"
if o, err := h.source.Open(lt); err == nil {
if i, err := o.Stat(); err == nil && !i.IsDir() {
return &StaticFileInfo{
ExtraHeaders: map[string]string{
"Content-Encoding": "br",
"Vary": "Accept-Encoding",
},
Size: i.Size(),
Mime: mt,
Reader: o.Reader(),
}, nil
}
}
case strings.Contains(encoding, "gzip"):
lt := p + ".gz"
if o, err := h.source.Open(lt); err == nil {
if i, err := o.Stat(); err == nil && !i.IsDir() {
return &StaticFileInfo{
ExtraHeaders: map[string]string{
"Content-Encoding": "gzip",
},
Size: i.Size(),
Mime: mt,
Reader: o.Reader(),
}, nil
}
}
}
if o, err := h.source.Open(p); err == nil {
if i, err := o.Stat(); err == nil && !i.IsDir() {
return &StaticFileInfo{
Size: i.Size(),
Mime: mt,
Reader: o.Reader(),
}, nil
}
}
return nil, fmt.Errorf("path %s not found", p)
}
func (h *StaticHandler) Get(p string, encoding string) (*StaticFileInfo, error) {
if i, err := h.get(p, encoding); err == nil {
return i, nil
}
if i, err := h.get(h.index, encoding); err == nil {
return i, nil
}
return nil, fmt.Errorf("path %s and index not found", p)
}
+3 -46
View File
@@ -3,16 +3,12 @@ package server
import (
"context"
"fmt"
"mime"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/kaedwen/webrtc/pkg/common"
"github.com/kaedwen/webrtc/static"
"github.com/pion/webrtc/v3"
"go.uber.org/zap"
"nhooyr.io/websocket"
@@ -48,18 +44,8 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
engine := gin.Default()
engine.GET("/signaling/:id", h.signalingHandler)
if cfg.Http.StaticPath != nil {
engine.NoRoute(func(c *gin.Context) {
t := path.Join(*cfg.Http.StaticPath, c.Request.URL.Path)
if i, err := os.Stat(t); err == nil && !i.IsDir() {
h.compress(c, t)
return
}
h.compress(c, path.Join(*cfg.Http.StaticPath, "index.html"))
})
}
// static handler
static.SetupHandler(engine, cfg.Http)
// set out handler
h.Handler = engine
@@ -67,35 +53,6 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
return &h
}
func (h *HttpServer) compress(c *gin.Context, t string) {
encoding := c.Request.Header.Get("Accept-Encoding")
switch true {
case strings.Contains(encoding, "br"):
lt := t + ".br"
if i, err := os.Stat(lt); err == nil {
fmt.Println(i.Name())
c.Header("Content-Type", mime.TypeByExtension(filepath.Ext(t)))
c.Header("Content-Encoding", "br")
c.Header("Vary", "Accept-Encoding")
c.File(lt)
return
}
case strings.Contains(encoding, "gzip"):
lt := t + ".br"
if i, err := os.Stat(lt); err == nil {
fmt.Println(i.Name())
c.Header("Content-Type", mime.TypeByExtension(filepath.Ext(t)))
c.Header("Content-Encoding", "gzip")
c.File(lt)
return
}
}
fmt.Println(t)
c.File(t)
}
func (h *HttpServer) ListenAndServe(ctx context.Context, addr string) {
go func() {
+7
View File
@@ -0,0 +1,7 @@
package server
import "io"
type StaticHandler interface {
Get(path string) io.ReadCloser
}
+56
View File
@@ -0,0 +1,56 @@
//go:build !embed
package static
import (
"io"
"io/fs"
"net/http"
"os"
"path"
"github.com/gin-gonic/gin"
"github.com/kaedwen/webrtc/pkg/common"
)
type staticSourceFile struct {
target *os.File
}
func (ss *staticSourceFile) Reader() io.ReadCloser {
return ss.target
}
func (ss *staticSourceFile) Stat() (fs.FileInfo, error) {
return ss.target.Stat()
}
type staticDiskSource struct {
base string
}
func (s staticDiskSource) Open(p string) (common.StaticSourceFile, error) {
t, err := os.Open(path.Join(s.base, p))
if err != nil {
return nil, err
}
return &staticSourceFile{t}, nil
}
func SetupHandler(e *gin.Engine, cfg common.ConfigHTTP) {
if cfg.StaticPath != nil {
handler := common.NewStaticHandler(staticDiskSource{*cfg.StaticPath}, "index.html")
e.NoRoute(func(c *gin.Context) {
encoding := c.Request.Header.Get("Accept-Encoding")
p := c.Request.URL.Path
if i, err := handler.Get(p, encoding); err == nil {
c.DataFromReader(http.StatusOK, i.Size, i.Mime, i.Reader, i.ExtraHeaders)
return
}
c.Status(http.StatusNotFound)
})
}
}
+57
View File
@@ -0,0 +1,57 @@
//go:build embed
package static
import (
"embed"
"io"
"io/fs"
"net/http"
"path"
"github.com/gin-gonic/gin"
"github.com/kaedwen/webrtc/pkg/common"
)
//go:embed dist/*
var f embed.FS
type staticSourceFile struct {
target fs.File
}
func (ss *staticSourceFile) Reader() io.ReadCloser {
return ss.target
}
func (ss *staticSourceFile) Stat() (fs.FileInfo, error) {
return ss.target.Stat()
}
type staticSource struct {
base string
}
func (s staticSource) Open(p string) (common.StaticSourceFile, error) {
t, err := f.Open(path.Join(s.base, p))
if err != nil {
return nil, err
}
return &staticSourceFile{t}, nil
}
func SetupHandler(e *gin.Engine, _ common.ConfigHTTP) {
handler := common.NewStaticHandler(staticSource{"dist"}, "index.html")
e.NoRoute(func(c *gin.Context) {
encoding := c.Request.Header.Get("Accept-Encoding")
p := c.Request.URL.Path
if i, err := handler.Get(p, encoding); err == nil {
c.DataFromReader(http.StatusOK, i.Size, i.Mime, i.Reader, i.ExtraHeaders)
return
}
c.Status(http.StatusNotFound)
})
}