From 2bd12f635cef281ab0d497c9e1bafe92247d88d5 Mon Sep 17 00:00:00 2001 From: Kegsay Date: Thu, 4 Jun 2020 16:26:35 +0100 Subject: [PATCH] Convert serverkeys to inthttp (#1097) --- cmd/dendrite-client-api-server/main.go | 2 +- cmd/dendrite-federation-api-server/main.go | 2 +- cmd/dendrite-federation-sender-server/main.go | 2 +- cmd/dendrite-monolith-server/main.go | 2 +- cmd/dendrite-room-server/main.go | 2 +- internal/basecomponent/base.go | 8 +- serverkeyapi/api/api.go | 98 +------------ serverkeyapi/api/http.go | 57 -------- serverkeyapi/internal/api.go | 6 +- serverkeyapi/inthttp/client.go | 137 ++++++++++++++++++ .../{internal/http.go => inthttp/server.go} | 11 +- serverkeyapi/serverkeyapi.go | 6 +- 12 files changed, 164 insertions(+), 169 deletions(-) delete mode 100644 serverkeyapi/api/http.go create mode 100644 serverkeyapi/inthttp/client.go rename serverkeyapi/{internal/http.go => inthttp/server.go} (82%) diff --git a/cmd/dendrite-client-api-server/main.go b/cmd/dendrite-client-api-server/main.go index ba8e6af7c..2eec84ab8 100644 --- a/cmd/dendrite-client-api-server/main.go +++ b/cmd/dendrite-client-api-server/main.go @@ -32,7 +32,7 @@ func main() { deviceDB := base.CreateDeviceDB() federation := base.CreateFederationClient() - serverKeyAPI := base.CreateHTTPServerKeyAPIs() + serverKeyAPI := base.ServerKeyAPIClient() keyRing := serverKeyAPI.KeyRing() asQuery := base.AppserviceHTTPClient() diff --git a/cmd/dendrite-federation-api-server/main.go b/cmd/dendrite-federation-api-server/main.go index aca6ba579..604dd4e3d 100644 --- a/cmd/dendrite-federation-api-server/main.go +++ b/cmd/dendrite-federation-api-server/main.go @@ -31,7 +31,7 @@ func main() { deviceDB := base.CreateDeviceDB() federation := base.CreateFederationClient() - serverKeyAPI := base.CreateHTTPServerKeyAPIs() + serverKeyAPI := base.ServerKeyAPIClient() keyRing := serverKeyAPI.KeyRing() fsAPI := base.FederationSenderHTTPClient() diff --git a/cmd/dendrite-federation-sender-server/main.go b/cmd/dendrite-federation-sender-server/main.go index 14524dcad..aeaa837d1 100644 --- a/cmd/dendrite-federation-sender-server/main.go +++ b/cmd/dendrite-federation-sender-server/main.go @@ -26,7 +26,7 @@ func main() { federation := base.CreateFederationClient() - serverKeyAPI := base.CreateHTTPServerKeyAPIs() + serverKeyAPI := base.ServerKeyAPIClient() keyRing := serverKeyAPI.KeyRing() rsAPI := base.RoomserverHTTPClient() diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go index ba9189256..78919f2b6 100644 --- a/cmd/dendrite-monolith-server/main.go +++ b/cmd/dendrite-monolith-server/main.go @@ -74,7 +74,7 @@ func main() { base, federation, ) if base.UseHTTPAPIs { - serverKeyAPI = base.CreateHTTPServerKeyAPIs() + serverKeyAPI = base.ServerKeyAPIClient() } keyRing := serverKeyAPI.KeyRing() diff --git a/cmd/dendrite-room-server/main.go b/cmd/dendrite-room-server/main.go index f4da560a6..65a1e9ae5 100644 --- a/cmd/dendrite-room-server/main.go +++ b/cmd/dendrite-room-server/main.go @@ -25,7 +25,7 @@ func main() { defer base.Close() // nolint: errcheck federation := base.CreateFederationClient() - serverKeyAPI := base.CreateHTTPServerKeyAPIs() + serverKeyAPI := base.ServerKeyAPIClient() keyRing := serverKeyAPI.KeyRing() fsAPI := base.FederationSenderHTTPClient() diff --git a/internal/basecomponent/base.go b/internal/basecomponent/base.go index cd297b82e..620b12d6a 100644 --- a/internal/basecomponent/base.go +++ b/internal/basecomponent/base.go @@ -45,6 +45,7 @@ import ( roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" rsinthttp "github.com/matrix-org/dendrite/roomserver/inthttp" serverKeyAPI "github.com/matrix-org/dendrite/serverkeyapi/api" + skinthttp "github.com/matrix-org/dendrite/serverkeyapi/inthttp" "github.com/sirupsen/logrus" _ "net/http/pprof" @@ -176,10 +177,9 @@ func (b *BaseDendrite) FederationSenderHTTPClient() federationSenderAPI.Federati return f } -// CreateHTTPServerKeyAPIs returns ServerKeyInternalAPI for hitting the server key -// API over HTTP -func (b *BaseDendrite) CreateHTTPServerKeyAPIs() serverKeyAPI.ServerKeyInternalAPI { - f, err := serverKeyAPI.NewServerKeyInternalAPIHTTP( +// ServerKeyAPIClient returns ServerKeyInternalAPI for hitting the server key API over HTTP +func (b *BaseDendrite) ServerKeyAPIClient() serverKeyAPI.ServerKeyInternalAPI { + f, err := skinthttp.NewServerKeyClient( b.Cfg.ServerKeyAPIURL(), b.httpClient, b.ImmutableCache, diff --git a/serverkeyapi/api/api.go b/serverkeyapi/api/api.go index a43f9c0a1..7af626345 100644 --- a/serverkeyapi/api/api.go +++ b/serverkeyapi/api/api.go @@ -2,11 +2,7 @@ package api import ( "context" - "errors" - "net/http" - "time" - "github.com/matrix-org/dendrite/internal/caching" "github.com/matrix-org/gomatrixserverlib" ) @@ -28,97 +24,17 @@ type ServerKeyInternalAPI interface { ) error } -// NewRoomserverInputAPIHTTP creates a RoomserverInputAPI implemented by talking to a HTTP POST API. -// If httpClient is nil an error is returned -func NewServerKeyInternalAPIHTTP( - serverKeyAPIURL string, - httpClient *http.Client, - immutableCache caching.ImmutableCache, -) (ServerKeyInternalAPI, error) { - if httpClient == nil { - return nil, errors.New("NewRoomserverInternalAPIHTTP: httpClient is ") - } - return &httpServerKeyInternalAPI{ - serverKeyAPIURL: serverKeyAPIURL, - httpClient: httpClient, - immutableCache: immutableCache, - }, nil +type QueryPublicKeysRequest struct { + Requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp `json:"requests"` } -type httpServerKeyInternalAPI struct { - ServerKeyInternalAPI - - serverKeyAPIURL string - httpClient *http.Client - immutableCache caching.ImmutableCache +type QueryPublicKeysResponse struct { + Results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"results"` } -func (s *httpServerKeyInternalAPI) KeyRing() *gomatrixserverlib.KeyRing { - // This is a bit of a cheat - we tell gomatrixserverlib that this API is - // both the key database and the key fetcher. While this does have the - // rather unfortunate effect of preventing gomatrixserverlib from handling - // key fetchers directly, we can at least reimplement this behaviour on - // the other end of the API. - return &gomatrixserverlib.KeyRing{ - KeyDatabase: s, - KeyFetchers: []gomatrixserverlib.KeyFetcher{s}, - } +type InputPublicKeysRequest struct { + Keys map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"keys"` } -func (s *httpServerKeyInternalAPI) FetcherName() string { - return "httpServerKeyInternalAPI" -} - -func (s *httpServerKeyInternalAPI) StoreKeys( - _ context.Context, - results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, -) error { - // Run in a background context - we don't want to stop this work just - // because the caller gives up waiting. - ctx := context.Background() - request := InputPublicKeysRequest{ - Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult), - } - response := InputPublicKeysResponse{} - for req, res := range results { - request.Keys[req] = res - s.immutableCache.StoreServerKey(req, res) - } - return s.InputPublicKeys(ctx, &request, &response) -} - -func (s *httpServerKeyInternalAPI) FetchKeys( - _ context.Context, - requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp, -) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) { - // Run in a background context - we don't want to stop this work just - // because the caller gives up waiting. - ctx := context.Background() - result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult) - request := QueryPublicKeysRequest{ - Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp), - } - response := QueryPublicKeysResponse{ - Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult), - } - now := gomatrixserverlib.AsTimestamp(time.Now()) - for req, ts := range requests { - if res, ok := s.immutableCache.GetServerKey(req); ok { - if now > res.ValidUntilTS && res.ExpiredTS == gomatrixserverlib.PublicKeyNotExpired { - continue - } - result[req] = res - continue - } - request.Requests[req] = ts - } - err := s.QueryPublicKeys(ctx, &request, &response) - if err != nil { - return nil, err - } - for req, res := range response.Results { - result[req] = res - s.immutableCache.StoreServerKey(req, res) - } - return result, nil +type InputPublicKeysResponse struct { } diff --git a/serverkeyapi/api/http.go b/serverkeyapi/api/http.go deleted file mode 100644 index ab89f7bfc..000000000 --- a/serverkeyapi/api/http.go +++ /dev/null @@ -1,57 +0,0 @@ -package api - -import ( - "context" - - commonHTTP "github.com/matrix-org/dendrite/internal/http" - "github.com/matrix-org/gomatrixserverlib" - - "github.com/opentracing/opentracing-go" -) - -const ( - // ServerKeyInputPublicKeyPath is the HTTP path for the InputPublicKeys API. - ServerKeyInputPublicKeyPath = "/serverkeyapi/inputPublicKey" - - // ServerKeyQueryPublicKeyPath is the HTTP path for the QueryPublicKeys API. - ServerKeyQueryPublicKeyPath = "/serverkeyapi/queryPublicKey" -) - -type InputPublicKeysRequest struct { - Keys map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"keys"` -} - -type InputPublicKeysResponse struct { -} - -func (h *httpServerKeyInternalAPI) InputPublicKeys( - ctx context.Context, - request *InputPublicKeysRequest, - response *InputPublicKeysResponse, -) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "InputPublicKey") - defer span.Finish() - - apiURL := h.serverKeyAPIURL + ServerKeyInputPublicKeyPath - return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) -} - -type QueryPublicKeysRequest struct { - Requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp `json:"requests"` -} - -type QueryPublicKeysResponse struct { - Results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"results"` -} - -func (h *httpServerKeyInternalAPI) QueryPublicKeys( - ctx context.Context, - request *QueryPublicKeysRequest, - response *QueryPublicKeysResponse, -) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublicKey") - defer span.Finish() - - apiURL := h.serverKeyAPIURL + ServerKeyQueryPublicKeyPath - return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) -} diff --git a/serverkeyapi/internal/api.go b/serverkeyapi/internal/api.go index c63b23f04..176983c86 100644 --- a/serverkeyapi/internal/api.go +++ b/serverkeyapi/internal/api.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - "github.com/matrix-org/dendrite/internal/caching" "github.com/matrix-org/dendrite/serverkeyapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -13,9 +12,8 @@ import ( type ServerKeyAPI struct { api.ServerKeyInternalAPI - ImmutableCache caching.ImmutableCache - OurKeyRing gomatrixserverlib.KeyRing - FedClient *gomatrixserverlib.FederationClient + OurKeyRing gomatrixserverlib.KeyRing + FedClient *gomatrixserverlib.FederationClient } func (s *ServerKeyAPI) KeyRing() *gomatrixserverlib.KeyRing { diff --git a/serverkeyapi/inthttp/client.go b/serverkeyapi/inthttp/client.go new file mode 100644 index 000000000..f986634ba --- /dev/null +++ b/serverkeyapi/inthttp/client.go @@ -0,0 +1,137 @@ +package inthttp + +import ( + "context" + "errors" + "net/http" + "time" + + "github.com/matrix-org/dendrite/internal/caching" + internalHTTP "github.com/matrix-org/dendrite/internal/http" + "github.com/matrix-org/dendrite/serverkeyapi/api" + "github.com/matrix-org/gomatrixserverlib" + "github.com/opentracing/opentracing-go" +) + +// HTTP paths for the internal HTTP APIs +const ( + ServerKeyInputPublicKeyPath = "/serverkeyapi/inputPublicKey" + ServerKeyQueryPublicKeyPath = "/serverkeyapi/queryPublicKey" +) + +// NewServerKeyClient creates a ServerKeyInternalAPI implemented by talking to a HTTP POST API. +// If httpClient is nil an error is returned +func NewServerKeyClient( + serverKeyAPIURL string, + httpClient *http.Client, + immutableCache caching.ImmutableCache, +) (api.ServerKeyInternalAPI, error) { + if httpClient == nil { + return nil, errors.New("NewRoomserverInternalAPIHTTP: httpClient is ") + } + return &httpServerKeyInternalAPI{ + serverKeyAPIURL: serverKeyAPIURL, + httpClient: httpClient, + immutableCache: immutableCache, + }, nil +} + +type httpServerKeyInternalAPI struct { + serverKeyAPIURL string + httpClient *http.Client + immutableCache caching.ImmutableCache +} + +func (s *httpServerKeyInternalAPI) KeyRing() *gomatrixserverlib.KeyRing { + // This is a bit of a cheat - we tell gomatrixserverlib that this API is + // both the key database and the key fetcher. While this does have the + // rather unfortunate effect of preventing gomatrixserverlib from handling + // key fetchers directly, we can at least reimplement this behaviour on + // the other end of the API. + return &gomatrixserverlib.KeyRing{ + KeyDatabase: s, + KeyFetchers: []gomatrixserverlib.KeyFetcher{s}, + } +} + +func (s *httpServerKeyInternalAPI) FetcherName() string { + return "httpServerKeyInternalAPI" +} + +func (s *httpServerKeyInternalAPI) StoreKeys( + _ context.Context, + results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, +) error { + // Run in a background context - we don't want to stop this work just + // because the caller gives up waiting. + ctx := context.Background() + request := api.InputPublicKeysRequest{ + Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult), + } + response := api.InputPublicKeysResponse{} + for req, res := range results { + request.Keys[req] = res + s.immutableCache.StoreServerKey(req, res) + } + return s.InputPublicKeys(ctx, &request, &response) +} + +func (s *httpServerKeyInternalAPI) FetchKeys( + _ context.Context, + requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp, +) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) { + // Run in a background context - we don't want to stop this work just + // because the caller gives up waiting. + ctx := context.Background() + result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult) + request := api.QueryPublicKeysRequest{ + Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp), + } + response := api.QueryPublicKeysResponse{ + Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult), + } + now := gomatrixserverlib.AsTimestamp(time.Now()) + for req, ts := range requests { + if res, ok := s.immutableCache.GetServerKey(req); ok { + if now > res.ValidUntilTS && res.ExpiredTS == gomatrixserverlib.PublicKeyNotExpired { + continue + } + result[req] = res + continue + } + request.Requests[req] = ts + } + err := s.QueryPublicKeys(ctx, &request, &response) + if err != nil { + return nil, err + } + for req, res := range response.Results { + result[req] = res + s.immutableCache.StoreServerKey(req, res) + } + return result, nil +} + +func (h *httpServerKeyInternalAPI) InputPublicKeys( + ctx context.Context, + request *api.InputPublicKeysRequest, + response *api.InputPublicKeysResponse, +) error { + span, ctx := opentracing.StartSpanFromContext(ctx, "InputPublicKey") + defer span.Finish() + + apiURL := h.serverKeyAPIURL + ServerKeyInputPublicKeyPath + return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) +} + +func (h *httpServerKeyInternalAPI) QueryPublicKeys( + ctx context.Context, + request *api.QueryPublicKeysRequest, + response *api.QueryPublicKeysResponse, +) error { + span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublicKey") + defer span.Finish() + + apiURL := h.serverKeyAPIURL + ServerKeyQueryPublicKeyPath + return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) +} diff --git a/serverkeyapi/internal/http.go b/serverkeyapi/inthttp/server.go similarity index 82% rename from serverkeyapi/internal/http.go rename to serverkeyapi/inthttp/server.go index eef66b76c..d5517e143 100644 --- a/serverkeyapi/internal/http.go +++ b/serverkeyapi/inthttp/server.go @@ -1,4 +1,4 @@ -package internal +package inthttp import ( "encoding/json" @@ -6,13 +6,14 @@ import ( "github.com/gorilla/mux" "github.com/matrix-org/dendrite/internal" + "github.com/matrix-org/dendrite/internal/caching" "github.com/matrix-org/dendrite/serverkeyapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) -func (s *ServerKeyAPI) SetupHTTP(internalAPIMux *mux.Router) { - internalAPIMux.Handle(api.ServerKeyQueryPublicKeyPath, +func AddRoutes(s api.ServerKeyInternalAPI, internalAPIMux *mux.Router, cache caching.ImmutableCache) { + internalAPIMux.Handle(ServerKeyQueryPublicKeyPath, internal.MakeInternalAPI("queryPublicKeys", func(req *http.Request) util.JSONResponse { request := api.QueryPublicKeysRequest{} response := api.QueryPublicKeysResponse{} @@ -27,7 +28,7 @@ func (s *ServerKeyAPI) SetupHTTP(internalAPIMux *mux.Router) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) - internalAPIMux.Handle(api.ServerKeyInputPublicKeyPath, + internalAPIMux.Handle(ServerKeyInputPublicKeyPath, internal.MakeInternalAPI("inputPublicKeys", func(req *http.Request) util.JSONResponse { request := api.InputPublicKeysRequest{} response := api.InputPublicKeysResponse{} @@ -37,7 +38,7 @@ func (s *ServerKeyAPI) SetupHTTP(internalAPIMux *mux.Router) { store := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult) for req, res := range request.Keys { store[req] = res - s.ImmutableCache.StoreServerKey(req, res) + cache.StoreServerKey(req, res) } if err := s.StoreKeys(req.Context(), store); err != nil { return util.ErrorResponse(err) diff --git a/serverkeyapi/serverkeyapi.go b/serverkeyapi/serverkeyapi.go index 61d807d64..5bf8f67d7 100644 --- a/serverkeyapi/serverkeyapi.go +++ b/serverkeyapi/serverkeyapi.go @@ -7,6 +7,7 @@ import ( "github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/serverkeyapi/api" "github.com/matrix-org/dendrite/serverkeyapi/internal" + "github.com/matrix-org/dendrite/serverkeyapi/inthttp" "github.com/matrix-org/dendrite/serverkeyapi/storage" "github.com/matrix-org/dendrite/serverkeyapi/storage/cache" "github.com/matrix-org/gomatrixserverlib" @@ -34,8 +35,7 @@ func SetupServerKeyAPIComponent( } internalAPI := internal.ServerKeyAPI{ - ImmutableCache: base.ImmutableCache, - FedClient: fedClient, + FedClient: fedClient, OurKeyRing: gomatrixserverlib.KeyRing{ KeyFetchers: []gomatrixserverlib.KeyFetcher{ &gomatrixserverlib.DirectKeyFetcher{ @@ -77,7 +77,7 @@ func SetupServerKeyAPIComponent( }).Info("Enabled perspective key fetcher") } - internalAPI.SetupHTTP(base.InternalAPIMux) + inthttp.AddRoutes(&internalAPI, base.InternalAPIMux, base.ImmutableCache) return &internalAPI }