Browse Source

embed: support registering user handlers

siddontang 9 years ago
parent
commit
86de0797e1
3 changed files with 25 additions and 6 deletions
  1. 7 0
      embed/config.go
  2. 1 0
      embed/etcd.go
  3. 17 6
      embed/serve.go

+ 7 - 0
embed/config.go

@@ -17,6 +17,7 @@ package embed
 import (
 import (
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
+	"net/http"
 	"net/url"
 	"net/url"
 	"strings"
 	"strings"
 
 
@@ -98,6 +99,12 @@ type Config struct {
 
 
 	// ForceNewCluster starts a new cluster even if previously started; unsafe.
 	// ForceNewCluster starts a new cluster even if previously started; unsafe.
 	ForceNewCluster bool `json:"force-new-cluster"`
 	ForceNewCluster bool `json:"force-new-cluster"`
+
+	// UserHandlers is for registering users handlers and only used for
+	// embedding etcd into other applications.
+	// The map key is the route path for the handler, and
+	// you must ensure it can't be conflicted with etcd's.
+	UserHandlers map[string]http.Handler `json:"-"`
 }
 }
 
 
 // configYAML holds the config suitable for yaml parsing
 // configYAML holds the config suitable for yaml parsing

+ 1 - 0
embed/etcd.go

@@ -277,6 +277,7 @@ func startClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
 				plog.Info("stopping listening for client requests on ", u.Host)
 				plog.Info("stopping listening for client requests on ", u.Host)
 			}
 			}
 		}()
 		}()
+		sctx.userHandlers = cfg.UserHandlers
 		sctxs[u.Host] = sctx
 		sctxs[u.Host] = sctx
 	}
 	}
 	return sctxs, nil
 	return sctxs, nil

+ 17 - 6
embed/serve.go

@@ -42,6 +42,8 @@ type serveCtx struct {
 
 
 	ctx    context.Context
 	ctx    context.Context
 	cancel context.CancelFunc
 	cancel context.CancelFunc
+
+	userHandlers map[string]http.Handler
 }
 }
 
 
 func newServeCtx() *serveCtx {
 func newServeCtx() *serveCtx {
@@ -72,9 +74,8 @@ func (sctx *serveCtx) serve(s *etcdserver.EtcdServer, tlscfg *tls.Config, handle
 			return err
 			return err
 		}
 		}
 
 
-		httpmux := http.NewServeMux()
-		httpmux.Handle("/v3alpha/", gwmux)
-		httpmux.Handle("/", handler)
+		httpmux := sctx.createMux(gwmux, handler)
+
 		srvhttp := &http.Server{
 		srvhttp := &http.Server{
 			Handler:  httpmux,
 			Handler:  httpmux,
 			ErrorLog: logger, // do not log user error
 			ErrorLog: logger, // do not log user error
@@ -100,9 +101,8 @@ func (sctx *serveCtx) serve(s *etcdserver.EtcdServer, tlscfg *tls.Config, handle
 
 
 		tlsl := tls.NewListener(m.Match(cmux.Any()), tlscfg)
 		tlsl := tls.NewListener(m.Match(cmux.Any()), tlscfg)
 		// TODO: add debug flag; enable logging when debug flag is set
 		// TODO: add debug flag; enable logging when debug flag is set
-		httpmux := http.NewServeMux()
-		httpmux.Handle("/v3alpha/", gwmux)
-		httpmux.Handle("/", handler)
+		httpmux := sctx.createMux(gwmux, handler)
+
 		srv := &http.Server{
 		srv := &http.Server{
 			Handler:   httpmux,
 			Handler:   httpmux,
 			TLSConfig: tlscfg,
 			TLSConfig: tlscfg,
@@ -170,3 +170,14 @@ func (sctx *serveCtx) registerGateway(opts []grpc.DialOption) (*gw.ServeMux, err
 	}
 	}
 	return gwmux, nil
 	return gwmux, nil
 }
 }
+
+func (sctx *serveCtx) createMux(gwmux *gw.ServeMux, handler http.Handler) *http.ServeMux {
+	httpmux := http.NewServeMux()
+	for path, h := range sctx.userHandlers {
+		httpmux.Handle(path, h)
+	}
+
+	httpmux.Handle("/v3alpha/", gwmux)
+	httpmux.Handle("/", handler)
+	return httpmux
+}