diff --git a/clientapi/routing/joinroom.go b/clientapi/routing/joinroom.go index dbce305fd..f72bb9162 100644 --- a/clientapi/routing/joinroom.go +++ b/clientapi/routing/joinroom.go @@ -15,7 +15,6 @@ package routing import ( - "context" "fmt" "net/http" "strings" @@ -385,23 +384,13 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib "num_state_events": len(respSendJoin.StateEvents), }).Info("Room join signature and auth verification passed") - // By this point we've verified all of the signatures, retrieved all of the - // missing auth events and verified that everything checks out. Nothing - // *should* go wrong in the roomserver after this point, so rather than have - // the client block on the roomserver taking in all of the new events, we - // should be okay to do this in a goroutine and return the successful join - // back to the client. - // TODO: Verify that this is really the case. - go func() { - ctx := context.Background() - if err = r.producer.SendEventWithState( - ctx, - gomatrixserverlib.RespState(respSendJoin.RespState), - event.Headered(respMakeJoin.RoomVersion), - ); err != nil { - util.GetLogger(ctx).WithError(err).Error("r.producer.SendEventWithState") - } - }() + if err = r.producer.SendEventWithState( + r.req.Context(), + gomatrixserverlib.RespState(respSendJoin.RespState), + event.Headered(respMakeJoin.RoomVersion), + ); err != nil { + util.GetLogger(r.req.Context()).WithError(err).Error("r.producer.SendEventWithState") + } return &util.JSONResponse{ Code: http.StatusOK, diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go index e105d3019..d4aa28c75 100644 --- a/cmd/dendrite-monolith-server/main.go +++ b/cmd/dendrite-monolith-server/main.go @@ -90,16 +90,26 @@ func main() { // Expose the matrix APIs directly rather than putting them under a /api path. go func() { - logrus.Info("Listening on ", *httpBindAddr) - logrus.Fatal(http.ListenAndServe(*httpBindAddr, nil)) + serv := http.Server{ + Addr: *httpBindAddr, + WriteTimeout: basecomponent.HTTPServerTimeout, + } + + logrus.Info("Listening on ", serv.Addr) + logrus.Fatal(serv.ListenAndServe()) }() // Handle HTTPS if certificate and key are provided - go func() { - if *certFile != "" && *keyFile != "" { + if *certFile != "" && *keyFile != "" { + go func() { + serv := http.Server{ + Addr: *httpBindAddr, + WriteTimeout: basecomponent.HTTPServerTimeout, + } + logrus.Info("Listening on ", *httpsBindAddr) - logrus.Fatal(http.ListenAndServeTLS(*httpsBindAddr, *certFile, *keyFile, nil)) - } - }() + logrus.Fatal(serv.ListenAndServeTLS(*certFile, *keyFile)) + }() + } // We want to block forever to let the HTTP and HTTPS handler serve the APIs select {} diff --git a/common/basecomponent/base.go b/common/basecomponent/base.go index 5c6f64775..73e01de13 100644 --- a/common/basecomponent/base.go +++ b/common/basecomponent/base.go @@ -60,6 +60,9 @@ type BaseDendrite struct { KafkaProducer sarama.SyncProducer } +const HTTPServerTimeout = time.Minute * 5 +const HTTPClientTimeout = time.Second * 30 + // 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" @@ -80,14 +83,12 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string) *BaseDendrite { kafkaConsumer, kafkaProducer = setupKafka(cfg) } - const defaultHTTPTimeout = 30 * time.Second - return &BaseDendrite{ componentName: componentName, tracerCloser: closer, Cfg: cfg, APIMux: mux.NewRouter().UseEncodedPath(), - httpClient: &http.Client{Timeout: defaultHTTPTimeout}, + httpClient: &http.Client{Timeout: HTTPClientTimeout}, KafkaConsumer: kafkaConsumer, KafkaProducer: kafkaProducer, } @@ -212,8 +213,12 @@ func (b *BaseDendrite) SetupAndServeHTTP(bindaddr string, listenaddr string) { common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(b.APIMux), b.Cfg) logrus.Infof("Starting %s server on %s", b.componentName, addr) - err := http.ListenAndServe(addr, nil) + serv := http.Server{ + Addr: addr, + WriteTimeout: HTTPServerTimeout, + } + err := serv.ListenAndServe() if err != nil { logrus.WithError(err).Fatal("failed to serve http") }