From 895d5fea41177e444c18f4fdc820fffa5f67d5bf Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sat, 9 Dec 2023 17:08:45 +0100 Subject: Add drafty skeleton --- pkg/server/errors.go | 1 + pkg/server/messages.go | 4 ++ pkg/server/server.go | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 pkg/server/errors.go create mode 100644 pkg/server/messages.go create mode 100644 pkg/server/server.go (limited to 'pkg/server') diff --git a/pkg/server/errors.go b/pkg/server/errors.go new file mode 100644 index 0000000..abb4e43 --- /dev/null +++ b/pkg/server/errors.go @@ -0,0 +1 @@ +package server diff --git a/pkg/server/messages.go b/pkg/server/messages.go new file mode 100644 index 0000000..50edded --- /dev/null +++ b/pkg/server/messages.go @@ -0,0 +1,4 @@ +package server + +type MessageNodeSubmission struct { +} diff --git a/pkg/server/server.go b/pkg/server/server.go new file mode 100644 index 0000000..2d10c4b --- /dev/null +++ b/pkg/server/server.go @@ -0,0 +1,106 @@ +package server + +import ( + "context" + "fmt" + "net" + "net/http" + "strings" + "time" +) + +const ( + EndpointAddChain = "/add-chain" + EndpointGetStatus = "/get-status" + + DefaultAddress = "localhost:2009" + DefaultConfigFile = "/home/rgdd/.config/silent-ct/config.json" // FIXME +) + +type Nodes []Node + +type Node struct { + Name string `json:"name"` + Secret string `json:"secret"` + Domains []string `json:"issues"` +} + +type Config struct { + Address string // hostname[:port] or unix:///path/to/file.sock + Nodes Nodes // Which nodes are trusted to issue what certificates +} + +type Server struct { + Config + http.Server + + unixSocket bool // true if listening with a unix socket + eventCh chan MessageNodeSubmission + errorCh chan error +} + +func New(cfg Config) (Server, error) { + mux := http.NewServeMux() + srv := Server{Config: cfg, Server: http.Server{Handler: mux}} + mux.HandleFunc(EndpointAddChain, func(w http.ResponseWriter, r *http.Request) { srv.addChain(w, r) }) + mux.HandleFunc(EndpointGetStatus, func(w http.ResponseWriter, r *http.Request) { srv.getStatus(w, r) }) + if len(srv.Address) == 0 { + srv.Config.Address = DefaultAddress + } + if strings.HasPrefix(srv.Config.Address, "unix://") { + srv.Config.Address = srv.Config.Address[7:] + srv.unixSocket = true + } + return srv, nil +} + +func (srv *Server) Run(ctx context.Context, submitCh chan MessageNodeSubmission, errorCh chan error) error { + srv.eventCh = submitCh + srv.errorCh = errorCh + network := "unix" + if !srv.unixSocket { + network = "tcp" + } + + listener, err := net.Listen(network, srv.Address) + if err != nil { + return fmt.Errorf("listen: %v", err) + } + defer listener.Close() + + exitErr := make(chan error, 1) + defer close(exitErr) + go func() { + exitErr <- srv.Serve(listener) + }() + + select { + case err := <-exitErr: + if err != nil && err != http.ErrServerClosed { + return fmt.Errorf("serve: %v", err) + } + case <-ctx.Done(): + tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := srv.Shutdown(tctx); err != nil { + return fmt.Errorf("shutdown: %v", err) + } + } + return nil +} + +func (srv *Server) getStatus(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Only HTTP GET method is allowed", http.StatusMethodNotAllowed) + return + } + fmt.Fprintf(w, "OK\n") +} + +func (srv *Server) addChain(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Only HTTP POST method is allowed", http.StatusMethodNotAllowed) + return + } + fmt.Fprintf(w, "TODO: HTTP POST /add-chain\n") +} -- cgit v1.2.3