Update SetupAndServeHTTP

This commit is contained in:
Neil Alexander 2020-08-13 09:19:41 +01:00
parent 1f24d1afec
commit 96287ef5fd
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
22 changed files with 150 additions and 138 deletions

View file

@ -30,6 +30,8 @@ func main() {
intAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
appservice.AddInternalRoutes(base.InternalAPIMux, intAPI)
base.SetupAndServeHTTP(string(base.Cfg.AppServiceAPI.Bind), string(base.Cfg.AppServiceAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.AppServiceAPI.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -43,6 +43,8 @@ func main() {
rsAPI, eduInputAPI, asQuery, stateAPI, transactions.New(), fsAPI, userAPI, keyAPI, nil,
)
base.SetupAndServeHTTP(string(base.Cfg.ClientAPI.Bind), string(base.Cfg.ClientAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.ClientAPI.InternalAPI.Listen,
base.Cfg.ClientAPI.ExternalAPI.Listen,
)
}

View file

@ -28,6 +28,8 @@ func main() {
currentstateserver.AddInternalRoutes(base.InternalAPIMux, stateAPI)
base.SetupAndServeHTTP(string(base.Cfg.CurrentStateServer.Bind), string(base.Cfg.CurrentStateServer.Listen))
base.SetupAndServeHTTP(
base.Cfg.CurrentStateServer.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -33,6 +33,8 @@ func main() {
intAPI := eduserver.NewInternalAPI(base, cache.New(), base.UserAPIClient())
eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI)
base.SetupAndServeHTTP(string(base.Cfg.EDUServer.Bind), string(base.Cfg.EDUServer.Listen))
base.SetupAndServeHTTP(
base.Cfg.EDUServer.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -37,6 +37,8 @@ func main() {
rsAPI, fsAPI, base.EDUServerClient(), base.CurrentStateAPIClient(), keyAPI,
)
base.SetupAndServeHTTP(string(base.Cfg.FederationAPI.Bind), string(base.Cfg.FederationAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.FederationAPI.InternalAPI.Listen,
base.Cfg.FederationAPI.ExternalAPI.Listen,
)
}

View file

@ -35,6 +35,8 @@ func main() {
)
federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI)
base.SetupAndServeHTTP(string(base.Cfg.FederationSender.Bind), string(base.Cfg.FederationSender.Listen))
base.SetupAndServeHTTP(
base.Cfg.FederationSender.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -29,6 +29,8 @@ func main() {
keyserver.AddInternalRoutes(base.InternalAPIMux, intAPI)
base.SetupAndServeHTTP(string(base.Cfg.KeyServer.Bind), string(base.Cfg.KeyServer.Listen))
base.SetupAndServeHTTP(
base.Cfg.KeyServer.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -30,6 +30,8 @@ func main() {
mediaapi.AddPublicRoutes(base.PublicAPIMux, &base.Cfg.MediaAPI, userAPI, client)
base.SetupAndServeHTTP(string(base.Cfg.MediaAPI.Bind), string(base.Cfg.MediaAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.MediaAPI.InternalAPI.Listen,
base.Cfg.MediaAPI.ExternalAPI.Listen,
)
}

View file

@ -16,7 +16,7 @@ package main
import (
"flag"
"net/http"
"fmt"
"os"
"github.com/matrix-org/dendrite/appservice"
@ -25,7 +25,6 @@ import (
"github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/roomserver"
@ -33,8 +32,6 @@ import (
"github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus"
)
var (
@ -48,23 +45,25 @@ var (
func main() {
cfg := setup.ParseFlags(true)
httpAddr := config.HTTPAddress("http://" + *httpBindAddr)
httpsAddr := config.HTTPAddress("https://" + *httpsBindAddr)
if *enableHTTPAPIs {
// If the HTTP APIs are enabled then we need to update the Listen
// statements in the configuration so that we know where to find
// the API endpoints. They'll listen on the same port as the monolith
// itself.
addr := config.HTTPAddress("http://" + *httpBindAddr)
cfg.AppServiceAPI.InternalAPI.Connect = addr
cfg.ClientAPI.InternalAPI.Connect = addr
cfg.CurrentStateServer.InternalAPI.Connect = addr
cfg.EDUServer.InternalAPI.Connect = addr
cfg.FederationAPI.InternalAPI.Connect = addr
cfg.FederationSender.InternalAPI.Connect = addr
cfg.KeyServer.InternalAPI.Connect = addr
cfg.MediaAPI.InternalAPI.Connect = addr
cfg.RoomServer.InternalAPI.Connect = addr
cfg.ServerKeyAPI.InternalAPI.Connect = addr
cfg.SyncAPI.InternalAPI.Connect = addr
cfg.AppServiceAPI.InternalAPI.Connect = httpAddr
cfg.ClientAPI.InternalAPI.Connect = httpAddr
cfg.CurrentStateServer.InternalAPI.Connect = httpAddr
cfg.EDUServer.InternalAPI.Connect = httpAddr
cfg.FederationAPI.InternalAPI.Connect = httpAddr
cfg.FederationSender.InternalAPI.Connect = httpAddr
cfg.KeyServer.InternalAPI.Connect = httpAddr
cfg.MediaAPI.InternalAPI.Connect = httpAddr
cfg.RoomServer.InternalAPI.Connect = httpAddr
cfg.ServerKeyAPI.InternalAPI.Connect = httpAddr
cfg.SyncAPI.InternalAPI.Connect = httpAddr
}
base := setup.NewBaseDendrite(cfg, "Monolith", *enableHTTPAPIs)
@ -149,31 +148,42 @@ func main() {
}
monolith.AddAllPublicRoutes(base.PublicAPIMux)
httputil.SetupHTTPAPI(
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
&cfg.Global,
base.UseHTTPAPIs,
)
fmt.Printf("Public: %+v\n", base.PublicAPIMux)
fmt.Printf("Internal: %+v\n", base.InternalAPIMux)
/*
httputil.SetupHTTPAPI(
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
&cfg.Global,
base.UseHTTPAPIs,
)
*/
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
base.SetupAndServeHTTP(*httpBindAddr, *httpBindAddr)
base.SetupAndServeHTTP(
config.HTTPAddress(httpAddr), // internal API
config.HTTPAddress(httpAddr), // external API
)
}()
// Handle HTTPS if certificate and key are provided
if *certFile != "" && *keyFile != "" {
go func() {
serv := http.Server{
Addr: *httpsBindAddr,
WriteTimeout: setup.HTTPServerTimeout,
Handler: base.BaseMux,
}
_ = httpsAddr
/*
if *certFile != "" && *keyFile != "" {
go func() {
serv := http.Server{
Addr: config.HTTPAddress(httpsAddr).,
WriteTimeout: setup.HTTPServerTimeout,
Handler: base.BaseMux,
}
logrus.Info("Listening on ", serv.Addr)
logrus.Fatal(serv.ListenAndServeTLS(*certFile, *keyFile))
}()
}
logrus.Info("Listening on ", serv.Addr)
logrus.Fatal(serv.ListenAndServeTLS(*certFile, *keyFile))
}()
}
*/
// We want to block forever to let the HTTP and HTTPS handler serve the APIs
select {}

View file

@ -33,6 +33,8 @@ func main() {
rsAPI.SetFederationSenderAPI(fsAPI)
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI)
base.SetupAndServeHTTP(string(base.Cfg.RoomServer.Bind), string(base.Cfg.RoomServer.Listen))
base.SetupAndServeHTTP(
base.Cfg.RoomServer.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -29,5 +29,8 @@ func main() {
intAPI := serverkeyapi.NewInternalAPI(&base.Cfg.ServerKeyAPI, federation, base.Caches)
serverkeyapi.AddInternalRoutes(base.InternalAPIMux, intAPI, base.Caches)
base.SetupAndServeHTTP(string(base.Cfg.ServerKeyAPI.Bind), string(base.Cfg.ServerKeyAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.ServerKeyAPI.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -33,6 +33,8 @@ func main() {
base.PublicAPIMux, base.KafkaConsumer, userAPI, rsAPI, base.KeyServerHTTPClient(), base.CurrentStateAPIClient(),
federation, &cfg.SyncAPI)
base.SetupAndServeHTTP(string(base.Cfg.SyncAPI.Bind), string(base.Cfg.SyncAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.SyncAPI.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -31,5 +31,8 @@ func main() {
userapi.AddInternalRoutes(base.InternalAPIMux, userAPI)
base.SetupAndServeHTTP(string(base.Cfg.UserAPI.Bind), string(base.Cfg.UserAPI.Listen))
base.SetupAndServeHTTP(
base.Cfg.UserAPI.InternalAPI.Listen,
setup.NoExternalListener,
)
}

View file

@ -45,6 +45,11 @@ func main() {
flag.Parse()
if *tlsCertFile == "" && *tlsKeyFile == "" && *privateKeyFile == "" {
flag.Usage()
return
}
if *tlsCertFile != "" || *tlsKeyFile != "" {
if *tlsCertFile == "" || *tlsKeyFile == "" {
log.Fatal("Zero or both of --tls-key and --tls-cert must be supplied")

View file

@ -120,7 +120,7 @@ func startMediaAPI(suffix string, dynamicThumbnails bool) (*exec.Cmd, chan error
serverArgs,
)
fmt.Printf("==TESTSERVER== STARTED %v -> %v : %v\n", proxyAddr, cfg.MediaAPI.Listen, dir)
fmt.Printf("==TESTSERVER== STARTED %v -> %v : %v\n", proxyAddr, cfg.MediaAPI.InternalAPI.Listen, dir)
return cmd, cmdChan, proxyCmd, proxyAddr, dir
}

View file

@ -278,7 +278,7 @@ func testRoomserver(input []string, wantOutput []string, checkQueries func(api.R
cmd.Args = []string{"dendrite-room-server", "--config", filepath.Join(dir, test.ConfigFile)}
gotOutput, err := runAndReadFromTopic(cmd, cfg.RoomServerURL()+"/metrics", doInput, outputTopic, len(wantOutput), func() {
queryAPI, _ := inthttp.NewRoomserverClient("http://"+string(cfg.RoomServer.Listen), &http.Client{Timeout: timeoutHTTP}, cache)
queryAPI, _ := inthttp.NewRoomserverClient("http://"+string(cfg.RoomServer.InternalAPI.Connect), &http.Client{Timeout: timeoutHTTP}, cache)
checkQueries(queryAPI)
})
if err != nil {

View file

@ -133,7 +133,8 @@ func startSyncServer() (*exec.Cmd, chan error) {
}
// TODO use the address assigned by the config generator rather than clobbering.
cfg.Global.ServerName = "localhost"
cfg.SyncAPI.Listen = config.Address(syncserverAddr)
cfg.SyncAPI.InternalAPI.Listen = config.HTTPAddress("http://" + syncserverAddr)
cfg.SyncAPI.InternalAPI.Connect = cfg.SyncAPI.InternalAPI.Listen
if err := test.WriteConfig(cfg, dir); err != nil {
panic(err)

View file

@ -26,7 +26,8 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(FederationSenderPerformJoinRequestPath,
internalAPIMux.Handle(
FederationSenderPerformJoinRequestPath,
httputil.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformJoinRequest
var response api.PerformJoinResponse
@ -37,7 +38,8 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(FederationSenderPerformLeaveRequestPath,
internalAPIMux.Handle(
FederationSenderPerformLeaveRequestPath,
httputil.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformLeaveRequest
var response api.PerformLeaveResponse
@ -50,7 +52,8 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(FederationSenderPerformDirectoryLookupRequestPath,
internalAPIMux.Handle(
FederationSenderPerformDirectoryLookupRequestPath,
httputil.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformDirectoryLookupRequest
var response api.PerformDirectoryLookupResponse
@ -63,7 +66,8 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(FederationSenderPerformServersAlivePath,
internalAPIMux.Handle(
FederationSenderPerformServersAlivePath,
httputil.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformServersAliveRequest
var response api.PerformServersAliveResponse
@ -76,7 +80,8 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(FederationSenderPerformBroadcastEDUPath,
internalAPIMux.Handle(
FederationSenderPerformBroadcastEDUPath,
httputil.MakeInternalAPI("PerformBroadcastEDU", func(req *http.Request) util.JSONResponse {
var request api.PerformBroadcastEDURequest
var response api.PerformBroadcastEDUResponse

View file

@ -145,7 +145,7 @@ type Address string
// An HTTPAddress to listen on, starting with either http:// or https://.
type HTTPAddress string
func (h HTTPAddress) GetAddress() (Address, error) {
func (h HTTPAddress) Address() (Address, error) {
url, err := url.Parse(string(h))
if err != nil {
return "", err

View file

@ -28,7 +28,6 @@ import (
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth"
federationsenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
@ -233,27 +232,6 @@ func (f *FederationWakeups) Wakeup(ctx context.Context, origin gomatrixserverlib
}
}
// SetupHTTPAPI registers both internal and external HTTP APIs.
func SetupHTTPAPI(servMux, publicApiMux, internalApiMux *mux.Router, cfg *config.Global, enableHTTPAPIs bool) {
SetupInternalHTTPAPI(servMux, internalApiMux, cfg, enableHTTPAPIs)
SetupExternalHTTPAPI(servMux, publicApiMux, cfg)
}
// SetupInternalHTTPAPI registers internal APIs and metrics only.
func SetupInternalHTTPAPI(servMux, internalApiMux *mux.Router, cfg *config.Global, enableHTTPAPIs bool) {
if cfg.Metrics.Enabled {
servMux.Handle("/metrics", WrapHandlerInBasicAuth(promhttp.Handler(), cfg.Metrics.BasicAuth))
}
if enableHTTPAPIs {
servMux.Handle(InternalPathPrefix, internalApiMux)
}
}
// SetupExternalHTTPAPI registers public APIs only.
func SetupExternalHTTPAPI(servMux, publicApiMux *mux.Router, cfg *config.Global) {
servMux.Handle(PublicPathPrefix, WrapHandlerInCORS(publicApiMux))
}
// WrapHandlerInBasicAuth adds basic auth to a handler. Only used for /metrics
func WrapHandlerInBasicAuth(h http.Handler, b BasicAuth) http.HandlerFunc {
if b.Username == "" || b.Password == "" {

View file

@ -15,6 +15,6 @@
package httputil
const (
PublicPathPrefix = "/_matrix/"
InternalPathPrefix = "/api/"
PublicPathPrefix = "/_matrix"
InternalPathPrefix = "/api"
)

View file

@ -19,7 +19,6 @@ import (
"io"
"net/http"
"net/url"
"sync"
"time"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
@ -69,7 +68,6 @@ type BaseDendrite struct {
// PublicAPIMux should be used to register new public matrix api endpoints
PublicAPIMux *mux.Router
InternalAPIMux *mux.Router
BaseMux *mux.Router // base router which created public/internal subrouters
UseHTTPAPIs bool
httpClient *http.Client
Cfg *config.Dendrite
@ -81,6 +79,8 @@ type BaseDendrite struct {
const HTTPServerTimeout = time.Minute * 5
const HTTPClientTimeout = time.Second * 30
const NoExternalListener = ""
// NewBaseDendrite creates a new instance to be used by a component.
// The componentName is used for logging purposes, and should be a friendly name
// of the compontent running, e.g. "SyncAPI"
@ -135,17 +135,14 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
// We need to be careful with media APIs if they read from a filesystem to make sure they
// are not inadvertently reading paths without cleaning, else this could introduce a
// directory traversal attack e.g /../../../etc/passwd
httpmux := mux.NewRouter().SkipClean(true)
return &BaseDendrite{
componentName: componentName,
UseHTTPAPIs: useHTTPAPIs,
tracerCloser: closer,
Cfg: cfg,
Caches: cache,
BaseMux: httpmux,
PublicAPIMux: httpmux.PathPrefix(httputil.PublicPathPrefix).Subrouter().UseEncodedPath(),
InternalAPIMux: httpmux.PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
PublicAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicPathPrefix).Subrouter().UseEncodedPath(),
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
httpClient: &client,
KafkaConsumer: kafkaConsumer,
KafkaProducer: kafkaProducer,
@ -267,65 +264,55 @@ func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationCli
// SetupAndServeHTTP sets up the HTTP server to serve endpoints registered on
// ApiMux under /api/ and adds a prometheus handler under /metrics.
func (b *BaseDendrite) SetupAndServeHTTP(internaladdr, externaladdr string) {
var wg sync.WaitGroup
func (b *BaseDendrite) SetupAndServeHTTP(internalHTTPAddr, externalHTTPAddr config.HTTPAddress) {
block := make(chan struct{})
externalRouter := mux.NewRouter().SkipClean(true)
internalRouter := externalRouter
if internaladdr != externaladdr {
internalRouter = mux.NewRouter().SkipClean(true)
}
internalAddr, _ := internalHTTPAddr.Address()
externalAddr, _ := externalHTTPAddr.Address()
externalServ := &http.Server{
Addr: externaladdr,
internalRouter := mux.NewRouter()
externalRouter := internalRouter
internalServ := &http.Server{
Addr: string(internalAddr),
WriteTimeout: HTTPServerTimeout,
Handler: externalRouter,
Handler: internalRouter,
}
internalServ := externalServ
if internaladdr != externaladdr {
internalServ = &http.Server{
Addr: internaladdr,
externalServ := internalServ
if externalAddr != internalAddr {
externalRouter = mux.NewRouter()
externalServ = &http.Server{
Addr: string(externalAddr),
WriteTimeout: HTTPServerTimeout,
Handler: internalRouter,
Handler: externalRouter,
}
}
httputil.SetupExternalHTTPAPI(
externalRouter,
b.PublicAPIMux,
&b.Cfg.Global,
)
internalRouter.PathPrefix(httputil.InternalPathPrefix).Handler(b.InternalAPIMux)
externalRouter.PathPrefix(httputil.PublicPathPrefix).Handler(b.PublicAPIMux)
httputil.SetupInternalHTTPAPI(
internalRouter,
b.InternalAPIMux,
&b.Cfg.Global,
b.UseHTTPAPIs,
)
wg.Add(1)
go func() {
defer wg.Done()
logrus.Infof("Starting %s external APIs on %s", b.componentName, externalServ.Addr)
if err := externalServ.ListenAndServe(); err != nil {
logrus.WithError(err).Fatal("failed to serve http")
defer close(block)
logrus.Infof("Starting %s listener on %s", b.componentName, internalServ.Addr)
if err := internalServ.ListenAndServe(); err != nil {
logrus.WithError(err).Fatal("failed to serve HTTP")
}
logrus.Infof("Stopped %s external APIs on %s", b.componentName, externalServ.Addr)
logrus.Infof("Stopped %s listener on %s", b.componentName, internalServ.Addr)
}()
if internaladdr != externaladdr {
wg.Add(1)
if externalAddr != "" && internalAddr != externalAddr {
go func() {
defer wg.Done()
logrus.Infof("Starting %s internal APIs on %s", b.componentName, internalServ.Addr)
if err := internalServ.ListenAndServe(); err != nil {
logrus.WithError(err).Fatal("failed to serve http")
defer close(block)
logrus.Infof("Starting %s listener on %s", b.componentName, externalServ.Addr)
if err := externalServ.ListenAndServe(); err != nil {
logrus.WithError(err).Fatal("failed to serve HTTP")
}
logrus.Infof("Stopped %s internal APIs on %s", b.componentName, internalServ.Addr)
logrus.Infof("Stopped %s listener on %s", b.componentName, externalServ.Addr)
}()
}
wg.Wait()
<-block
}
// setupKafka creates kafka consumer/producer pair from the config.