From d0c4916fe9b2afaa273a2a7bc9782321a866ab9f Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 20 Jan 2014 09:59:33 -0800 Subject: [PATCH] refactor(server): move listener init out of server.go --- etcd.go | 16 +++++++-- server/listener.go | 39 ++++++++++++++++++++++ server/server.go | 77 ++++++------------------------------------- tests/server_utils.go | 9 +++-- 4 files changed, 68 insertions(+), 73 deletions(-) create mode 100644 server/listener.go diff --git a/etcd.go b/etcd.go index d24814840..96ab64957 100644 --- a/etcd.go +++ b/etcd.go @@ -18,6 +18,7 @@ package main import ( "fmt" + "net" "os" "runtime" "time" @@ -128,20 +129,29 @@ func main() { sConfig := server.ServerConfig{ Name: info.Name, URL: info.EtcdURL, - BindAddr: info.EtcdListenHost, CORS: corsInfo, } - s := server.New(sConfig, &tlsConfig, &info.EtcdTLS, ps, registry, store, &mb) + s := server.New(sConfig, ps, registry, store, &mb) if config.Trace() { s.EnableTracing() } + var sListener net.Listener + if tlsConfig.Scheme == "https" { + sListener, err = server.NewTLSListener(info.EtcdListenHost, info.EtcdTLS.CertFile, info.EtcdTLS.KeyFile) + } else { + sListener, err = server.NewListener(info.EtcdListenHost) + } + if err != nil { + panic(err) + } + ps.SetServer(s) // Run peer server in separate thread while the client server blocks. go func() { log.Fatal(ps.ListenAndServe(config.Snapshot, config.Peers)) }() - log.Fatal(s.ListenAndServe()) + log.Fatal(s.Serve(sListener)) } diff --git a/server/listener.go b/server/listener.go new file mode 100644 index 000000000..291d022ae --- /dev/null +++ b/server/listener.go @@ -0,0 +1,39 @@ +package server + +import ( + "crypto/tls" + "net" +) + +func NewListener(addr string) (net.Listener, error) { + if addr == "" { + addr = ":http" + } + l, e := net.Listen("tcp", addr) + if e != nil { + return nil, e + } + return l, nil +} + +func NewTLSListener(addr, keyFile, certFile string) (net.Listener, error) { + if addr == "" { + addr = ":https" + } + config := &tls.Config{} + config.NextProtos = []string{"http/1.1"} + + var err error + config.Certificates = make([]tls.Certificate, 1) + config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, err + } + + conn, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + return tls.NewListener(conn, config), nil +} diff --git a/server/server.go b/server/server.go index 99f440e66..c3bedfaf6 100644 --- a/server/server.go +++ b/server/server.go @@ -1,7 +1,6 @@ package server import ( - "crypto/tls" "encoding/json" "fmt" "net" @@ -24,10 +23,9 @@ import ( ) type ServerConfig struct { - Name string - URL string - BindAddr string - CORS *corsInfo + Name string + URL string + CORS *corsInfo } // This is the default implementation of the Server interface. @@ -36,31 +34,25 @@ type Server struct { Config ServerConfig peerServer *PeerServer registry *Registry - listener net.Listener store store.Store - tlsConf *TLSConfig - tlsInfo *TLSInfo router *mux.Router corsMiddleware *corsHTTPMiddleware metrics *metrics.Bucket + listener net.Listener } // Creates a new Server. -func New(sConfig ServerConfig, tlsConf *TLSConfig, tlsInfo *TLSInfo, peerServer *PeerServer, registry *Registry, store store.Store, mb *metrics.Bucket) *Server { +func New(sConfig ServerConfig, peerServer *PeerServer, registry *Registry, store store.Store, mb *metrics.Bucket) *Server { r := mux.NewRouter() cors := &corsHTTPMiddleware{r, sConfig.CORS} s := &Server{ Config: sConfig, Server: http.Server{ - Handler: cors, - TLSConfig: &tlsConf.Server, - Addr: sConfig.BindAddr, + Handler: cors, }, store: store, registry: registry, - tlsConf: tlsConf, - tlsInfo: tlsInfo, peerServer: peerServer, router: r, corsMiddleware: cors, @@ -198,59 +190,10 @@ func (s *Server) handleFunc(path string, f func(http.ResponseWriter, *http.Reque } // Start to listen and response etcd client command -func (s *Server) ListenAndServe() error { - log.Infof("etcd server [name %s, listen on %s, advertised url %s]", s.Config.Name, s.Server.Addr, s.Config.URL) - - if s.tlsConf.Scheme == "http" { - return s.listenAndServe() - } else { - return s.listenAndServeTLS(s.tlsInfo.CertFile, s.tlsInfo.KeyFile) - } -} - -// Overridden version of net/http added so we can manage the listener. -func (s *Server) listenAndServe() error { - addr := s.Server.Addr - if addr == "" { - addr = ":http" - } - l, e := net.Listen("tcp", addr) - if e != nil { - return e - } - s.listener = l - return s.Server.Serve(l) -} - -// Overridden version of net/http added so we can manage the listener. -func (s *Server) listenAndServeTLS(certFile, keyFile string) error { - addr := s.Server.Addr - if addr == "" { - addr = ":https" - } - config := &tls.Config{} - if s.Server.TLSConfig != nil { - *config = *s.Server.TLSConfig - } - if config.NextProtos == nil { - config.NextProtos = []string{"http/1.1"} - } - - var err error - config.Certificates = make([]tls.Certificate, 1) - config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return err - } - - conn, err := net.Listen("tcp", addr) - if err != nil { - return err - } - - tlsListener := tls.NewListener(conn, config) - s.listener = tlsListener - return s.Server.Serve(tlsListener) +func (s *Server) Serve(listener net.Listener) error { + log.Infof("etcd server [name %s, listen on %s, advertised url %s]", s.Config.Name, listener.Addr(), s.Config.URL) + s.listener = listener + return s.Server.Serve(listener) } // Stops the server. diff --git a/tests/server_utils.go b/tests/server_utils.go index 93f3795b9..2977224e9 100644 --- a/tests/server_utils.go +++ b/tests/server_utils.go @@ -43,10 +43,13 @@ func RunServer(f func(*server.Server)) { sConfig := server.ServerConfig{ Name: testName, URL: "http://"+testClientURL, - BindAddr: testClientURL, CORS: corsInfo, } - s := server.New(sConfig, &server.TLSConfig{Scheme: "http"}, &server.TLSInfo{}, ps, registry, store, nil) + s := server.New(sConfig, ps, registry, store, nil) + sListener, err := server.NewListener(testClientURL) + if err != nil { + panic(err) + } ps.SetServer(s) @@ -61,7 +64,7 @@ func RunServer(f func(*server.Server)) { // Start up etcd server. go func() { c <- true - s.ListenAndServe() + s.Serve(sListener) }() <-c