From 975da990a943ef40113e0ea02a5c46d398a9ed55 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Sat, 17 Oct 2020 15:33:56 +0100 Subject: [PATCH] rewrite api package --- api/{server => }/acme/acme.go | 0 api/{server => }/acme/autocert/autocert.go | 2 +- .../acme/autocert/autocert_test.go | 0 api/{server => }/acme/autocert/cache.go | 0 api/{server => }/acme/certmagic/certmagic.go | 2 +- api/{server => }/acme/certmagic/storage.go | 0 api/{server => }/acme/options.go | 0 api/api.go | 16 +++-- api/{server => }/http/http.go | 66 ++++++++----------- api/{server => }/options.go | 22 ++----- api/server/cors/cors.go | 44 ------------- api/server/http/http_test.go | 41 ------------ api/server/server.go | 15 ----- 13 files changed, 44 insertions(+), 164 deletions(-) rename api/{server => }/acme/acme.go (100%) rename api/{server => }/acme/autocert/autocert.go (96%) rename api/{server => }/acme/autocert/autocert_test.go (100%) rename api/{server => }/acme/autocert/cache.go (100%) rename api/{server => }/acme/certmagic/certmagic.go (97%) rename api/{server => }/acme/certmagic/storage.go (100%) rename api/{server => }/acme/options.go (100%) rename api/{server => }/http/http.go (57%) rename api/{server => }/options.go (72%) delete mode 100644 api/server/cors/cors.go delete mode 100644 api/server/http/http_test.go delete mode 100644 api/server/server.go diff --git a/api/server/acme/acme.go b/api/acme/acme.go similarity index 100% rename from api/server/acme/acme.go rename to api/acme/acme.go diff --git a/api/server/acme/autocert/autocert.go b/api/acme/autocert/autocert.go similarity index 96% rename from api/server/acme/autocert/autocert.go rename to api/acme/autocert/autocert.go index ab9be09a..a4a3900e 100644 --- a/api/server/acme/autocert/autocert.go +++ b/api/acme/autocert/autocert.go @@ -7,7 +7,7 @@ import ( "net" "os" - "github.com/micro/go-micro/v3/api/server/acme" + "github.com/micro/go-micro/v3/api/acme" "github.com/micro/go-micro/v3/logger" "golang.org/x/crypto/acme/autocert" ) diff --git a/api/server/acme/autocert/autocert_test.go b/api/acme/autocert/autocert_test.go similarity index 100% rename from api/server/acme/autocert/autocert_test.go rename to api/acme/autocert/autocert_test.go diff --git a/api/server/acme/autocert/cache.go b/api/acme/autocert/cache.go similarity index 100% rename from api/server/acme/autocert/cache.go rename to api/acme/autocert/cache.go diff --git a/api/server/acme/certmagic/certmagic.go b/api/acme/certmagic/certmagic.go similarity index 97% rename from api/server/acme/certmagic/certmagic.go rename to api/acme/certmagic/certmagic.go index 3a2803d3..e6b8ca32 100644 --- a/api/server/acme/certmagic/certmagic.go +++ b/api/acme/certmagic/certmagic.go @@ -8,7 +8,7 @@ import ( "time" "github.com/caddyserver/certmagic" - "github.com/micro/go-micro/v3/api/server/acme" + "github.com/micro/go-micro/v3/api/acme" "github.com/micro/go-micro/v3/logger" ) diff --git a/api/server/acme/certmagic/storage.go b/api/acme/certmagic/storage.go similarity index 100% rename from api/server/acme/certmagic/storage.go rename to api/acme/certmagic/storage.go diff --git a/api/server/acme/options.go b/api/acme/options.go similarity index 100% rename from api/server/acme/options.go rename to api/acme/options.go diff --git a/api/api.go b/api/api.go index 402c938b..1dac89ee 100644 --- a/api/api.go +++ b/api/api.go @@ -2,6 +2,7 @@ package api import ( "errors" + "net/http" "regexp" "strings" @@ -9,23 +10,24 @@ import ( "github.com/micro/go-micro/v3/server" ) -type Api interface { +// Gateway is an api gateway interface +type Gateway interface { // Initialise options Init(...Option) error // Get the options Options() Options - // Register a http handler + // Register an endpoint Register(*Endpoint) error - // Register a route + // Deregister a route Deregister(*Endpoint) error + // Register http handler + Handle(path string, hd http.Handler) + // Start serving requests + Serve() error // Implementation of api String() string } -type Options struct{} - -type Option func(*Options) error - // Endpoint is a mapping between an RPC method and HTTP endpoint type Endpoint struct { // RPC Method e.g. Greeter.Hello diff --git a/api/server/http/http.go b/api/http/http.go similarity index 57% rename from api/server/http/http.go rename to api/http/http.go index 90eed2fa..6eb35592 100644 --- a/api/server/http/http.go +++ b/api/http/http.go @@ -5,70 +5,62 @@ import ( "crypto/tls" "net" "net/http" - "os" "sync" - "github.com/gorilla/handlers" - "github.com/micro/go-micro/v3/api/server" - "github.com/micro/go-micro/v3/api/server/cors" + "github.com/micro/go-micro/v3/api" "github.com/micro/go-micro/v3/logger" ) type httpServer struct { mux *http.ServeMux - opts server.Options + opts api.Options mtx sync.RWMutex address string exit chan chan error } -func NewServer(address string, opts ...server.Option) server.Server { - var options server.Options +// NewGateway returns a new HTTP api gateway +func NewGateway(opts ...api.Option) api.Gateway { + var options api.Options for _, o := range opts { o(&options) } return &httpServer{ - opts: options, - mux: http.NewServeMux(), - address: address, - exit: make(chan chan error), + opts: options, + mux: http.NewServeMux(), + exit: make(chan chan error), } } -func (s *httpServer) Address() string { - s.mtx.RLock() - defer s.mtx.RUnlock() - return s.address -} - -func (s *httpServer) Init(opts ...server.Option) error { +func (s *httpServer) Init(opts ...api.Option) error { for _, o := range opts { o(&s.opts) } return nil } +func (s *httpServer) Options() api.Options { + return s.opts +} + +func (s *httpServer) Register(ep *api.Endpoint) error { return nil } +func (s *httpServer) Deregister(ep *api.Endpoint) error { return nil } + func (s *httpServer) Handle(path string, handler http.Handler) { - // TODO: move this stuff out to one place with ServeHTTP - - // apply the wrappers, e.g. auth - for _, wrapper := range s.opts.Wrappers { - handler = wrapper(handler) - } - - // wrap with cors - if s.opts.EnableCORS { - handler = cors.CombinedCORSHandler(handler) - } - - // wrap with logger - handler = handlers.CombinedLoggingHandler(os.Stdout, handler) - s.mux.Handle(path, handler) } +func (s *httpServer) Serve() error { + if err := s.Start(); err != nil { + return err + } + + <-s.exit + return nil +} + func (s *httpServer) Start() error { var l net.Listener var err error @@ -77,10 +69,10 @@ func (s *httpServer) Start() error { // should we check the address to make sure its using :443? l, err = s.opts.ACMEProvider.Listen(s.opts.ACMEHosts...) } else if s.opts.EnableTLS && s.opts.TLSConfig != nil { - l, err = tls.Listen("tcp", s.address, s.opts.TLSConfig) + l, err = tls.Listen("tcp", s.opts.Address, s.opts.TLSConfig) } else { // otherwise plain listen - l, err = net.Listen("tcp", s.address) + l, err = net.Listen("tcp", s.opts.Address) } if err != nil { return err @@ -90,10 +82,6 @@ func (s *httpServer) Start() error { logger.Infof("HTTP API Listening on %s", l.Addr().String()) } - s.mtx.Lock() - s.address = l.Addr().String() - s.mtx.Unlock() - go func() { if err := http.Serve(l, s.mux); err != nil { // temporary fix diff --git a/api/server/options.go b/api/options.go similarity index 72% rename from api/server/options.go rename to api/options.go index d6168a40..9e988828 100644 --- a/api/server/options.go +++ b/api/options.go @@ -1,37 +1,27 @@ -package server +package api import ( "crypto/tls" - "net/http" + "github.com/micro/go-micro/v3/api/acme" "github.com/micro/go-micro/v3/api/resolver" - "github.com/micro/go-micro/v3/api/server/acme" ) -type Option func(o *Options) - type Options struct { + Address string EnableACME bool - EnableCORS bool ACMEProvider acme.Provider EnableTLS bool ACMEHosts []string TLSConfig *tls.Config Resolver resolver.Resolver - Wrappers []Wrapper } -type Wrapper func(h http.Handler) http.Handler +type Option func(o *Options) -func WrapHandler(w ...Wrapper) Option { +func Address(a string) Option { return func(o *Options) { - o.Wrappers = append(o.Wrappers, w...) - } -} - -func EnableCORS(b bool) Option { - return func(o *Options) { - o.EnableCORS = b + o.Address = a } } diff --git a/api/server/cors/cors.go b/api/server/cors/cors.go deleted file mode 100644 index cd5b4079..00000000 --- a/api/server/cors/cors.go +++ /dev/null @@ -1,44 +0,0 @@ -package cors - -import ( - "net/http" -) - -// CombinedCORSHandler wraps a server and provides CORS headers -func CombinedCORSHandler(h http.Handler) http.Handler { - return corsHandler{h} -} - -type corsHandler struct { - handler http.Handler -} - -func (c corsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - SetHeaders(w, r) - - if r.Method == "OPTIONS" { - return - } - - c.handler.ServeHTTP(w, r) -} - -// SetHeaders sets the CORS headers -func SetHeaders(w http.ResponseWriter, r *http.Request) { - set := func(w http.ResponseWriter, k, v string) { - if v := w.Header().Get(k); len(v) > 0 { - return - } - w.Header().Set(k, v) - } - - if origin := r.Header.Get("Origin"); len(origin) > 0 { - set(w, "Access-Control-Allow-Origin", origin) - } else { - set(w, "Access-Control-Allow-Origin", "*") - } - - set(w, "Access-Control-Allow-Credentials", "true") - set(w, "Access-Control-Allow-Methods", "POST, PATCH, GET, OPTIONS, PUT, DELETE") - set(w, "Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, Namespace") -} diff --git a/api/server/http/http_test.go b/api/server/http/http_test.go deleted file mode 100644 index bbee35a0..00000000 --- a/api/server/http/http_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package http - -import ( - "fmt" - "io/ioutil" - "net/http" - "testing" -) - -func TestHTTPServer(t *testing.T) { - testResponse := "hello world" - - s := NewServer("localhost:0") - - s.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, testResponse) - })) - - if err := s.Start(); err != nil { - t.Fatal(err) - } - - rsp, err := http.Get(fmt.Sprintf("http://%s/", s.Address())) - if err != nil { - t.Fatal(err) - } - defer rsp.Body.Close() - - b, err := ioutil.ReadAll(rsp.Body) - if err != nil { - t.Fatal(err) - } - - if string(b) != testResponse { - t.Fatalf("Unexpected response, got %s, expected %s", string(b), testResponse) - } - - if err := s.Stop(); err != nil { - t.Fatal(err) - } -} diff --git a/api/server/server.go b/api/server/server.go deleted file mode 100644 index b1d63e35..00000000 --- a/api/server/server.go +++ /dev/null @@ -1,15 +0,0 @@ -// Package server provides an API gateway server which handles inbound requests -package server - -import ( - "net/http" -) - -// Server serves api requests -type Server interface { - Address() string - Init(opts ...Option) error - Handle(path string, handler http.Handler) - Start() error - Stop() error -}