mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 03:55:57 +08:00
refactor(web): move to provider pattern (#6838)
### Summary move to provider pattern
This commit is contained in:
parent
c92ef53e9c
commit
fdcdbf021a
@ -351,7 +351,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) createPublicServer(apiHandler *api.APIHandler, web *web.Web) (*http.Server, error) {
|
func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*http.Server, error) {
|
||||||
|
|
||||||
r := baseapp.NewRouter()
|
r := baseapp.NewRouter()
|
||||||
|
|
||||||
|
@ -6,12 +6,13 @@ import (
|
|||||||
"go.signoz.io/signoz/pkg/cache/rediscache"
|
"go.signoz.io/signoz/pkg/cache/rediscache"
|
||||||
"go.signoz.io/signoz/pkg/config"
|
"go.signoz.io/signoz/pkg/config"
|
||||||
"go.signoz.io/signoz/pkg/web"
|
"go.signoz.io/signoz/pkg/web"
|
||||||
|
"go.signoz.io/signoz/pkg/web/routerweb"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SigNoz struct {
|
type SigNoz struct {
|
||||||
Cache cache.Cache
|
Cache cache.Cache
|
||||||
Web *web.Web
|
Web web.Web
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *config.Config, skipWebFrontend bool) (*SigNoz, error) {
|
func New(config *config.Config, skipWebFrontend bool) (*SigNoz, error) {
|
||||||
@ -25,7 +26,7 @@ func New(config *config.Config, skipWebFrontend bool) (*SigNoz, error) {
|
|||||||
cache = rediscache.New(&config.Cache.Redis)
|
cache = rediscache.New(&config.Cache.Redis)
|
||||||
}
|
}
|
||||||
|
|
||||||
web, err := web.New(zap.L(), config.Web)
|
web, err := routerweb.New(zap.L(), config.Web)
|
||||||
if err != nil && !skipWebFrontend {
|
if err != nil && !skipWebFrontend {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
22
pkg/web/noopweb/provider.go
Normal file
22
pkg/web/noopweb/provider.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package noopweb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"go.signoz.io/signoz/pkg/factory"
|
||||||
|
"go.signoz.io/signoz/pkg/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
type provider struct{}
|
||||||
|
|
||||||
|
func New(ctx context.Context, settings factory.ProviderSettings, config web.Config) (web.Web, error) {
|
||||||
|
return &provider{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *provider) AddToRouter(router *mux.Router) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *provider) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
|
93
pkg/web/routerweb/provider.go
Normal file
93
pkg/web/routerweb/provider.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package routerweb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"go.signoz.io/signoz/pkg/http/middleware"
|
||||||
|
"go.signoz.io/signoz/pkg/web"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
indexFileName string = "index.html"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Web struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
cfg web.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger *zap.Logger, cfg web.Config) (*Web, error) {
|
||||||
|
if logger == nil {
|
||||||
|
return nil, fmt.Errorf("cannot build web, logger is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err := os.Stat(cfg.Directory)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot access web directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := fi.IsDir()
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("web directory is not a directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err = os.Stat(filepath.Join(cfg.Directory, indexFileName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot access %q in web directory: %w", indexFileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.IsNotExist(err) || fi.IsDir() {
|
||||||
|
return nil, fmt.Errorf("%q does not exist", indexFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Web{
|
||||||
|
logger: logger.Named("go.signoz.io/pkg/web"),
|
||||||
|
cfg: cfg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (web *Web) AddToRouter(router *mux.Router) error {
|
||||||
|
cache := middleware.NewCache(7 * 24 * time.Hour)
|
||||||
|
err := router.PathPrefix(web.cfg.Prefix).
|
||||||
|
Handler(
|
||||||
|
http.StripPrefix(
|
||||||
|
web.cfg.Prefix,
|
||||||
|
cache.Wrap(http.HandlerFunc(web.ServeHTTP)),
|
||||||
|
),
|
||||||
|
).GetError()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to add web to router: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (web *Web) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
// Join internally call path.Clean to prevent directory traversal
|
||||||
|
path := filepath.Join(web.cfg.Directory, req.URL.Path)
|
||||||
|
|
||||||
|
// check whether a file exists or is a directory at the given path
|
||||||
|
fi, err := os.Stat(path)
|
||||||
|
if os.IsNotExist(err) || fi.IsDir() {
|
||||||
|
// file does not exist or path is a directory, serve index.html
|
||||||
|
http.ServeFile(rw, req, filepath.Join(web.cfg.Directory, indexFileName))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// if we got an error (that wasn't that the file doesn't exist) stating the
|
||||||
|
// file, return a 500 internal server error and stop
|
||||||
|
// TODO: Put down a crash html page here
|
||||||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, use http.FileServer to serve the static file
|
||||||
|
http.FileServer(http.Dir(web.cfg.Directory)).ServeHTTP(rw, req)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package routerweb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.signoz.io/signoz/pkg/web"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ func TestServeHttpWithoutPrefix(t *testing.T) {
|
|||||||
expected, err := io.ReadAll(fi)
|
expected, err := io.ReadAll(fi)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
web, err := New(zap.NewNop(), Config{Prefix: "/", Directory: filepath.Join("testdata")})
|
web, err := New(zap.NewNop(), web.Config{Prefix: "/", Directory: filepath.Join("testdata")})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
||||||
@ -87,7 +88,7 @@ func TestServeHttpWithPrefix(t *testing.T) {
|
|||||||
expected, err := io.ReadAll(fi)
|
expected, err := io.ReadAll(fi)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
web, err := New(zap.NewNop(), Config{Prefix: "/web", Directory: filepath.Join("testdata")})
|
web, err := New(zap.NewNop(), web.Config{Prefix: "/web", Directory: filepath.Join("testdata")})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
@ -1,94 +1,15 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.signoz.io/signoz/pkg/http/middleware"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ http.Handler = (*Web)(nil)
|
// Web is the interface that wraps the methods of the web package.
|
||||||
|
type Web interface {
|
||||||
const (
|
// AddToRouter adds the web routes to an existing router.
|
||||||
indexFileName string = "index.html"
|
AddToRouter(router *mux.Router) error
|
||||||
)
|
// ServeHTTP serves the web routes.
|
||||||
|
http.Handler
|
||||||
type Web struct {
|
|
||||||
logger *zap.Logger
|
|
||||||
cfg Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(logger *zap.Logger, cfg Config) (*Web, error) {
|
|
||||||
if logger == nil {
|
|
||||||
return nil, fmt.Errorf("cannot build web, logger is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
fi, err := os.Stat(cfg.Directory)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot access web directory: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ok := fi.IsDir()
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("web directory is not a directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
fi, err = os.Stat(filepath.Join(cfg.Directory, indexFileName))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot access %q in web directory: %w", indexFileName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if os.IsNotExist(err) || fi.IsDir() {
|
|
||||||
return nil, fmt.Errorf("%q does not exist", indexFileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Web{
|
|
||||||
logger: logger.Named("go.signoz.io/pkg/web"),
|
|
||||||
cfg: cfg,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (web *Web) AddToRouter(router *mux.Router) error {
|
|
||||||
cache := middleware.NewCache(7 * 24 * time.Hour)
|
|
||||||
err := router.PathPrefix(web.cfg.Prefix).
|
|
||||||
Handler(
|
|
||||||
http.StripPrefix(
|
|
||||||
web.cfg.Prefix,
|
|
||||||
cache.Wrap(http.HandlerFunc(web.ServeHTTP)),
|
|
||||||
),
|
|
||||||
).GetError()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to add web to router: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (web *Web) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
// Join internally call path.Clean to prevent directory traversal
|
|
||||||
path := filepath.Join(web.cfg.Directory, req.URL.Path)
|
|
||||||
|
|
||||||
// check whether a file exists or is a directory at the given path
|
|
||||||
fi, err := os.Stat(path)
|
|
||||||
if os.IsNotExist(err) || fi.IsDir() {
|
|
||||||
// file does not exist or path is a directory, serve index.html
|
|
||||||
http.ServeFile(rw, req, filepath.Join(web.cfg.Directory, indexFileName))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// if we got an error (that wasn't that the file doesn't exist) stating the
|
|
||||||
// file, return a 500 internal server error and stop
|
|
||||||
// TODO: Put down a crash html page here
|
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, use http.FileServer to serve the static file
|
|
||||||
http.FileServer(http.Dir(web.cfg.Directory)).ServeHTTP(rw, req)
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user