From 6bd2b52ce2a4b9dcb8356bee6939d4bf6df50eae Mon Sep 17 00:00:00 2001 From: Christopher Wunder Date: Mon, 14 Jul 2025 01:00:57 +0200 Subject: [PATCH] Add configuration options Adds flexibility for host, port and directory where static files are read from. --- examples/{static => html}/hello-world.html | 0 examples/html/hello-world2.html | 11 +++ examples/main.go | 9 ++- pkg/statix/server.go | 78 ++++++++++++++++++++-- pkg/statix/server_test.go | 73 +++++++++++++++++++- 5 files changed, 163 insertions(+), 8 deletions(-) rename examples/{static => html}/hello-world.html (100%) create mode 100644 examples/html/hello-world2.html diff --git a/examples/static/hello-world.html b/examples/html/hello-world.html similarity index 100% rename from examples/static/hello-world.html rename to examples/html/hello-world.html diff --git a/examples/html/hello-world2.html b/examples/html/hello-world2.html new file mode 100644 index 0000000..eb9fef2 --- /dev/null +++ b/examples/html/hello-world2.html @@ -0,0 +1,11 @@ + + + + + + Hello World2 + + +

Hello, World2!

+ + diff --git a/examples/main.go b/examples/main.go index 053867b..ee1cb1c 100644 --- a/examples/main.go +++ b/examples/main.go @@ -6,7 +6,14 @@ import ( func main() { // Create a new server instance with the specified address - srv := statix.NewServer(":8080") + srv, err := statix.NewServer( + statix.WithPort(8080), + statix.WithStaticDir("./html"), + ) + + if err != nil { + panic(err) // Handle error appropriately + } // Start the server if err := srv.Start(); err != nil { diff --git a/pkg/statix/server.go b/pkg/statix/server.go index 45faf29..a16d37a 100644 --- a/pkg/statix/server.go +++ b/pkg/statix/server.go @@ -2,6 +2,8 @@ package server import ( + "errors" + "fmt" "log" "net/http" "path/filepath" @@ -13,16 +15,82 @@ type server struct { server http.Server } +type options struct { + host *string + port *int + staticDir *string +} + +type Option func(*options) error + +// WithHost sets the host for the server. +func WithHost(host string) Option { + return func(opts *options) error { + if host == "" { + return errors.New("host cannot be empty") // Empty host + } + opts.host = &host + return nil + } +} + +// WithPort sets the port for the server. +func WithPort(port int) Option { + return func(opts *options) error { + if port < 1 || port > 65535 { + return errors.New("invalid port number") // Invalid port number + } + opts.port = &port + return nil + } +} + +// WithStaticDir sets the directory to serve static files from. +func WithStaticDir(dir string) Option { + return func(opts *options) error { + if dir == "" { + return errors.New("static directory cannot be empty") // Empty directory path + } + opts.staticDir = &dir + return nil + } +} + // NewServer creates a new server instance with the specified address. -func NewServer(addr string) *server { - handler := http.DefaultServeMux +func NewServer(opts ...Option) (*server, error) { + // Apply options + var o options + for _, opt := range opts { + if err := opt(&o); err != nil { + return nil, err // Return error if option fails + } + } - handler.HandleFunc("/", staticFileHandler(defaultStaticDir)) + // Apply default options if not set + applyDefaultOptions(&o) + + handler := http.DefaultServeMux + handler.HandleFunc("/", staticFileHandler(*o.staticDir)) return &server{server: http.Server{ - Addr: addr, + Addr: fmt.Sprintf("%s:%d", *o.host, *o.port), Handler: handler, - }} + }}, nil +} + +func applyDefaultOptions(opts *options) { + if opts.host == nil { + defaultHost := "localhost" + opts.host = &defaultHost // Default host if not set + } + if opts.port == nil { + defaultPort := 8080 + opts.port = &defaultPort // Default port if not set + } + if opts.staticDir == nil { + defaultStaticDir := defaultStaticDir + opts.staticDir = &defaultStaticDir // Default static directory + } } func staticFileHandler(dir string) http.HandlerFunc { diff --git a/pkg/statix/server_test.go b/pkg/statix/server_test.go index f8672cc..8bbb042 100644 --- a/pkg/statix/server_test.go +++ b/pkg/statix/server_test.go @@ -8,8 +8,15 @@ import ( // TestNewServer tests the NewServer function. func TestNewServer(t *testing.T) { - addr := ":8080" - srv := NewServer(addr) + addr := "localhost:8080" + srv, err := NewServer( + WithPort(8080), + WithStaticDir("./static"), + ) + + if err != nil { + t.Fatalf("expected no error, got %v", err) + } if srv.server.Addr != addr { t.Errorf("expected server Addr %s, got %s", addr, srv.server.Addr) @@ -63,3 +70,65 @@ func TestStaticFileHandler(t *testing.T) { t.Errorf("expected status code 404, got %d", rr.Code) } } + +func TestWithHost(t *testing.T) { + opts := &options{} + host := "localhost" + + err := WithHost(host)(opts) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if opts.host == nil || *opts.host != host { + t.Errorf("expected host %s, got %v", host, opts.host) + } + + // Test empty host + err = WithHost("")(opts) + if err == nil || err.Error() != "host cannot be empty" { + t.Errorf("expected error for empty host, got %v", err) + } +} + +func TestWithPort(t *testing.T) { + opts := &options{} + port := 8080 + + err := WithPort(port)(opts) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if opts.port == nil || *opts.port != port { + t.Errorf("expected port %d, got %v", port, opts.port) + } + + // Test invalid ports + err = WithPort(0)(opts) + if err == nil || err.Error() != "invalid port number" { + t.Errorf("expected error for invalid port, got %v", err) + } + + err = WithPort(70000)(opts) + if err == nil || err.Error() != "invalid port number" { + t.Errorf("expected error for invalid port, got %v", err) + } +} + +func TestWithStaticDir(t *testing.T) { + opts := &options{} + dir := "/static" + + err := WithStaticDir(dir)(opts) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if opts.staticDir == nil || *opts.staticDir != dir { + t.Errorf("expected static directory %s, got %v", dir, opts.staticDir) + } + + // Test empty directory + err = WithStaticDir("")(opts) + if err == nil || err.Error() != "static directory cannot be empty" { + t.Errorf("expected error for empty directory, got %v", err) + } +}