Documentation
¶
Overview ¶
Package server provides an embeddable S3-compatible HTTP server.
It exposes the go-faster/fs S3 implementation as a library: construct a storage backend (for example github.com/go-faster/fs/storagefs) and either build a bare http.Handler to mount into your own server, or use the Server type for a turnkey HTTP server with health checks, timeouts and graceful shutdown.
The package deliberately does not pull in any observability stack. Wrap the handler yourself (for example with otelhttp) via Config.WrapHandler or by wrapping the result of NewHandler.
Index ¶
Examples ¶
Constants ¶
const ( DefaultAddr = ":8080" DefaultReadTimeout = 30 * time.Second DefaultWriteTimeout = 30 * time.Second DefaultIdleTimeout = 120 * time.Second DefaultHealthPath = "/health" )
Default server configuration values.
Variables ¶
This section is empty.
Functions ¶
func HandlerFromService ¶
HandlerFromService returns the S3-compatible http.Handler for an already-constructed service. Use this to wrap or replace the default validation layer.
func NewHandler ¶
NewHandler returns the S3-compatible http.Handler for a storage backend, wiring the validation service and the request router. Mount it into your own http.Server or mux to embed the S3 API.
Example ¶
ExampleNewHandler demonstrates the low-level API: build a bare http.Handler for a storage backend and mount it into your own server or mux.
package main
import (
"fmt"
"log"
"net/http"
"net/http/httptest"
"github.com/go-faster/fs/server"
"github.com/go-faster/fs/storagemem"
)
func main() {
store := storagemem.New()
h := server.NewHandler(store)
// Mount under a prefix in your own mux.
mux := http.NewServeMux()
mux.Handle("/s3/", http.StripPrefix("/s3", h))
ts := httptest.NewServer(mux)
defer ts.Close()
// Create a bucket via the embedded S3 API.
req, _ := http.NewRequest(http.MethodPut, ts.URL+"/s3/example-bucket", http.NoBody)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer func() { _ = resp.Body.Close() }()
fmt.Println(resp.StatusCode)
}
Output: 200
Types ¶
type Config ¶
type Config struct {
// Storage is the backend used to serve S3 operations. Required.
Storage fs.Storage
// Addr is the TCP address to listen on. Defaults to DefaultAddr (":8080").
Addr string
// ReadTimeout, WriteTimeout and IdleTimeout configure the underlying
// http.Server. Zero values fall back to the Default* constants.
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
// HealthPath is the path serving a plaintext "OK" health check. Defaults to
// DefaultHealthPath ("/health"). Set to "-" to disable the health endpoint.
HealthPath string
// Buckets are created (if absent) before the server begins serving in
// ListenAndServe / Serve.
Buckets []string
// WrapHandler, if set, wraps the composed handler (health endpoint + S3
// router) before it is served. This is the injection point for
// observability or middleware, e.g. otelhttp.NewHandler or request logging.
WrapHandler func(http.Handler) http.Handler
}
Config configures a Server.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an embeddable S3-compatible HTTP server with health checks, timeouts and graceful shutdown.
Example ¶
ExampleServer demonstrates the high-level API: a turnkey server with a health endpoint, timeouts and graceful shutdown driven by a context.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/go-faster/fs/server"
"github.com/go-faster/fs/storagemem"
)
func main() {
store := storagemem.New()
srv, err := server.New(server.Config{
Storage: store,
Addr: "127.0.0.1:0", // ephemeral port
Buckets: []string{"example-bucket"},
HealthPath: "/health",
// WrapHandler is the injection point for observability or middleware,
// e.g. otelhttp.NewHandler(h, "s3") or a request logger.
})
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() { done <- srv.ListenAndServe(ctx) }()
// ... serve requests ...
time.Sleep(10 * time.Millisecond)
cancel() // trigger graceful shutdown
if err := <-done; err != nil {
log.Fatal(err)
}
fmt.Println("stopped cleanly")
}
Output: stopped cleanly
func New ¶
New builds a Server from cfg. Storage is required. Configuration defaults are applied for any zero-valued fields.
func (*Server) HTTPServer ¶
HTTPServer returns the underlying *http.Server, allowing callers to set advanced fields (ConnContext, BaseContext, ErrorLog, TLSConfig, ...) before calling ListenAndServe or Serve. The Handler, Addr and timeout fields are managed by New and should not be replaced.
func (*Server) Handler ¶
Handler returns the composed http.Handler (S3 router, optional health endpoint and Config.WrapHandler). It can be mounted directly without using ListenAndServe.
func (*Server) ListenAndServe ¶
ListenAndServe pre-creates configured buckets, listens on Config.Addr and serves until ctx is canceled, then performs a graceful shutdown. It returns nil on a clean shutdown.