diff --git a/dendrite-config.yaml b/dendrite-config.yaml index 44441787..b99a7c71 100644 --- a/dendrite-config.yaml +++ b/dendrite-config.yaml @@ -113,7 +113,7 @@ listen: media_api: "localhost:7774" public_rooms_api: "localhost:7775" federation_sender: "localhost:7776" - appservice: "localhost:7777" + appservice_api: "localhost:7777" # The configuration for tracing the dendrite components. tracing: diff --git a/src/github.com/matrix-org/dendrite/appservice/api/query.go b/src/github.com/matrix-org/dendrite/appservice/api/query.go new file mode 100644 index 00000000..b094c914 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/appservice/api/query.go @@ -0,0 +1,49 @@ +// Copyright 2018 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package api contains methods used by dendrite components in multi-process +// mode to send requests to the appservice component, typically in order to ask +// an application service for some information. +package api + +import ( + "net/http" +) + +// AppServiceQueryAPI is used to query user and room alias data from application +// services +type AppServiceQueryAPI interface { + // TODO: Check whether a room alias exists within any application service namespaces + // TODO: QueryUserIDExists +} + +// httpAppServiceQueryAPI contains the URL to an appservice query API and a +// reference to a httpClient used to reach it +type httpAppServiceQueryAPI struct { + appserviceURL string + httpClient *http.Client +} + +// NewAppServiceQueryAPIHTTP creates a AppServiceQueryAPI implemented by talking +// to a HTTP POST API. +// If httpClient is nil then it uses http.DefaultClient +func NewAppServiceQueryAPIHTTP( + appserviceURL string, + httpClient *http.Client, +) AppServiceQueryAPI { + if httpClient == nil { + httpClient = http.DefaultClient + } + return &httpAppServiceQueryAPI{appserviceURL, httpClient} +} diff --git a/src/github.com/matrix-org/dendrite/appservice/appservice.go b/src/github.com/matrix-org/dendrite/appservice/appservice.go index 57b127f2..4d3c2d2f 100644 --- a/src/github.com/matrix-org/dendrite/appservice/appservice.go +++ b/src/github.com/matrix-org/dendrite/appservice/appservice.go @@ -15,9 +15,13 @@ package appservice import ( + "net/http" "sync" + "time" + appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/appservice/consumers" + "github.com/matrix-org/dendrite/appservice/query" "github.com/matrix-org/dendrite/appservice/routing" "github.com/matrix-org/dendrite/appservice/storage" "github.com/matrix-org/dendrite/appservice/types" @@ -25,7 +29,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/common/basecomponent" "github.com/matrix-org/dendrite/common/transactions" - "github.com/matrix-org/dendrite/roomserver/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) @@ -36,10 +40,10 @@ func SetupAppServiceAPIComponent( base *basecomponent.BaseDendrite, accountsDB *accounts.Database, federation *gomatrixserverlib.FederationClient, - aliasAPI api.RoomserverAliasAPI, - queryAPI api.RoomserverQueryAPI, + roomserverAliasAPI roomserverAPI.RoomserverAliasAPI, + roomserverQueryAPI roomserverAPI.RoomserverQueryAPI, transactionsCache *transactions.Cache, -) { +) appserviceAPI.AppServiceQueryAPI { // Create a connection to the appservice postgres DB appserviceDB, err := storage.NewDatabase(string(base.Cfg.Database.AppService)) if err != nil { @@ -59,9 +63,22 @@ func SetupAppServiceAPIComponent( workerStates[i] = ws } + // Create a HTTP client that this component will use for all outbound and + // inbound requests (inbound only for the internal API) + httpClient := &http.Client{ + Timeout: time.Second * 30, + } + + appserviceQueryAPI := query.AppServiceQueryAPI{ + HTTPClient: httpClient, + Cfg: base.Cfg, + } + + appserviceQueryAPI.SetupHTTP(http.DefaultServeMux) + consumer := consumers.NewOutputRoomEventConsumer( base.Cfg, base.KafkaConsumer, accountsDB, appserviceDB, - queryAPI, aliasAPI, workerStates, + roomserverQueryAPI, roomserverAliasAPI, workerStates, ) if err := consumer.Start(); err != nil { logrus.WithError(err).Panicf("failed to start app service roomserver consumer") @@ -74,7 +91,9 @@ func SetupAppServiceAPIComponent( // Set up HTTP Endpoints routing.Setup( - base.APIMux, *base.Cfg, queryAPI, aliasAPI, accountsDB, - federation, transactionsCache, + base.APIMux, *base.Cfg, roomserverQueryAPI, roomserverAliasAPI, + accountsDB, federation, transactionsCache, ) + + return &appserviceQueryAPI } diff --git a/src/github.com/matrix-org/dendrite/appservice/query/query.go b/src/github.com/matrix-org/dendrite/appservice/query/query.go new file mode 100644 index 00000000..cdaf681a --- /dev/null +++ b/src/github.com/matrix-org/dendrite/appservice/query/query.go @@ -0,0 +1,34 @@ +// Copyright 2018 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package query handles requests from other internal dendrite components when +// they interact with the AppServiceQueryAPI. +package query + +import ( + "net/http" + + "github.com/matrix-org/dendrite/common/config" +) + +// AppServiceQueryAPI is an implementation of api.AppServiceQueryAPI +type AppServiceQueryAPI struct { + HTTPClient *http.Client + Cfg *config.Dendrite +} + +// SetupHTTP adds the AppServiceQueryPAI handlers to the http.ServeMux. This +// handles and muxes incoming api requests the to internal AppServiceQueryAPI. +func (a *AppServiceQueryAPI) SetupHTTP(servMux *http.ServeMux) { +} diff --git a/src/github.com/matrix-org/dendrite/appservice/workers/transaction_scheduler.go b/src/github.com/matrix-org/dendrite/appservice/workers/transaction_scheduler.go index 8f966c94..3e5fee30 100644 --- a/src/github.com/matrix-org/dendrite/appservice/workers/transaction_scheduler.go +++ b/src/github.com/matrix-org/dendrite/appservice/workers/transaction_scheduler.go @@ -65,7 +65,7 @@ func worker(db *storage.Database, ws types.ApplicationServiceWorkerState) { }).Info("starting application service") ctx := context.Background() - // Grab the HTTP client for sending requests to app services + // Create a HTTP client for sending requests to app services client := &http.Client{ Timeout: transactionTimeout, // TODO: Verify certificates diff --git a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go index 6f31ca75..01e204ce 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go +++ b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go @@ -22,7 +22,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/routing" "github.com/matrix-org/dendrite/common/basecomponent" "github.com/matrix-org/dendrite/common/transactions" - "github.com/matrix-org/dendrite/roomserver/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) @@ -35,9 +35,9 @@ func SetupClientAPIComponent( accountsDB *accounts.Database, federation *gomatrixserverlib.FederationClient, keyRing *gomatrixserverlib.KeyRing, - aliasAPI api.RoomserverAliasAPI, - inputAPI api.RoomserverInputAPI, - queryAPI api.RoomserverQueryAPI, + aliasAPI roomserverAPI.RoomserverAliasAPI, + inputAPI roomserverAPI.RoomserverInputAPI, + queryAPI roomserverAPI.RoomserverQueryAPI, transactionsCache *transactions.Cache, ) { roomserverProducer := producers.NewRoomserverProducer(inputAPI) @@ -60,10 +60,8 @@ func SetupClientAPIComponent( } routing.Setup( - base.APIMux, *base.Cfg, roomserverProducer, - queryAPI, aliasAPI, accountsDB, deviceDB, - federation, *keyRing, - userUpdateProducer, syncProducer, - transactionsCache, + base.APIMux, *base.Cfg, roomserverProducer, queryAPI, aliasAPI, + accountsDB, deviceDB, federation, *keyRing, userUpdateProducer, + syncProducer, transactionsCache, ) } diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/joinroom.go b/src/github.com/matrix-org/dendrite/clientapi/routing/joinroom.go index 7c0af2eb..c1bd251b 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/joinroom.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/joinroom.go @@ -27,7 +27,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/producers" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" - "github.com/matrix-org/dendrite/roomserver/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -42,8 +42,8 @@ func JoinRoomByIDOrAlias( cfg config.Dendrite, federation *gomatrixserverlib.FederationClient, producer *producers.RoomserverProducer, - queryAPI api.RoomserverQueryAPI, - aliasAPI api.RoomserverAliasAPI, + queryAPI roomserverAPI.RoomserverQueryAPI, + aliasAPI roomserverAPI.RoomserverAliasAPI, keyRing gomatrixserverlib.KeyRing, accountDB *accounts.Database, ) util.JSONResponse { @@ -87,8 +87,8 @@ type joinRoomReq struct { cfg config.Dendrite federation *gomatrixserverlib.FederationClient producer *producers.RoomserverProducer - queryAPI api.RoomserverQueryAPI - aliasAPI api.RoomserverAliasAPI + queryAPI roomserverAPI.RoomserverQueryAPI + aliasAPI roomserverAPI.RoomserverAliasAPI keyRing gomatrixserverlib.KeyRing } @@ -100,10 +100,10 @@ func (r joinRoomReq) joinRoomByID(roomID string) util.JSONResponse { // If the server is not in the room the we will need to look up the // remote server the invite came from in order to request a join event // from that server. - queryReq := api.QueryInvitesForUserRequest{ + queryReq := roomserverAPI.QueryInvitesForUserRequest{ RoomID: roomID, TargetUserID: r.userID, } - var queryRes api.QueryInvitesForUserResponse + var queryRes roomserverAPI.QueryInvitesForUserResponse if err := r.queryAPI.QueryInvitesForUser(r.req.Context(), &queryReq, &queryRes); err != nil { return httputil.LogThenError(r.req, err) } @@ -145,8 +145,8 @@ func (r joinRoomReq) joinRoomByAlias(roomAlias string) util.JSONResponse { } } if domain == r.cfg.Matrix.ServerName { - queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias} - var queryRes api.GetRoomIDForAliasResponse + queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias} + var queryRes roomserverAPI.GetRoomIDForAliasResponse if err = r.aliasAPI.GetRoomIDForAlias(r.req.Context(), &queryReq, &queryRes); err != nil { return httputil.LogThenError(r.req, err) } @@ -214,7 +214,7 @@ func (r joinRoomReq) joinRoomUsingServers( return httputil.LogThenError(r.req, err) } - var queryRes api.QueryLatestEventsAndStateResponse + var queryRes roomserverAPI.QueryLatestEventsAndStateResponse event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, r.queryAPI, &queryRes) if err == nil { if _, err = r.producer.SendEvents(r.req.Context(), []gomatrixserverlib.Event{*event}, r.cfg.Matrix.ServerName, nil); err != nil { diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/register.go b/src/github.com/matrix-org/dendrite/clientapi/routing/register.go index 813c4b3f..bfecec5d 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/register.go @@ -318,8 +318,8 @@ func UserIDIsWithinApplicationServiceNamespace( } // Loop through all known application service's namespaces and see if any match - for _, knownAppservice := range cfg.Derived.ApplicationServices { - for _, namespace := range knownAppservice.NamespaceMap["users"] { + for _, knownAppService := range cfg.Derived.ApplicationServices { + for _, namespace := range knownAppService.NamespaceMap["users"] { // AS namespaces are checked for validity in config if namespace.RegexpObject.MatchString(userID) { return true diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go index 3ffc833e..6cb93a31 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go @@ -21,7 +21,6 @@ import ( "github.com/matrix-org/dendrite/common/keydb" "github.com/matrix-org/dendrite/common/transactions" - "github.com/matrix-org/dendrite/appservice" "github.com/matrix-org/dendrite/clientapi" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/basecomponent" @@ -66,7 +65,6 @@ func main() { mediaapi.SetupMediaAPIComponent(base, deviceDB) publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB) syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query) - appservice.SetupAppServiceAPIComponent(base, accountDB, federation, alias, query, transactions.New()) httpHandler := common.WrapHandlerInCORS(base.APIMux) diff --git a/src/github.com/matrix-org/dendrite/common/basecomponent/base.go b/src/github.com/matrix-org/dendrite/common/basecomponent/base.go index ed7cb7ab..e97d49b0 100644 --- a/src/github.com/matrix-org/dendrite/common/basecomponent/base.go +++ b/src/github.com/matrix-org/dendrite/common/basecomponent/base.go @@ -30,8 +30,9 @@ import ( "github.com/gorilla/mux" sarama "gopkg.in/Shopify/sarama.v1" + appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/common/config" - "github.com/matrix-org/dendrite/roomserver/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/sirupsen/logrus" ) @@ -80,12 +81,22 @@ func (b *BaseDendrite) Close() error { return b.tracerCloser.Close() } -// CreateHTTPRoomserverAPIs returns the AliasAPI, InputAPI and QueryAPI to hit +// CreateHTTPAppServiceAPIs returns the QueryAPI for hitting the appservice +// component over HTTP. +func (b *BaseDendrite) CreateHTTPAppServiceAPIs() appserviceAPI.AppServiceQueryAPI { + return appserviceAPI.NewAppServiceQueryAPIHTTP(b.Cfg.AppServiceURL(), nil) +} + +// CreateHTTPRoomserverAPIs returns the AliasAPI, InputAPI and QueryAPI for hitting // the roomserver over HTTP. -func (b *BaseDendrite) CreateHTTPRoomserverAPIs() (api.RoomserverAliasAPI, api.RoomserverInputAPI, api.RoomserverQueryAPI) { - alias := api.NewRoomserverAliasAPIHTTP(b.Cfg.RoomServerURL(), nil) - input := api.NewRoomserverInputAPIHTTP(b.Cfg.RoomServerURL(), nil) - query := api.NewRoomserverQueryAPIHTTP(b.Cfg.RoomServerURL(), nil) +func (b *BaseDendrite) CreateHTTPRoomserverAPIs() ( + roomserverAPI.RoomserverAliasAPI, + roomserverAPI.RoomserverInputAPI, + roomserverAPI.RoomserverQueryAPI, +) { + alias := roomserverAPI.NewRoomserverAliasAPIHTTP(b.Cfg.RoomServerURL(), nil) + input := roomserverAPI.NewRoomserverInputAPIHTTP(b.Cfg.RoomServerURL(), nil) + query := roomserverAPI.NewRoomserverQueryAPIHTTP(b.Cfg.RoomServerURL(), nil) return alias, input, query } diff --git a/src/github.com/matrix-org/dendrite/common/config/appservice.go b/src/github.com/matrix-org/dendrite/common/config/appservice.go index a18d716e..7a43d48f 100644 --- a/src/github.com/matrix-org/dendrite/common/config/appservice.go +++ b/src/github.com/matrix-org/dendrite/common/config/appservice.go @@ -114,9 +114,9 @@ func (a *ApplicationService) IsInterestedInRoomAlias( return false } -// loadAppservices iterates through all application service config files +// loadAppServices iterates through all application service config files // and loads their data into the config object for later access. -func loadAppservices(config *Dendrite) error { +func loadAppServices(config *Dendrite) error { for _, configPath := range config.ApplicationServices.ConfigFiles { // Create a new application service with default options appservice := ApplicationService{ diff --git a/src/github.com/matrix-org/dendrite/common/config/config.go b/src/github.com/matrix-org/dendrite/common/config/config.go index bd6e361d..86dd2770 100644 --- a/src/github.com/matrix-org/dendrite/common/config/config.go +++ b/src/github.com/matrix-org/dendrite/common/config/config.go @@ -198,6 +198,7 @@ type Dendrite struct { MediaAPI Address `yaml:"media_api"` ClientAPI Address `yaml:"client_api"` FederationAPI Address `yaml:"federation_api"` + AppServiceAPI Address `yaml:"appservice_api"` SyncAPI Address `yaml:"sync_api"` RoomServer Address `yaml:"room_server"` FederationSender Address `yaml:"federation_sender"` @@ -408,7 +409,7 @@ func (config *Dendrite) derive() error { } // Load application service configuration files - if err := loadAppservices(config); err != nil { + if err := loadAppServices(config); err != nil { return err } @@ -640,6 +641,15 @@ func fingerprintPEM(data []byte) *gomatrixserverlib.TLSFingerprint { } } +// AppServiceURL returns a HTTP URL for where the appservice component is listening. +func (config *Dendrite) AppServiceURL() string { + // Hard code the roomserver to talk HTTP for now. + // If we support HTTPS we need to think of a practical way to do certificate validation. + // People setting up servers shouldn't need to get a certificate valid for the public + // internet for an internal API. + return "http://" + string(config.Listen.AppServiceAPI) +} + // RoomServerURL returns an HTTP URL for where the roomserver is listening. func (config *Dendrite) RoomServerURL() string { // Hard code the roomserver to talk HTTP for now. diff --git a/src/github.com/matrix-org/dendrite/common/http/http.go b/src/github.com/matrix-org/dendrite/common/http/http.go new file mode 100644 index 00000000..3c647544 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/common/http/http.go @@ -0,0 +1,57 @@ +package http + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" +) + +// PostJSON performs a POST request with JSON on an internal HTTP API +func PostJSON( + ctx context.Context, span opentracing.Span, httpClient *http.Client, + apiURL string, request, response interface{}, +) error { + jsonBytes, err := json.Marshal(request) + if err != nil { + return err + } + + req, err := http.NewRequest(http.MethodPost, apiURL, bytes.NewReader(jsonBytes)) + if err != nil { + return err + } + + // Mark the span as being an RPC client. + ext.SpanKindRPCClient.Set(span) + carrier := opentracing.HTTPHeadersCarrier(req.Header) + tracer := opentracing.GlobalTracer() + + if err = tracer.Inject(span.Context(), opentracing.HTTPHeaders, carrier); err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + + res, err := httpClient.Do(req.WithContext(ctx)) + if res != nil { + defer (func() { err = res.Body.Close() })() + } + if err != nil { + return err + } + if res.StatusCode != http.StatusOK { + var errorBody struct { + Message string `json:"message"` + } + if err = json.NewDecoder(res.Body).Decode(&errorBody); err != nil { + return err + } + return fmt.Errorf("api: %d: %s", res.StatusCode, errorBody.Message) + } + return json.NewDecoder(res.Body).Decode(response) +} diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/alias.go b/src/github.com/matrix-org/dendrite/roomserver/api/alias.go index 16760da6..57671071 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/alias.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/alias.go @@ -18,6 +18,7 @@ import ( "context" "net/http" + commonHTTP "github.com/matrix-org/dendrite/common/http" opentracing "github.com/opentracing/opentracing-go" ) @@ -139,7 +140,7 @@ func (h *httpRoomserverAliasAPI) SetRoomAlias( defer span.Finish() apiURL := h.roomserverURL + RoomserverSetRoomAliasPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // GetRoomIDForAlias implements RoomserverAliasAPI @@ -152,7 +153,7 @@ func (h *httpRoomserverAliasAPI) GetRoomIDForAlias( defer span.Finish() apiURL := h.roomserverURL + RoomserverGetRoomIDForAliasPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // GetAliasesForRoomID implements RoomserverAliasAPI @@ -165,7 +166,7 @@ func (h *httpRoomserverAliasAPI) GetAliasesForRoomID( defer span.Finish() apiURL := h.roomserverURL + RoomserverGetAliasesForRoomIDPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // RemoveRoomAlias implements RoomserverAliasAPI @@ -178,5 +179,5 @@ func (h *httpRoomserverAliasAPI) RemoveRoomAlias( defer span.Finish() apiURL := h.roomserverURL + RoomserverRemoveRoomAliasPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/input.go b/src/github.com/matrix-org/dendrite/roomserver/api/input.go index e81e7920..2c2e27c6 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/input.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/input.go @@ -19,6 +19,7 @@ import ( "context" "net/http" + commonHTTP "github.com/matrix-org/dendrite/common/http" "github.com/matrix-org/gomatrixserverlib" opentracing "github.com/opentracing/opentracing-go" ) @@ -134,5 +135,5 @@ func (h *httpRoomserverInputAPI) InputRoomEvents( defer span.Finish() apiURL := h.roomserverURL + RoomserverInputRoomEventsPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/query.go b/src/github.com/matrix-org/dendrite/roomserver/api/query.go index 5e4ba811..8c375321 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/query.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/query.go @@ -15,16 +15,12 @@ package api import ( - "bytes" "context" - "encoding/json" - "fmt" "net/http" - opentracing "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" - + commonHTTP "github.com/matrix-org/dendrite/common/http" "github.com/matrix-org/gomatrixserverlib" + opentracing "github.com/opentracing/opentracing-go" ) // QueryLatestEventsAndStateRequest is a request to QueryLatestEventsAndState @@ -337,7 +333,7 @@ func (h *httpRoomserverQueryAPI) QueryLatestEventsAndState( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryLatestEventsAndStatePath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryStateAfterEvents implements RoomserverQueryAPI @@ -350,7 +346,7 @@ func (h *httpRoomserverQueryAPI) QueryStateAfterEvents( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryStateAfterEventsPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryEventsByID implements RoomserverQueryAPI @@ -363,7 +359,7 @@ func (h *httpRoomserverQueryAPI) QueryEventsByID( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryEventsByIDPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryMembershipForUser implements RoomserverQueryAPI @@ -376,7 +372,7 @@ func (h *httpRoomserverQueryAPI) QueryMembershipForUser( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryMembershipForUserPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryMembershipsForRoom implements RoomserverQueryAPI @@ -389,7 +385,7 @@ func (h *httpRoomserverQueryAPI) QueryMembershipsForRoom( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryMembershipsForRoomPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryInvitesForUser implements RoomserverQueryAPI @@ -402,7 +398,7 @@ func (h *httpRoomserverQueryAPI) QueryInvitesForUser( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryInvitesForUserPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryServerAllowedToSeeEvent implements RoomserverQueryAPI @@ -415,7 +411,7 @@ func (h *httpRoomserverQueryAPI) QueryServerAllowedToSeeEvent( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryServerAllowedToSeeEventPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryMissingEvents implements RoomServerQueryAPI @@ -428,7 +424,7 @@ func (h *httpRoomserverQueryAPI) QueryMissingEvents( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryMissingEventsPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } // QueryStateAndAuthChain implements RoomserverQueryAPI @@ -441,49 +437,5 @@ func (h *httpRoomserverQueryAPI) QueryStateAndAuthChain( defer span.Finish() apiURL := h.roomserverURL + RoomserverQueryStateAndAuthChainPath - return postJSON(ctx, span, h.httpClient, apiURL, request, response) -} - -func postJSON( - ctx context.Context, span opentracing.Span, httpClient *http.Client, - apiURL string, request, response interface{}, -) error { - jsonBytes, err := json.Marshal(request) - if err != nil { - return err - } - - req, err := http.NewRequest(http.MethodPost, apiURL, bytes.NewReader(jsonBytes)) - if err != nil { - return err - } - - // Mark the span as being an RPC client. - ext.SpanKindRPCClient.Set(span) - carrier := opentracing.HTTPHeadersCarrier(req.Header) - tracer := opentracing.GlobalTracer() - - if err = tracer.Inject(span.Context(), opentracing.HTTPHeaders, carrier); err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - res, err := httpClient.Do(req.WithContext(ctx)) - if res != nil { - defer (func() { err = res.Body.Close() })() - } - if err != nil { - return err - } - if res.StatusCode != http.StatusOK { - var errorBody struct { - Message string `json:"message"` - } - if err = json.NewDecoder(res.Body).Decode(&errorBody); err != nil { - return err - } - return fmt.Errorf("api: %d: %s", res.StatusCode, errorBody.Message) - } - return json.NewDecoder(res.Body).Decode(response) + return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) }