add static embed fs
This commit is contained in:
1 parent
a6f8afbd7d
commit
17a912e7f1
6 files changed
+228
-47
No files matched your search
@@ -27,6 +27,6 @@ jobs:
|
|||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
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
|
- name: Build
|
||||||
run: make build
|
run: make build
|
||||||
@@ -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
@@ -3,16 +3,12 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/kaedwen/webrtc/pkg/common"
|
"github.com/kaedwen/webrtc/pkg/common"
|
||||||
|
"github.com/kaedwen/webrtc/static"
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"nhooyr.io/websocket"
|
"nhooyr.io/websocket"
|
||||||
@@ -48,18 +44,8 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
|
|||||||
engine := gin.Default()
|
engine := gin.Default()
|
||||||
engine.GET("/signaling/:id", h.signalingHandler)
|
engine.GET("/signaling/:id", h.signalingHandler)
|
||||||
|
|
||||||
if cfg.Http.StaticPath != nil {
|
// static handler
|
||||||
engine.NoRoute(func(c *gin.Context) {
|
static.SetupHandler(engine, cfg.Http)
|
||||||
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"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// set out handler
|
// set out handler
|
||||||
h.Handler = engine
|
h.Handler = engine
|
||||||
@@ -67,35 +53,6 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
|
|||||||
return &h
|
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) {
|
func (h *HttpServer) ListenAndServe(ctx context.Context, addr string) {
|
||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type StaticHandler interface {
|
||||||
|
Get(path string) io.ReadCloser
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in new issue
Block a user