refactor(web): move to provider pattern (#6838)

### Summary

move to provider pattern
This commit is contained in:
Vibhu Pandey 2025-01-17 20:03:21 +05:30 committed by GitHub
parent c92ef53e9c
commit fdcdbf021a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 129 additions and 91 deletions

View File

@ -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()

View File

@ -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
} }

View 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) {}

View 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)
}

View File

@ -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()

View File

@ -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)
} }