Merge branch 'master' into fix-database-errors-601

This commit is contained in:
Maximilian Seifert 2019-10-30 21:51:51 +01:00
commit 1171b5c999
24 changed files with 176 additions and 87 deletions

View file

@ -23,11 +23,10 @@ run](scripts/build-test-lint.sh).
## Continuous Integration ## Continuous Integration
When a Pull Request is submitted, continuous integration jobs are run When a Pull Request is submitted, continuous integration jobs are run
automatically to ensure the code builds and is relatively well-written. Checks automatically to ensure the code builds and is relatively well-written. The
are run on [Buildkite](https://buildkite.com/matrix-dot-org/dendrite/) and jobs are run on [Buildkite](https://buildkite.com/matrix-dot-org/dendrite/),
[CircleCI](https://circleci.com/gh/matrix-org/dendrite/). The Buildkite and the Buildkite pipeline configuration can be found in Matrix.org's
pipeline can be found in Matrix.org's [pipelines [pipelines repository](https://github.com/matrix-org/pipelines).
repository](https://github.com/matrix-org/pipelines).
If a job fails, click the "details" button and you should be taken to the job's If a job fails, click the "details" button and you should be taken to the job's
logs. logs.
@ -44,16 +43,20 @@ To save waiting for CI to finish after every commit, it is ideal to run the
checks locally before pushing, fixing errors first. This also saves other checks locally before pushing, fixing errors first. This also saves other
people time as only so many PRs can be tested at a given time. people time as only so many PRs can be tested at a given time.
To execute what Buildkite tests, simply run `./scripts/build-test-lint.sh`. To execute what Buildkite tests, first run `./scripts/build-test-lint.sh`;
This script will build the code, lint it, and run `go test ./...` with race this script will build the code, lint it, and run `go test ./...` with race
condition checking enabled. If something needs to be changed, fix it and then condition checking enabled. If something needs to be changed, fix it and then
run the script again until it no longer complains. Be warned that the linting run the script again until it no longer complains. Be warned that the linting
can take a significant amount of CPU and RAM. can take a significant amount of CPU and RAM.
CircleCI simply runs [Sytest](https://github.com/matrix-org/sytest) with a test Once the code builds, run [Sytest](https://github.com/matrix-org/sytest)
whitelist. See according to the guide in
[docs/sytest.md](https://github.com/matrix-org/dendrite/blob/master/docs/sytest.md#using-a-sytest-docker-image) [docs/sytest.md](https://github.com/matrix-org/dendrite/blob/master/docs/sytest.md#using-a-sytest-docker-image)
for instructions on setting it up to run locally. so you can see whether something is being broken and whether there are newly
passing tests.
If these two steps report no problems, the code should be able to pass the CI
tests.
## Picking Things To Do ## Picking Things To Do

View file

@ -1,4 +1,4 @@
# Dendrite [![Build Status](https://badge.buildkite.com/4be40938ab19f2bbc4a6c6724517353ee3ec1422e279faf374.svg?branch=master)](https://buildkite.com/matrix-dot-org/dendrite) [![CircleCI](https://circleci.com/gh/matrix-org/dendrite.svg?style=svg)](https://circleci.com/gh/matrix-org/dendrite) [![Dendrite Dev on Matrix](https://img.shields.io/matrix/dendrite-dev:matrix.org.svg?label=%23dendrite-dev%3Amatrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#dendrite-dev:matrix.org) [![Dendrite on Matrix](https://img.shields.io/matrix/dendrite:matrix.org.svg?label=%23dendrite%3Amatrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#dendrite:matrix.org) # Dendrite [![Build Status](https://badge.buildkite.com/4be40938ab19f2bbc4a6c6724517353ee3ec1422e279faf374.svg?branch=master)](https://buildkite.com/matrix-dot-org/dendrite) [![Dendrite Dev on Matrix](https://img.shields.io/matrix/dendrite-dev:matrix.org.svg?label=%23dendrite-dev%3Amatrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#dendrite-dev:matrix.org) [![Dendrite on Matrix](https://img.shields.io/matrix/dendrite:matrix.org.svg?label=%23dendrite%3Amatrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#dendrite:matrix.org)
Dendrite will be a matrix homeserver written in go. Dendrite will be a matrix homeserver written in go.

View file

@ -120,28 +120,21 @@ func (s *accountDataStatements) selectAccountData(
func (s *accountDataStatements) selectAccountDataByType( func (s *accountDataStatements) selectAccountDataByType(
ctx context.Context, localpart, roomID, dataType string, ctx context.Context, localpart, roomID, dataType string,
) (data []gomatrixserverlib.ClientEvent, err error) { ) (data *gomatrixserverlib.ClientEvent, err error) {
data = []gomatrixserverlib.ClientEvent{}
stmt := s.selectAccountDataByTypeStmt stmt := s.selectAccountDataByTypeStmt
rows, err := stmt.QueryContext(ctx, localpart, roomID, dataType) var content []byte
if err != nil {
if err = stmt.QueryRowContext(ctx, localpart, roomID, dataType).Scan(&content); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return return
} }
for rows.Next() { data = &gomatrixserverlib.ClientEvent{
var content []byte Type: dataType,
Content: content,
if err = rows.Scan(&content); err != nil {
return
}
ac := gomatrixserverlib.ClientEvent{
Type: dataType,
Content: content,
}
data = append(data, ac)
} }
return return

View file

@ -263,11 +263,11 @@ func (d *Database) GetAccountData(ctx context.Context, localpart string) (
// GetAccountDataByType returns account data matching a given // GetAccountDataByType returns account data matching a given
// localpart, room ID and type. // localpart, room ID and type.
// If no account data could be found, returns an empty array // If no account data could be found, returns nil
// Returns an error if there was an issue with the retrieval // Returns an error if there was an issue with the retrieval
func (d *Database) GetAccountDataByType( func (d *Database) GetAccountDataByType(
ctx context.Context, localpart, roomID, dataType string, ctx context.Context, localpart, roomID, dataType string,
) (data []gomatrixserverlib.ClientEvent, err error) { ) (data *gomatrixserverlib.ClientEvent, err error) {
return d.accountDatas.selectAccountDataByType( return d.accountDatas.selectAccountDataByType(
ctx, localpart, roomID, dataType, ctx, localpart, roomID, dataType,
) )

View file

@ -23,6 +23,7 @@ import (
"github.com/matrix-org/dendrite/clientapi/routing" "github.com/matrix-org/dendrite/clientapi/routing"
"github.com/matrix-org/dendrite/common/basecomponent" "github.com/matrix-org/dendrite/common/basecomponent"
"github.com/matrix-org/dendrite/common/transactions" "github.com/matrix-org/dendrite/common/transactions"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
typingServerAPI "github.com/matrix-org/dendrite/typingserver/api" typingServerAPI "github.com/matrix-org/dendrite/typingserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
@ -43,6 +44,7 @@ func SetupClientAPIComponent(
typingInputAPI typingServerAPI.TypingServerInputAPI, typingInputAPI typingServerAPI.TypingServerInputAPI,
asAPI appserviceAPI.AppServiceQueryAPI, asAPI appserviceAPI.AppServiceQueryAPI,
transactionsCache *transactions.Cache, transactionsCache *transactions.Cache,
fedSenderAPI federationSenderAPI.FederationSenderQueryAPI,
) { ) {
roomserverProducer := producers.NewRoomserverProducer(inputAPI) roomserverProducer := producers.NewRoomserverProducer(inputAPI)
typingProducer := producers.NewTypingServerProducer(typingInputAPI) typingProducer := producers.NewTypingServerProducer(typingInputAPI)
@ -67,6 +69,6 @@ func SetupClientAPIComponent(
routing.Setup( routing.Setup(
base.APIMux, *base.Cfg, roomserverProducer, queryAPI, aliasAPI, asAPI, base.APIMux, *base.Cfg, roomserverProducer, queryAPI, aliasAPI, asAPI,
accountsDB, deviceDB, federation, *keyRing, userUpdateProducer, accountsDB, deviceDB, federation, *keyRing, userUpdateProducer,
syncProducer, typingProducer, transactionsCache, syncProducer, typingProducer, transactionsCache, fedSenderAPI,
) )
} }

View file

@ -22,12 +22,24 @@ import (
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
roomserverAPI "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/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
type roomDirectoryResponse struct {
RoomID string `json:"room_id"`
Servers []string `json:"servers"`
}
func (r *roomDirectoryResponse) fillServers(servers []gomatrixserverlib.ServerName) {
r.Servers = make([]string, len(servers))
for i, s := range servers {
r.Servers[i] = string(s)
}
}
// DirectoryRoom looks up a room alias // DirectoryRoom looks up a room alias
func DirectoryRoom( func DirectoryRoom(
req *http.Request, req *http.Request,
@ -35,6 +47,7 @@ func DirectoryRoom(
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI roomserverAPI.RoomserverAliasAPI, rsAPI roomserverAPI.RoomserverAliasAPI,
fedSenderAPI federationSenderAPI.FederationSenderQueryAPI,
) util.JSONResponse { ) util.JSONResponse {
_, domain, err := gomatrixserverlib.SplitID('#', roomAlias) _, domain, err := gomatrixserverlib.SplitID('#', roomAlias)
if err != nil { if err != nil {
@ -44,46 +57,51 @@ func DirectoryRoom(
} }
} }
if domain == cfg.Matrix.ServerName { var res roomDirectoryResponse
// Query the roomserver API to check if the alias exists locally
queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias} // Query the roomserver API to check if the alias exists locally.
var queryRes roomserverAPI.GetRoomIDForAliasResponse queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias}
if err = rsAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil { var queryRes roomserverAPI.GetRoomIDForAliasResponse
return httputil.LogThenError(req, err) if err = rsAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil {
return httputil.LogThenError(req, err)
}
res.RoomID = queryRes.RoomID
if res.RoomID == "" {
// If we don't know it locally, do a federation query.
// But don't send the query to ourselves.
if domain != cfg.Matrix.ServerName {
fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
if fedErr != nil {
// TODO: Return 502 if the remote server errored.
// TODO: Return 504 if the remote server timed out.
return httputil.LogThenError(req, fedErr)
}
res.RoomID = fedRes.RoomID
res.fillServers(fedRes.Servers)
} }
// List any roomIDs found associated with this alias if res.RoomID == "" {
if len(queryRes.RoomID) > 0 {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusNotFound,
JSON: queryRes, JSON: jsonerror.NotFound(
fmt.Sprintf("Room alias %s not found", roomAlias),
),
} }
} }
} else { } else {
// Query the federation for this room alias joinedHostsReq := federationSenderAPI.QueryJoinedHostServerNamesInRoomRequest{RoomID: res.RoomID}
resp, err := federation.LookupRoomAlias(req.Context(), domain, roomAlias) var joinedHostsRes federationSenderAPI.QueryJoinedHostServerNamesInRoomResponse
if err != nil { if err = fedSenderAPI.QueryJoinedHostServerNamesInRoom(req.Context(), &joinedHostsReq, &joinedHostsRes); err != nil {
switch err.(type) { return httputil.LogThenError(req, err)
case gomatrix.HTTPError:
default:
// TODO: Return 502 if the remote server errored.
// TODO: Return 504 if the remote server timed out.
return httputil.LogThenError(req, err)
}
}
if len(resp.RoomID) > 0 {
return util.JSONResponse{
Code: http.StatusOK,
JSON: resp,
}
} }
res.fillServers(joinedHostsRes.ServerNames)
} }
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusOK,
JSON: jsonerror.NotFound( JSON: res,
fmt.Sprintf("Room alias %s not found", roomAlias),
),
} }
} }

View file

@ -59,7 +59,7 @@ func GetTags(
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
if len(data) == 0 { if data == nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: struct{}{}, JSON: struct{}{},
@ -68,7 +68,7 @@ func GetTags(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: data[0].Content, JSON: data.Content,
} }
} }
@ -103,8 +103,8 @@ func PutTag(
} }
var tagContent gomatrix.TagContent var tagContent gomatrix.TagContent
if len(data) > 0 { if data != nil {
if err = json.Unmarshal(data[0].Content, &tagContent); err != nil { if err = json.Unmarshal(data.Content, &tagContent); err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
} else { } else {
@ -155,7 +155,7 @@ func DeleteTag(
} }
// If there are no tags in the database, exit // If there are no tags in the database, exit
if len(data) == 0 { if data == nil {
// Spec only defines 200 responses for this endpoint so we don't return anything else. // Spec only defines 200 responses for this endpoint so we don't return anything else.
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
@ -164,7 +164,7 @@ func DeleteTag(
} }
var tagContent gomatrix.TagContent var tagContent gomatrix.TagContent
err = json.Unmarshal(data[0].Content, &tagContent) err = json.Unmarshal(data.Content, &tagContent)
if err != nil { if err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
@ -204,7 +204,7 @@ func obtainSavedTags(
userID string, userID string,
roomID string, roomID string,
accountDB *accounts.Database, accountDB *accounts.Database,
) (string, []gomatrixserverlib.ClientEvent, error) { ) (string, *gomatrixserverlib.ClientEvent, error) {
localpart, _, err := gomatrixserverlib.SplitID('@', userID) localpart, _, err := gomatrixserverlib.SplitID('@', userID)
if err != nil { if err != nil {
return "", nil, err return "", nil, err

View file

@ -30,6 +30,7 @@ import (
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/dendrite/common/transactions" "github.com/matrix-org/dendrite/common/transactions"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -59,6 +60,7 @@ func Setup(
syncProducer *producers.SyncAPIProducer, syncProducer *producers.SyncAPIProducer,
typingProducer *producers.TypingServerProducer, typingProducer *producers.TypingServerProducer,
transactionsCache *transactions.Cache, transactionsCache *transactions.Cache,
federationSender federationSenderAPI.FederationSenderQueryAPI,
) { ) {
apiMux.Handle("/_matrix/client/versions", apiMux.Handle("/_matrix/client/versions",
@ -185,7 +187,7 @@ func Setup(
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI) return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI, federationSender)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)

View file

@ -35,5 +35,6 @@ func main() {
base, accountDB, deviceDB, federation, alias, query, cache, base, accountDB, deviceDB, federation, alias, query, cache,
) )
base.SetupAndServeHTTP(string(base.Cfg.Listen.FederationSender)) base.SetupAndServeHTTP(string(base.Cfg.Bind.AppServiceAPI), string(base.Cfg.Listen.AppServiceAPI))
} }

View file

@ -37,12 +37,14 @@ func main() {
asQuery := base.CreateHTTPAppServiceAPIs() asQuery := base.CreateHTTPAppServiceAPIs()
alias, input, query := base.CreateHTTPRoomserverAPIs() alias, input, query := base.CreateHTTPRoomserverAPIs()
fedSenderAPI := base.CreateHTTPFederationSenderAPIs()
typingInputAPI := typingserver.SetupTypingServerComponent(base, cache.NewTypingCache()) typingInputAPI := typingserver.SetupTypingServerComponent(base, cache.NewTypingCache())
clientapi.SetupClientAPIComponent( clientapi.SetupClientAPIComponent(
base, deviceDB, accountDB, federation, &keyRing, base, deviceDB, accountDB, federation, &keyRing,
alias, input, query, typingInputAPI, asQuery, transactions.New(), alias, input, query, typingInputAPI, asQuery, transactions.New(), fedSenderAPI,
) )
base.SetupAndServeHTTP(string(base.Cfg.Listen.ClientAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.ClientAPI), string(base.Cfg.Listen.ClientAPI))
} }

View file

@ -39,5 +39,6 @@ func main() {
alias, input, query, asQuery, alias, input, query, asQuery,
) )
base.SetupAndServeHTTP(string(base.Cfg.Listen.FederationAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationAPI), string(base.Cfg.Listen.FederationAPI))
} }

View file

@ -32,5 +32,6 @@ func main() {
base, federation, query, base, federation, query,
) )
base.SetupAndServeHTTP(string(base.Cfg.Listen.FederationSender)) base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationSender), string(base.Cfg.Listen.FederationSender))
} }

View file

@ -28,5 +28,6 @@ func main() {
mediaapi.SetupMediaAPIComponent(base, deviceDB) mediaapi.SetupMediaAPIComponent(base, deviceDB)
base.SetupAndServeHTTP(string(base.Cfg.Listen.MediaAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI))
} }

View file

@ -60,14 +60,14 @@ func main() {
asQuery := appservice.SetupAppServiceAPIComponent( asQuery := appservice.SetupAppServiceAPIComponent(
base, accountDB, deviceDB, federation, alias, query, transactions.New(), base, accountDB, deviceDB, federation, alias, query, transactions.New(),
) )
fedSenderAPI := federationsender.SetupFederationSenderComponent(base, federation, query)
clientapi.SetupClientAPIComponent( clientapi.SetupClientAPIComponent(
base, deviceDB, accountDB, base, deviceDB, accountDB,
federation, &keyRing, alias, input, query, federation, &keyRing, alias, input, query,
typingInputAPI, asQuery, transactions.New(), typingInputAPI, asQuery, transactions.New(), fedSenderAPI,
) )
federationapi.SetupFederationAPIComponent(base, accountDB, deviceDB, federation, &keyRing, alias, input, query, asQuery) federationapi.SetupFederationAPIComponent(base, accountDB, deviceDB, federation, &keyRing, alias, input, query, asQuery)
federationsender.SetupFederationSenderComponent(base, federation, query)
mediaapi.SetupMediaAPIComponent(base, deviceDB) mediaapi.SetupMediaAPIComponent(base, deviceDB)
publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB) publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB)
syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query) syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query)

View file

@ -28,5 +28,6 @@ func main() {
publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB) publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB)
base.SetupAndServeHTTP(string(base.Cfg.Listen.PublicRoomsAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.PublicRoomsAPI), string(base.Cfg.Listen.PublicRoomsAPI))
} }

View file

@ -28,5 +28,6 @@ func main() {
roomserver.SetupRoomServerComponent(base) roomserver.SetupRoomServerComponent(base)
base.SetupAndServeHTTP(string(base.Cfg.Listen.RoomServer)) base.SetupAndServeHTTP(string(base.Cfg.Bind.RoomServer), string(base.Cfg.Listen.RoomServer))
} }

View file

@ -31,5 +31,6 @@ func main() {
syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query) syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query)
base.SetupAndServeHTTP(string(base.Cfg.Listen.SyncAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.SyncAPI), string(base.Cfg.Listen.SyncAPI))
} }

View file

@ -32,5 +32,6 @@ func main() {
typingserver.SetupTypingServerComponent(base, cache.NewTypingCache()) typingserver.SetupTypingServerComponent(base, cache.NewTypingCache())
base.SetupAndServeHTTP(string(base.Cfg.Listen.TypingServer)) base.SetupAndServeHTTP(string(base.Cfg.Bind.TypingServer), string(base.Cfg.Listen.TypingServer))
} }

View file

@ -32,6 +32,7 @@ import (
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
typingServerAPI "github.com/matrix-org/dendrite/typingserver/api" typingServerAPI "github.com/matrix-org/dendrite/typingserver/api"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -107,6 +108,12 @@ func (b *BaseDendrite) CreateHTTPTypingServerAPIs() typingServerAPI.TypingServer
return typingServerAPI.NewTypingServerInputAPIHTTP(b.Cfg.TypingServerURL(), nil) return typingServerAPI.NewTypingServerInputAPIHTTP(b.Cfg.TypingServerURL(), nil)
} }
// CreateHTTPFederationSenderAPIs returns FederationSenderQueryAPI for hitting
// the federation sender over HTTP
func (b *BaseDendrite) CreateHTTPFederationSenderAPIs() federationSenderAPI.FederationSenderQueryAPI {
return federationSenderAPI.NewFederationSenderQueryAPIHTTP(b.Cfg.FederationSenderURL(), nil)
}
// CreateDeviceDB creates a new instance of the device database. Should only be // CreateDeviceDB creates a new instance of the device database. Should only be
// called once per component. // called once per component.
func (b *BaseDendrite) CreateDeviceDB() *devices.Database { func (b *BaseDendrite) CreateDeviceDB() *devices.Database {
@ -150,7 +157,16 @@ func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationCli
// SetupAndServeHTTP sets up the HTTP server to serve endpoints registered on // SetupAndServeHTTP sets up the HTTP server to serve endpoints registered on
// ApiMux under /api/ and adds a prometheus handler under /metrics. // ApiMux under /api/ and adds a prometheus handler under /metrics.
func (b *BaseDendrite) SetupAndServeHTTP(addr string) { func (b *BaseDendrite) SetupAndServeHTTP(bindaddr string, listenaddr string) {
// If a separate bind address is defined, listen on that. Otherwise use
// the listen address
var addr string
if bindaddr != "" {
addr = bindaddr
} else {
addr = listenaddr
}
common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(b.APIMux)) common.SetupHTTPAPI(http.DefaultServeMux, common.WrapHandlerInCORS(b.APIMux))
logrus.Infof("Starting %s server on %s", b.componentName, addr) logrus.Infof("Starting %s server on %s", b.componentName, addr)

View file

@ -196,6 +196,20 @@ type Dendrite struct {
// The internal addresses the components will listen on. // The internal addresses the components will listen on.
// These should not be exposed externally as they expose metrics and debugging APIs. // These should not be exposed externally as they expose metrics and debugging APIs.
// Falls back to addresses listed in Listen if not specified
Bind 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"`
PublicRoomsAPI Address `yaml:"public_rooms_api"`
TypingServer Address `yaml:"typing_server"`
} `yaml:"bind"`
// The addresses for talking to other microservices.
Listen struct { Listen struct {
MediaAPI Address `yaml:"media_api"` MediaAPI Address `yaml:"media_api"`
ClientAPI Address `yaml:"client_api"` ClientAPI Address `yaml:"client_api"`
@ -678,6 +692,15 @@ func (config *Dendrite) TypingServerURL() string {
return "http://" + string(config.Listen.TypingServer) return "http://" + string(config.Listen.TypingServer)
} }
// FederationSenderURL returns an HTTP URL for where the federation sender is listening.
func (config *Dendrite) FederationSenderURL() string {
// Hard code the typing server 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.FederationSender)
}
// SetupTracing configures the opentracing using the supplied configuration. // SetupTracing configures the opentracing using the supplied configuration.
func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err error) { func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err error) {
return config.Tracing.Jaeger.InitGlobalTracer( return config.Tracing.Jaeger.InitGlobalTracer(

View file

@ -91,6 +91,7 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
// the table names are globally unique. But we might not want to // the table names are globally unique. But we might not want to
// rely on that in the future. // rely on that in the future.
cfg.Database.Account = config.DataSource(database) cfg.Database.Account = config.DataSource(database)
cfg.Database.AppService = config.DataSource(database)
cfg.Database.Device = config.DataSource(database) cfg.Database.Device = config.DataSource(database)
cfg.Database.MediaAPI = config.DataSource(database) cfg.Database.MediaAPI = config.DataSource(database)
cfg.Database.RoomServer = config.DataSource(database) cfg.Database.RoomServer = config.DataSource(database)
@ -99,6 +100,7 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
cfg.Database.PublicRoomsAPI = config.DataSource(database) cfg.Database.PublicRoomsAPI = config.DataSource(database)
cfg.Listen.ClientAPI = assignAddress() cfg.Listen.ClientAPI = assignAddress()
cfg.Listen.AppServiceAPI = assignAddress()
cfg.Listen.FederationAPI = assignAddress() cfg.Listen.FederationAPI = assignAddress()
cfg.Listen.MediaAPI = assignAddress() cfg.Listen.MediaAPI = assignAddress()
cfg.Listen.RoomServer = assignAddress() cfg.Listen.RoomServer = assignAddress()
@ -106,6 +108,16 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
cfg.Listen.PublicRoomsAPI = assignAddress() cfg.Listen.PublicRoomsAPI = assignAddress()
cfg.Listen.TypingServer = assignAddress() cfg.Listen.TypingServer = assignAddress()
// Bind to the same address as the listen address
// All microservices are run on the same host in testing
cfg.Bind.ClientAPI = cfg.Listen.ClientAPI
cfg.Bind.FederationAPI = cfg.Listen.FederationAPI
cfg.Bind.MediaAPI = cfg.Listen.MediaAPI
cfg.Bind.RoomServer = cfg.Listen.RoomServer
cfg.Bind.SyncAPI = cfg.Listen.SyncAPI
cfg.Bind.PublicRoomsAPI = cfg.Listen.PublicRoomsAPI
cfg.Bind.TypingServer = cfg.Listen.TypingServer
return &cfg, port, nil return &cfg, port, nil
} }

View file

@ -27,7 +27,7 @@ echo "Installing golangci-lint..."
# TODO: Once go 1.13 is out, use go get's -mod=readonly option # TODO: Once go 1.13 is out, use go get's -mod=readonly option
# https://github.com/golang/go/issues/30667 # https://github.com/golang/go/issues/30667
cp go.mod go.mod.bak && cp go.sum go.sum.bak cp go.mod go.mod.bak && cp go.sum go.sum.bak
go get github.com/golangci/golangci-lint/cmd/golangci-lint go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.19.1
echo "Looking for lint..." echo "Looking for lint..."
golangci-lint run $args golangci-lint run $args

View file

@ -196,13 +196,13 @@ func (rp *RequestPool) appendAccountData(
events := []gomatrixserverlib.ClientEvent{} events := []gomatrixserverlib.ClientEvent{}
// Request the missing data from the database // Request the missing data from the database
for _, dataType := range dataTypes { for _, dataType := range dataTypes {
evs, err := rp.accountDB.GetAccountDataByType( event, err := rp.accountDB.GetAccountDataByType(
req.ctx, localpart, roomID, dataType, req.ctx, localpart, roomID, dataType,
) )
if err != nil { if err != nil {
return nil, err return nil, err
} }
events = append(events, evs...) events = append(events, *event)
} }
// Append the data to the response // Append the data to the response

View file

@ -173,3 +173,13 @@ Outbound federation can query profile data
Federation key API allows unsigned requests for keys Federation key API allows unsigned requests for keys
Inbound federation can receive v1 room-join requests Inbound federation can receive v1 room-join requests
Can paginate public room list Can paginate public room list
GET /directory/room/:room_alias yields room ID
PUT /directory/room/:room_alias creates alias
Room aliases can contain Unicode
Creators can delete alias
Alias creators can delete alias with no ops
Alias creators can delete canonical alias with no ops
Regular users cannot create room aliases within the AS namespace
Deleting a non-existent alias should return a 404
Users can't delete other's aliases
Outbound federation can query room alias directory