mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 02:44:59 +00:00
Add CORS support to handler.
This commit is contained in:
parent
3943e3e3cb
commit
1a9beb0916
8 changed files with 142 additions and 49 deletions
16
Gopkg.lock
generated
16
Gopkg.lock
generated
|
|
@ -82,6 +82,12 @@
|
|||
revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/handlers"
|
||||
packages = ["."]
|
||||
revision = "90663712d74cb411cbef281bc1e08c19d1a76145"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
|
|
@ -206,22 +212,14 @@
|
|||
[[projects]]
|
||||
name = "github.com/shirou/gopsutil"
|
||||
packages = [
|
||||
"cpu",
|
||||
"host",
|
||||
"internal/common",
|
||||
"mem",
|
||||
"net",
|
||||
"process"
|
||||
]
|
||||
revision = "bfe3c2e8f406bf352bc8df81f98c752224867349"
|
||||
version = "v2.17.11"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/shirou/w32"
|
||||
packages = ["."]
|
||||
revision = "bb4de0191aa41b5507caa14b0650cdbddcd9280b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/afero"
|
||||
|
|
@ -304,6 +302,6 @@
|
|||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "61a00007fe7398d958fc8668543d42293f1310f9f9b74c63ff96f5a892eab1e7"
|
||||
inputs-digest = "8f633d73d966ca439d2fdf3704a41d8ea59be8ed9a2cab0ab73de4b72c5772ba"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ func BuildServerFlags(cmd *cobra.Command, srv *server.Command) {
|
|||
// TLS
|
||||
SetTLSConfig(flags, &srv.Config.TLS.CertificatePath, &srv.Config.TLS.CertificateKeyPath, &srv.Config.TLS.SkipVerify)
|
||||
|
||||
// Handler
|
||||
flags.StringSliceVarP(&srv.Config.Handler.AllowedOrigins, "handler.allowed-origins", "", []string{"http://localhost/"}, "Comma separated list of allowed origin hosts (for CORS/WebUI).")
|
||||
|
||||
// Cluster
|
||||
flags.BoolVarP(&srv.Config.Cluster.Disabled, "cluster.disabled", "", srv.Config.Cluster.Disabled, "Disabled multi-node cluster communication (used for testing)")
|
||||
flags.BoolVarP(&srv.Config.Cluster.Coordinator, "cluster.coordinator", "", srv.Config.Cluster.Coordinator, "Host that will act as cluster coordinator during startup and resizing.")
|
||||
|
|
|
|||
35
handler.go
35
handler.go
|
|
@ -31,14 +31,16 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pilosa/pilosa/internal"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Handler represents an HTTP handler.
|
||||
type Handler struct {
|
||||
Router *mux.Router
|
||||
Handler http.Handler
|
||||
|
||||
FileSystem FileSystem
|
||||
|
||||
|
|
@ -48,6 +50,8 @@ type Handler struct {
|
|||
validators map[string]*queryValidationSpec
|
||||
|
||||
API *API
|
||||
|
||||
AllowedOrigins []string
|
||||
}
|
||||
|
||||
// externalPrefixFlag denotes endpoints that are intended to be exposed to clients.
|
||||
|
|
@ -67,15 +71,36 @@ type errorResponse struct {
|
|||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// HandlerOption is a functional option type for pilosa.Handler
|
||||
type HandlerOption func(s *Handler) error
|
||||
|
||||
func OptHandlerAllowedOrigins(origins []string) HandlerOption {
|
||||
return func(h *Handler) error {
|
||||
h.Handler = handlers.CORS(
|
||||
handlers.AllowedOrigins(origins),
|
||||
handlers.AllowedHeaders([]string{"Content-Type"}),
|
||||
)(h.Handler)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewHandler returns a new instance of Handler with a default logger.
|
||||
func NewHandler() *Handler {
|
||||
func NewHandler(opts ...HandlerOption) (*Handler, error) {
|
||||
handler := &Handler{
|
||||
FileSystem: NopFileSystem,
|
||||
Logger: NopLogger,
|
||||
}
|
||||
handler.Router = NewRouter(handler)
|
||||
handler.Handler = NewRouter(handler)
|
||||
handler.populateValidators()
|
||||
return handler
|
||||
|
||||
for _, opt := range opts {
|
||||
err := opt(handler)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "applying option")
|
||||
}
|
||||
}
|
||||
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
func (h *Handler) populateValidators() {
|
||||
|
|
@ -183,7 +208,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}()
|
||||
|
||||
t := time.Now()
|
||||
h.Router.ServeHTTP(w, r)
|
||||
h.Handler.ServeHTTP(w, r)
|
||||
dif := time.Since(t)
|
||||
|
||||
// Calculate per request StatsD metrics when the handler is fully configured.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import (
|
|||
)
|
||||
|
||||
func TestHandlerPanics(t *testing.T) {
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
bufLogger := test.NewBufferLogger()
|
||||
h.Handler.Logger = bufLogger
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ func TestHandler_NotFound(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ func TestHandler_Schema(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -139,7 +139,7 @@ func TestHandler_Status(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Cluster.SetState(pilosa.ClusterStateNormal)
|
||||
|
|
@ -158,7 +158,7 @@ func TestHandler_Status(t *testing.T) {
|
|||
func TestHandler_Info(t *testing.T) {
|
||||
s := test.NewServer()
|
||||
defer s.Close()
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, test.MustNewHTTPRequest("GET", "/info", nil))
|
||||
|
|
@ -173,7 +173,7 @@ func TestHandler_Info(t *testing.T) {
|
|||
func TestHandler_ClusterResizeAbort(t *testing.T) {
|
||||
|
||||
t.Run("No resize job", func(t *testing.T) {
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Cluster.SetState(pilosa.ClusterStateResizing)
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ func TestHandler_MaxSlices(t *testing.T) {
|
|||
hldr.MustCreateFragmentIfNotExists("i1", "f1", pilosa.ViewStandard, 0).MustSetBits(40, (0*SliceWidth)+2)
|
||||
hldr.MustCreateFragmentIfNotExists("i1", "f1", pilosa.ViewStandard, 0).MustSetBits(40, (0*SliceWidth)+8)
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -243,7 +243,7 @@ func TestHandler_MaxSlices_Inverse(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -260,7 +260,7 @@ func TestHandler_Query_Args_URL(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -288,7 +288,7 @@ func TestHandler_Query_Args_Protobuf(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -328,7 +328,7 @@ func TestHandler_Query_Args_Err(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ func TestHandler_Query_Args_Err(t *testing.T) {
|
|||
}
|
||||
func TestHandler_Query_Params_Err(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
test.NewHandler().ServeHTTP(w, test.MustNewHTTPRequest("POST", "/index/idx0/query?slices=0,1&db=sample", strings.NewReader("Bitmap(id=100)")))
|
||||
test.MustNewHandler().ServeHTTP(w, test.MustNewHTTPRequest("POST", "/index/idx0/query?slices=0,1&db=sample", strings.NewReader("Bitmap(id=100)")))
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status code: %d", w.Code)
|
||||
} else if body := w.Body.String(); body != `{"error":"db is not a valid argument"}`+"\n" {
|
||||
|
|
@ -355,7 +355,7 @@ func TestHandler_Query_Uint64_JSON(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -376,7 +376,7 @@ func TestHandler_Query_Uint64_Protobuf(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -406,7 +406,7 @@ func TestHandler_Query_Bitmap_JSON(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -439,7 +439,7 @@ func TestHandler_Query_Row_ColumnAttrs_JSON(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -462,7 +462,7 @@ func TestHandler_Query_Row_Protobuf(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -510,7 +510,7 @@ func TestHandler_Query_Row_ColumnAttrs_Protobuf(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -571,7 +571,7 @@ func TestHandler_Query_Pairs_JSON(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -595,7 +595,7 @@ func TestHandler_Query_Pairs_Protobuf(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -628,7 +628,7 @@ func TestHandler_Query_Err_JSON(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -649,7 +649,7 @@ func TestHandler_Query_Err_Protobuf(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
h.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) {
|
||||
|
|
@ -677,7 +677,7 @@ func TestHandler_Query_MethodNotAllowed(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -692,7 +692,7 @@ func TestHandler_Query_ErrParse(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -749,7 +749,7 @@ func TestHandler_DeleteFrame(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -1155,7 +1155,7 @@ func TestHandler_Version(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
|
||||
|
|
@ -1178,7 +1178,7 @@ func TestHandler_Fragment_Nodes(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(3)
|
||||
h.API.Cluster.ReplicaN = 2
|
||||
|
|
@ -1214,7 +1214,7 @@ func TestHandler_Expvars(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.API.Holder = hldr.Holder
|
||||
w := httptest.NewRecorder()
|
||||
|
|
@ -1237,7 +1237,7 @@ func TestHandler_RecalculateCaches(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
|
||||
|
|
@ -1253,7 +1253,7 @@ func TestHandler_WebUI(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
h := test.NewHandler()
|
||||
h := test.MustNewHandler()
|
||||
h.API.Holder = hldr.Holder
|
||||
h.API.Cluster = test.NewCluster(1)
|
||||
h.FileSystem = &statik.FileSystem{}
|
||||
|
|
@ -1276,3 +1276,41 @@ func TestHandler_WebUI(t *testing.T) {
|
|||
t.Fatalf("WebUI is not being served correctly.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CORS(t *testing.T) {
|
||||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
s := test.NewServer()
|
||||
s.Handler.API.Holder = hldr.Holder
|
||||
defer s.Close()
|
||||
|
||||
// No CORS config present, so should fail
|
||||
handler := test.MustNewHandler()
|
||||
|
||||
req := test.MustNewHTTPRequest("OPTIONS", "/index/foo/query", nil)
|
||||
req.Header.Add("Origin", "http://test/")
|
||||
req.Header.Add("Access-Control-Request-Method", "POST")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
result := w.Result()
|
||||
|
||||
// This handler does not support CORS, return Method Not Allowed (405)
|
||||
if result.StatusCode != 405 {
|
||||
t.Fatalf("CORS preflight status should be 405, but is %v", result.StatusCode)
|
||||
}
|
||||
|
||||
// CORS config should allow preflight response
|
||||
handler = test.MustNewHandler(pilosa.OptHandlerAllowedOrigins([]string{"http://test/"}))
|
||||
w = httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
result = w.Result()
|
||||
|
||||
if result.StatusCode != 200 {
|
||||
t.Fatalf("CORS preflight status should be 200, but is %v", result.StatusCode)
|
||||
}
|
||||
if w.HeaderMap["Access-Control-Allow-Origin"][0] != "http://test/" {
|
||||
t.Fatal("CORS header not present")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,11 +203,15 @@ func OptServerURI(uri *URI) ServerOption {
|
|||
|
||||
// NewServer returns a new instance of Server.
|
||||
func NewServer(opts ...ServerOption) (*Server, error) {
|
||||
handler, err := NewHandler()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "initializing handler")
|
||||
}
|
||||
s := &Server{
|
||||
closing: make(chan struct{}),
|
||||
Cluster: NewCluster(),
|
||||
Holder: NewHolder(),
|
||||
handler: NewHandler(),
|
||||
handler: handler,
|
||||
Broadcaster: NopBroadcaster,
|
||||
BroadcastReceiver: NopBroadcastReceiver,
|
||||
diagnostics: NewDiagnosticsCollector(DefaultDiagnosticServer),
|
||||
|
|
|
|||
|
|
@ -57,6 +57,11 @@ type Config struct {
|
|||
// Verbose toggles verbose logging which can be useful for debugging.
|
||||
Verbose bool `toml:"verbose"`
|
||||
|
||||
// HTTP Handler options
|
||||
Handler struct {
|
||||
AllowedOrigins []string `toml:"allowed-origins"`
|
||||
}
|
||||
|
||||
// TLS
|
||||
TLS TLSConfig
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,10 @@ func (m *Command) SetupServer() error {
|
|||
}
|
||||
m.logger.Printf("%s %s, build time %s\n", productName, pilosa.Version, pilosa.BuildTime)
|
||||
|
||||
handler := pilosa.NewHandler()
|
||||
handler, err := pilosa.NewHandler(pilosa.OptHandlerAllowedOrigins(m.Config.Handler.AllowedOrigins))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "wrapping handler")
|
||||
}
|
||||
handler.Logger = m.logger
|
||||
handler.FileSystem = &statik.FileSystem{}
|
||||
handler.API = pilosa.NewAPI()
|
||||
|
|
|
|||
|
|
@ -36,9 +36,13 @@ type Handler struct {
|
|||
}
|
||||
|
||||
// NewHandler returns a new instance of Handler.
|
||||
func NewHandler() *Handler {
|
||||
func NewHandler(opts ...pilosa.HandlerOption) (*Handler, error) {
|
||||
handler, err := pilosa.NewHandler(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h := &Handler{
|
||||
Handler: pilosa.NewHandler(),
|
||||
Handler: handler,
|
||||
}
|
||||
h.API = pilosa.NewAPI()
|
||||
h.Handler.API = h.API
|
||||
|
|
@ -47,6 +51,15 @@ func NewHandler() *Handler {
|
|||
// Handler test messages can no-op.
|
||||
h.API.Broadcaster = pilosa.NopBroadcaster
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// MustNewHandler returns a new instance of Handler.
|
||||
func MustNewHandler(opts ...pilosa.HandlerOption) *Handler {
|
||||
h, err := NewHandler(opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
|
|
@ -70,8 +83,12 @@ type Server struct {
|
|||
|
||||
// NewServer returns a test server running on a random port.
|
||||
func NewServer() *Server {
|
||||
handler, err := NewHandler()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s := &Server{
|
||||
Handler: NewHandler(),
|
||||
Handler: handler,
|
||||
}
|
||||
s.Server = httptest.NewServer(s.Handler.Handler)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue