embed: support registering user handlers

release-3.1
siddontang 2016-07-28 13:39:06 +08:00
parent ec5c5d9ddf
commit 86de0797e1
3 changed files with 25 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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 := sctx.createMux(gwmux, handler)
httpmux.Handle("/v3alpha/", gwmux)
httpmux.Handle("/", 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 := sctx.createMux(gwmux, handler)
httpmux.Handle("/v3alpha/", gwmux)
httpmux.Handle("/", 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
}