mirror of
https://github.com/1f349/dendrite.git
synced 2024-11-09 22:42:58 +00:00
Fix rooms v3 url paths for good - with tests (#1130)
* Fix rooms v3 url paths for good - with tests - Add a test rig around `federationapi` to test routing. - Use `JSONVerifier` over `KeyRing` so we can stub things out more easily. - Add `test.NopJSONVerifier` which verifies nothing. - Add `base.BaseMux` which is the original `mux.Router` used to spawn public/internal routers. - Listen on `base.BaseMux` and not the default serve mux as it cleans paths which we don't want. - Factor out `ListenAndServe` to `test.ListenAndServe` and add flag for listening on TLS. * Fix comments * Linting
This commit is contained in:
parent
1aac317341
commit
7c36fb78a7
@ -47,6 +47,7 @@ var (
|
|||||||
userID = flag.String("user-id", "@userid:$SERVER_NAME", "The user ID to use as the event sender")
|
userID = flag.String("user-id", "@userid:$SERVER_NAME", "The user ID to use as the event sender")
|
||||||
messageCount = flag.Int("message-count", 10, "The number of m.room.messsage events to generate")
|
messageCount = flag.Int("message-count", 10, "The number of m.room.messsage events to generate")
|
||||||
format = flag.String("Format", "InputRoomEvent", "The output format to use for the messages: InputRoomEvent or Event")
|
format = flag.String("Format", "InputRoomEvent", "The output format to use for the messages: InputRoomEvent or Event")
|
||||||
|
ver = flag.String("version", string(gomatrixserverlib.RoomVersionV1), "Room version to generate events as")
|
||||||
)
|
)
|
||||||
|
|
||||||
// By default we use a private key of 0.
|
// By default we use a private key of 0.
|
||||||
@ -109,7 +110,7 @@ func buildAndOutput() gomatrixserverlib.EventReference {
|
|||||||
|
|
||||||
event, err := b.Build(
|
event, err := b.Build(
|
||||||
now, name, key, privateKey,
|
now, name, key, privateKey,
|
||||||
gomatrixserverlib.RoomVersionV1,
|
gomatrixserverlib.RoomVersion(*ver),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -127,7 +128,7 @@ func writeEvent(event gomatrixserverlib.Event) {
|
|||||||
if *format == "InputRoomEvent" {
|
if *format == "InputRoomEvent" {
|
||||||
var ire api.InputRoomEvent
|
var ire api.InputRoomEvent
|
||||||
ire.Kind = api.KindNew
|
ire.Kind = api.KindNew
|
||||||
ire.Event = event.Headered(gomatrixserverlib.RoomVersionV1)
|
ire.Event = event.Headered(gomatrixserverlib.RoomVersion(*ver))
|
||||||
authEventIDs := []string{}
|
authEventIDs := []string{}
|
||||||
for _, ref := range b.AuthEvents.([]gomatrixserverlib.EventReference) {
|
for _, ref := range b.AuthEvents.([]gomatrixserverlib.EventReference) {
|
||||||
authEventIDs = append(authEventIDs, ref.EventID)
|
authEventIDs = append(authEventIDs, ref.EventID)
|
||||||
|
@ -173,7 +173,7 @@ func main() {
|
|||||||
monolith.AddAllPublicRoutes(base.Base.PublicAPIMux)
|
monolith.AddAllPublicRoutes(base.Base.PublicAPIMux)
|
||||||
|
|
||||||
httputil.SetupHTTPAPI(
|
httputil.SetupHTTPAPI(
|
||||||
http.DefaultServeMux,
|
base.Base.BaseMux,
|
||||||
base.Base.PublicAPIMux,
|
base.Base.PublicAPIMux,
|
||||||
base.Base.InternalAPIMux,
|
base.Base.InternalAPIMux,
|
||||||
&cfg,
|
&cfg,
|
||||||
@ -184,7 +184,7 @@ func main() {
|
|||||||
go func() {
|
go func() {
|
||||||
httpBindAddr := fmt.Sprintf(":%d", *instancePort)
|
httpBindAddr := fmt.Sprintf(":%d", *instancePort)
|
||||||
logrus.Info("Listening on ", httpBindAddr)
|
logrus.Info("Listening on ", httpBindAddr)
|
||||||
logrus.Fatal(http.ListenAndServe(httpBindAddr, nil))
|
logrus.Fatal(http.ListenAndServe(httpBindAddr, base.Base.BaseMux))
|
||||||
}()
|
}()
|
||||||
// Expose the matrix APIs also via libp2p
|
// Expose the matrix APIs also via libp2p
|
||||||
if base.LibP2P != nil {
|
if base.LibP2P != nil {
|
||||||
@ -197,7 +197,7 @@ func main() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
logrus.Fatal(listener.Close())
|
logrus.Fatal(listener.Close())
|
||||||
}()
|
}()
|
||||||
logrus.Fatal(http.Serve(listener, nil))
|
logrus.Fatal(http.Serve(listener, base.Base.BaseMux))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +94,6 @@ func createFederationClient(
|
|||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// Build both ends of a HTTP multiplex.
|
|
||||||
httpServer := &http.Server{
|
|
||||||
Addr: ":0",
|
|
||||||
TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){},
|
|
||||||
ReadTimeout: 15 * time.Second,
|
|
||||||
WriteTimeout: 45 * time.Second,
|
|
||||||
IdleTimeout: 60 * time.Second,
|
|
||||||
BaseContext: func(_ net.Listener) context.Context {
|
|
||||||
return context.Background()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ygg, err := yggconn.Setup(*instanceName, *instancePeer)
|
ygg, err := yggconn.Setup(*instanceName, *instancePeer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -188,13 +176,26 @@ func main() {
|
|||||||
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
||||||
|
|
||||||
httputil.SetupHTTPAPI(
|
httputil.SetupHTTPAPI(
|
||||||
http.DefaultServeMux,
|
base.BaseMux,
|
||||||
base.PublicAPIMux,
|
base.PublicAPIMux,
|
||||||
base.InternalAPIMux,
|
base.InternalAPIMux,
|
||||||
cfg,
|
cfg,
|
||||||
base.UseHTTPAPIs,
|
base.UseHTTPAPIs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Build both ends of a HTTP multiplex.
|
||||||
|
httpServer := &http.Server{
|
||||||
|
Addr: ":0",
|
||||||
|
TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){},
|
||||||
|
ReadTimeout: 15 * time.Second,
|
||||||
|
WriteTimeout: 45 * time.Second,
|
||||||
|
IdleTimeout: 60 * time.Second,
|
||||||
|
BaseContext: func(_ net.Listener) context.Context {
|
||||||
|
return context.Background()
|
||||||
|
},
|
||||||
|
Handler: base.BaseMux,
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
logrus.Info("Listening on ", ygg.DerivedServerName())
|
logrus.Info("Listening on ", ygg.DerivedServerName())
|
||||||
logrus.Fatal(httpServer.Serve(ygg))
|
logrus.Fatal(httpServer.Serve(ygg))
|
||||||
@ -202,7 +203,7 @@ func main() {
|
|||||||
go func() {
|
go func() {
|
||||||
httpBindAddr := fmt.Sprintf("localhost:%d", *instancePort)
|
httpBindAddr := fmt.Sprintf("localhost:%d", *instancePort)
|
||||||
logrus.Info("Listening on ", httpBindAddr)
|
logrus.Info("Listening on ", httpBindAddr)
|
||||||
logrus.Fatal(http.ListenAndServe(httpBindAddr, nil))
|
logrus.Fatal(http.ListenAndServe(httpBindAddr, base.BaseMux))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
|
@ -135,7 +135,7 @@ func main() {
|
|||||||
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
||||||
|
|
||||||
httputil.SetupHTTPAPI(
|
httputil.SetupHTTPAPI(
|
||||||
http.DefaultServeMux,
|
base.BaseMux,
|
||||||
base.PublicAPIMux,
|
base.PublicAPIMux,
|
||||||
base.InternalAPIMux,
|
base.InternalAPIMux,
|
||||||
cfg,
|
cfg,
|
||||||
@ -147,6 +147,7 @@ func main() {
|
|||||||
serv := http.Server{
|
serv := http.Server{
|
||||||
Addr: *httpBindAddr,
|
Addr: *httpBindAddr,
|
||||||
WriteTimeout: setup.HTTPServerTimeout,
|
WriteTimeout: setup.HTTPServerTimeout,
|
||||||
|
Handler: base.BaseMux,
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Info("Listening on ", serv.Addr)
|
logrus.Info("Listening on ", serv.Addr)
|
||||||
@ -158,6 +159,7 @@ func main() {
|
|||||||
serv := http.Server{
|
serv := http.Server{
|
||||||
Addr: *httpsBindAddr,
|
Addr: *httpsBindAddr,
|
||||||
WriteTimeout: setup.HTTPServerTimeout,
|
WriteTimeout: setup.HTTPServerTimeout,
|
||||||
|
Handler: base.BaseMux,
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Info("Listening on ", serv.Addr)
|
logrus.Info("Listening on ", serv.Addr)
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
// JSServer exposes an HTTP-like server interface which allows JS to 'send' requests to it.
|
// JSServer exposes an HTTP-like server interface which allows JS to 'send' requests to it.
|
||||||
type JSServer struct {
|
type JSServer struct {
|
||||||
// The router which will service requests
|
// The router which will service requests
|
||||||
Mux *http.ServeMux
|
Mux http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnRequestFromJS is the function that JS will invoke when there is a new request.
|
// OnRequestFromJS is the function that JS will invoke when there is a new request.
|
||||||
|
@ -19,7 +19,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/appservice"
|
"github.com/matrix-org/dendrite/appservice"
|
||||||
@ -233,7 +232,7 @@ func main() {
|
|||||||
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
monolith.AddAllPublicRoutes(base.PublicAPIMux)
|
||||||
|
|
||||||
httputil.SetupHTTPAPI(
|
httputil.SetupHTTPAPI(
|
||||||
http.DefaultServeMux,
|
base.BaseMux,
|
||||||
base.PublicAPIMux,
|
base.PublicAPIMux,
|
||||||
base.InternalAPIMux,
|
base.InternalAPIMux,
|
||||||
cfg,
|
cfg,
|
||||||
@ -245,7 +244,7 @@ func main() {
|
|||||||
go func() {
|
go func() {
|
||||||
logrus.Info("Listening on libp2p-js host ID ", node.Id)
|
logrus.Info("Listening on libp2p-js host ID ", node.Id)
|
||||||
s := JSServer{
|
s := JSServer{
|
||||||
Mux: http.DefaultServeMux,
|
Mux: base.BaseMux,
|
||||||
}
|
}
|
||||||
s.ListenAndServe("p2p")
|
s.ListenAndServe("p2p")
|
||||||
}()
|
}()
|
||||||
@ -255,7 +254,7 @@ func main() {
|
|||||||
go func() {
|
go func() {
|
||||||
logrus.Info("Listening for service-worker fetch traffic")
|
logrus.Info("Listening for service-worker fetch traffic")
|
||||||
s := JSServer{
|
s := JSServer{
|
||||||
Mux: http.DefaultServeMux,
|
Mux: base.BaseMux,
|
||||||
}
|
}
|
||||||
s.ListenAndServe("fetch")
|
s.ListenAndServe("fetch")
|
||||||
}()
|
}()
|
||||||
|
@ -35,7 +35,7 @@ func AddPublicRoutes(
|
|||||||
accountsDB accounts.Database,
|
accountsDB accounts.Database,
|
||||||
deviceDB devices.Database,
|
deviceDB devices.Database,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
keyRing *gomatrixserverlib.KeyRing,
|
keyRing gomatrixserverlib.JSONVerifier,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
asAPI appserviceAPI.AppServiceQueryAPI,
|
asAPI appserviceAPI.AppServiceQueryAPI,
|
||||||
federationSenderAPI federationSenderAPI.FederationSenderInternalAPI,
|
federationSenderAPI federationSenderAPI.FederationSenderInternalAPI,
|
||||||
@ -44,7 +44,7 @@ func AddPublicRoutes(
|
|||||||
|
|
||||||
routing.Setup(
|
routing.Setup(
|
||||||
router, cfg, rsAPI, asAPI,
|
router, cfg, rsAPI, asAPI,
|
||||||
eduAPI, federationSenderAPI, *keyRing,
|
eduAPI, federationSenderAPI, keyRing,
|
||||||
federation, accountsDB, deviceDB,
|
federation, accountsDB, deviceDB,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
102
federationapi/federationapi_test.go
Normal file
102
federationapi/federationapi_test.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package federationapi_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/federationapi"
|
||||||
|
"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/internal/test"
|
||||||
|
"github.com/matrix-org/gomatrix"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tests that event IDs with '/' in them (escaped as %2F) are correctly passed to the right handler and don't 404.
|
||||||
|
// Relevant for v3 rooms and a cause of flakey sytests as the IDs are randomly generated.
|
||||||
|
func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
|
||||||
|
_, privKey, _ := ed25519.GenerateKey(nil)
|
||||||
|
cfg := &config.Dendrite{}
|
||||||
|
cfg.Matrix.KeyID = gomatrixserverlib.KeyID("ed25519:auto")
|
||||||
|
cfg.Matrix.ServerName = gomatrixserverlib.ServerName("localhost")
|
||||||
|
cfg.Matrix.PrivateKey = privKey
|
||||||
|
cfg.Kafka.UseNaffka = true
|
||||||
|
cfg.Database.Naffka = "file::memory:"
|
||||||
|
cfg.SetDefaults()
|
||||||
|
base := setup.NewBaseDendrite(cfg, "Test", false)
|
||||||
|
keyRing := &test.NopJSONVerifier{}
|
||||||
|
fsAPI := base.FederationSenderHTTPClient()
|
||||||
|
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
|
||||||
|
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
|
||||||
|
federationapi.AddPublicRoutes(base.PublicAPIMux, cfg, nil, nil, nil, keyRing, nil, nil, fsAPI, nil)
|
||||||
|
httputil.SetupHTTPAPI(
|
||||||
|
base.BaseMux,
|
||||||
|
base.PublicAPIMux,
|
||||||
|
base.InternalAPIMux,
|
||||||
|
cfg,
|
||||||
|
base.UseHTTPAPIs,
|
||||||
|
)
|
||||||
|
baseURL, cancel := test.ListenAndServe(t, base.BaseMux, true)
|
||||||
|
defer cancel()
|
||||||
|
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))
|
||||||
|
|
||||||
|
fedCli := gomatrixserverlib.NewFederationClient(serverName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
roomVer gomatrixserverlib.RoomVersion
|
||||||
|
eventJSON string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
eventJSON: `{"auth_events":[["$Nzfbrhc3oaYVKzGM:localhost",{"sha256":"BCBHOgB4qxLPQkBd6th8ydFSyqjth/LF99VNjYffOQ0"}],["$EZzkD2BH1Gtm5v1D:localhost",{"sha256":"3dLUnDBs8/iC5DMw/ydKtmAqVZtzqqtHpsjsQPk7GJA"}]],"content":{"body":"Test Message"},"depth":11,"event_id":"$mGiPO3oGjQfCkIUw:localhost","hashes":{"sha256":"h+t+4DwIBC9UNyJ3jzyAQAAl4H3yQHVuHrm2S1JZizU"},"origin":"localhost","origin_server_ts":0,"prev_events":[["$tFr64vpiSHdLU0Qr:localhost",{"sha256":"+R07ZrIs4c4tjPFE+tmcYIGUfeLGFI/4e0OITb9uEcM"}]],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"LYFr/rW9m5/7UKBQMF5qWnG82He4VGsRESUgDmvkn5DrJRyS4TLL/7zl0Lymn3pa3q2yaTO74LQX/CRotqG1BA"}},"type":"m.room.message"}`,
|
||||||
|
roomVer: gomatrixserverlib.RoomVersionV1,
|
||||||
|
},
|
||||||
|
// single / (handlers which do not UseEncodedPath will fail this test)
|
||||||
|
// EventID: $0SFh2WJbjBs3OT+E0yl95giDKo/3Zp52HsHUUk4uPyg
|
||||||
|
{
|
||||||
|
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":8,"hashes":{"sha256":"dfK0MBn1RZZqCVJqWsn/MGY7QJHjQcwqF0unOonLCTU"},"origin":"localhost","origin_server_ts":0,"prev_events":["$1SwcZ1XY/Y8yKLjP4DzAOHN5WFBcDAZxb5vFDnW2ubA"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"INOjuWMg+GmFkUpmzhMB0bqLNs73mSvwldY1ftYIQ/B3lD9soD2OMG3AF+wgZW/I8xqzY4DOHfbnbUeYPf67BA"}},"type":"m.room.message"}`,
|
||||||
|
roomVer: gomatrixserverlib.RoomVersionV3,
|
||||||
|
},
|
||||||
|
// multiple /
|
||||||
|
// EventID: $OzENBCuVv/fnRAYCeQudIon/84/V5pxtEjQMTgi3emk
|
||||||
|
{
|
||||||
|
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":2,"hashes":{"sha256":"U5+WsiJAhiEM88J8HTjuUjPImVGVzDFD3v/WS+jb2f0"},"origin":"localhost","origin_server_ts":0,"prev_events":["$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"tKS469e9+wdWPEKB/LbBJWQ8vfOOdKgTWER5IwbSAH1CxmLvkCziUsgVu85zfzDSLoUi5mU5FHLiMTC6P/qICw"}},"type":"m.room.message"}`,
|
||||||
|
roomVer: gomatrixserverlib.RoomVersionV3,
|
||||||
|
},
|
||||||
|
// two slashes (handlers which clean paths before UseEncodedPath will fail this test)
|
||||||
|
// EventID: $EmwNBlHoSOVmCZ1cM//yv/OvxB6r4OFEIGSJea7+Amk
|
||||||
|
{
|
||||||
|
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":3917,"hashes":{"sha256":"cNAWtlHIegrji0mMA6x1rhpYCccY8W1NsWZqSpJFhjs"},"origin":"localhost","origin_server_ts":0,"prev_events":["$4GDB0bVjkWwS3G4noUZCq5oLWzpBYpwzdMcf7gj24CI"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"NKym6Kcy3u9mGUr21Hjfe3h7DfDilDhN5PqztT0QZ4NTZ+8Y7owseLolQVXp+TvNjecvzdDywsXXVvGiuQiWAQ"}},"type":"m.room.message"}`,
|
||||||
|
roomVer: gomatrixserverlib.RoomVersionV3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ev, err := gomatrixserverlib.NewEventFromTrustedJSON([]byte(tc.eventJSON), false, tc.roomVer)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to parse event: %s", err)
|
||||||
|
}
|
||||||
|
he := ev.Headered(tc.roomVer)
|
||||||
|
invReq, err := gomatrixserverlib.NewInviteV2Request(&he, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create invite v2 request: %s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, err = fedCli.SendInviteV2(context.Background(), serverName, invReq)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected an error, got none")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gerr, ok := err.(gomatrix.HTTPError)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("failed to cast response error as gomatrix.HTTPError")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t.Logf("Error: %+v", gerr)
|
||||||
|
if gerr.Code == 404 {
|
||||||
|
t.Errorf("invite event resulted in a 404")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,7 @@ func Invite(
|
|||||||
eventID string,
|
eventID string,
|
||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
rsAPI api.RoomserverInternalAPI,
|
rsAPI api.RoomserverInternalAPI,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.JSONVerifier,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
inviteReq := gomatrixserverlib.InviteV2Request{}
|
inviteReq := gomatrixserverlib.InviteV2Request{}
|
||||||
if err := json.Unmarshal(request.Content(), &inviteReq); err != nil {
|
if err := json.Unmarshal(request.Content(), &inviteReq); err != nil {
|
||||||
|
@ -143,7 +143,7 @@ func SendJoin(
|
|||||||
request *gomatrixserverlib.FederationRequest,
|
request *gomatrixserverlib.FederationRequest,
|
||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
rsAPI api.RoomserverInternalAPI,
|
rsAPI api.RoomserverInternalAPI,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.JSONVerifier,
|
||||||
roomID, eventID string,
|
roomID, eventID string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||||
|
@ -113,7 +113,7 @@ func SendLeave(
|
|||||||
request *gomatrixserverlib.FederationRequest,
|
request *gomatrixserverlib.FederationRequest,
|
||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
rsAPI api.RoomserverInternalAPI,
|
rsAPI api.RoomserverInternalAPI,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.JSONVerifier,
|
||||||
roomID, eventID string,
|
roomID, eventID string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||||
|
@ -51,7 +51,7 @@ func Setup(
|
|||||||
asAPI appserviceAPI.AppServiceQueryAPI,
|
asAPI appserviceAPI.AppServiceQueryAPI,
|
||||||
eduAPI eduserverAPI.EDUServerInputAPI,
|
eduAPI eduserverAPI.EDUServerInputAPI,
|
||||||
fsAPI federationSenderAPI.FederationSenderInternalAPI,
|
fsAPI federationSenderAPI.FederationSenderInternalAPI,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.JSONVerifier,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
accountDB accounts.Database,
|
accountDB accounts.Database,
|
||||||
deviceDB devices.Database,
|
deviceDB devices.Database,
|
||||||
|
@ -37,7 +37,7 @@ func Send(
|
|||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
rsAPI api.RoomserverInternalAPI,
|
rsAPI api.RoomserverInternalAPI,
|
||||||
eduAPI eduserverAPI.EDUServerInputAPI,
|
eduAPI eduserverAPI.EDUServerInputAPI,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.JSONVerifier,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
t := txnReq{
|
t := txnReq{
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
eduAPI "github.com/matrix-org/dendrite/eduserver/api"
|
eduAPI "github.com/matrix-org/dendrite/eduserver/api"
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
|
"github.com/matrix-org/dendrite/internal/test"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
@ -53,15 +54,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type testNopJSONVerifier struct {
|
|
||||||
// this verifier verifies nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *testNopJSONVerifier) VerifyJSONs(ctx context.Context, requests []gomatrixserverlib.VerifyJSONRequest) ([]gomatrixserverlib.VerifyJSONResult, error) {
|
|
||||||
result := make([]gomatrixserverlib.VerifyJSONResult, len(requests))
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type testEDUProducer struct {
|
type testEDUProducer struct {
|
||||||
// this producer keeps track of calls to InputTypingEvent
|
// this producer keeps track of calls to InputTypingEvent
|
||||||
invocations []eduAPI.InputTypingEventRequest
|
invocations []eduAPI.InputTypingEventRequest
|
||||||
@ -330,7 +322,7 @@ func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, fedClient txnFederat
|
|||||||
context: context.Background(),
|
context: context.Background(),
|
||||||
rsAPI: rsAPI,
|
rsAPI: rsAPI,
|
||||||
eduAPI: &testEDUProducer{},
|
eduAPI: &testEDUProducer{},
|
||||||
keys: &testNopJSONVerifier{},
|
keys: &test.NopJSONVerifier{},
|
||||||
federation: fedClient,
|
federation: fedClient,
|
||||||
haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent),
|
haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent),
|
||||||
newEvents: make(map[string]bool),
|
newEvents: make(map[string]bool),
|
||||||
|
@ -185,7 +185,7 @@ func MakeInternalAPI(metricsName string, f func(*http.Request) util.JSONResponse
|
|||||||
func MakeFedAPI(
|
func MakeFedAPI(
|
||||||
metricsName string,
|
metricsName string,
|
||||||
serverName gomatrixserverlib.ServerName,
|
serverName gomatrixserverlib.ServerName,
|
||||||
keyRing gomatrixserverlib.KeyRing,
|
keyRing gomatrixserverlib.JSONVerifier,
|
||||||
wakeup *FederationWakeups,
|
wakeup *FederationWakeups,
|
||||||
f func(*http.Request, *gomatrixserverlib.FederationRequest, map[string]string) util.JSONResponse,
|
f func(*http.Request, *gomatrixserverlib.FederationRequest, map[string]string) util.JSONResponse,
|
||||||
) http.Handler {
|
) http.Handler {
|
||||||
@ -233,9 +233,8 @@ func (f *FederationWakeups) Wakeup(ctx context.Context, origin gomatrixserverlib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics
|
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics listener
|
||||||
// listener.
|
func SetupHTTPAPI(servMux, publicApiMux, internalApiMux *mux.Router, cfg *config.Dendrite, enableHTTPAPIs bool) {
|
||||||
func SetupHTTPAPI(servMux *http.ServeMux, publicApiMux *mux.Router, internalApiMux *mux.Router, cfg *config.Dendrite, enableHTTPAPIs bool) {
|
|
||||||
if cfg.Metrics.Enabled {
|
if cfg.Metrics.Enabled {
|
||||||
servMux.Handle("/metrics", WrapHandlerInBasicAuth(promhttp.Handler(), cfg.Metrics.BasicAuth))
|
servMux.Handle("/metrics", WrapHandlerInBasicAuth(promhttp.Handler(), cfg.Metrics.BasicAuth))
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ type BaseDendrite struct {
|
|||||||
// PublicAPIMux should be used to register new public matrix api endpoints
|
// PublicAPIMux should be used to register new public matrix api endpoints
|
||||||
PublicAPIMux *mux.Router
|
PublicAPIMux *mux.Router
|
||||||
InternalAPIMux *mux.Router
|
InternalAPIMux *mux.Router
|
||||||
|
BaseMux *mux.Router // base router which created public/internal subrouters
|
||||||
UseHTTPAPIs bool
|
UseHTTPAPIs bool
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
Cfg *config.Dendrite
|
Cfg *config.Dendrite
|
||||||
@ -127,6 +128,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
|
|||||||
tracerCloser: closer,
|
tracerCloser: closer,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Caches: cache,
|
Caches: cache,
|
||||||
|
BaseMux: httpmux,
|
||||||
PublicAPIMux: httpmux.PathPrefix(httputil.PublicPathPrefix).Subrouter().UseEncodedPath(),
|
PublicAPIMux: httpmux.PathPrefix(httputil.PublicPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
InternalAPIMux: httpmux.PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
InternalAPIMux: httpmux.PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
httpClient: &client,
|
httpClient: &client,
|
||||||
@ -238,12 +240,13 @@ func (b *BaseDendrite) SetupAndServeHTTP(bindaddr string, listenaddr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
httputil.SetupHTTPAPI(
|
httputil.SetupHTTPAPI(
|
||||||
http.DefaultServeMux,
|
b.BaseMux,
|
||||||
b.PublicAPIMux,
|
b.PublicAPIMux,
|
||||||
b.InternalAPIMux,
|
b.InternalAPIMux,
|
||||||
b.Cfg,
|
b.Cfg,
|
||||||
b.UseHTTPAPIs,
|
b.UseHTTPAPIs,
|
||||||
)
|
)
|
||||||
|
serv.Handler = b.BaseMux
|
||||||
logrus.Infof("Starting %s server on %s", b.componentName, serv.Addr)
|
logrus.Infof("Starting %s server on %s", b.componentName, serv.Addr)
|
||||||
|
|
||||||
err := serv.ListenAndServe()
|
err := serv.ListenAndServe()
|
||||||
|
31
internal/test/keyring.go
Normal file
31
internal/test/keyring.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// 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 test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NopJSONVerifier is a JSONVerifier that verifies nothing and returns no errors.
|
||||||
|
type NopJSONVerifier struct {
|
||||||
|
// this verifier verifies nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *NopJSONVerifier) VerifyJSONs(ctx context.Context, requests []gomatrixserverlib.VerifyJSONRequest) ([]gomatrixserverlib.VerifyJSONResult, error) {
|
||||||
|
result := make([]gomatrixserverlib.VerifyJSONResult, len(requests))
|
||||||
|
return result, nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2017 Vector Creations Ltd
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -15,11 +15,16 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
)
|
)
|
||||||
@ -103,3 +108,46 @@ func StartProxy(bindAddr string, cfg *config.Dendrite) (*exec.Cmd, chan error) {
|
|||||||
proxyArgs,
|
proxyArgs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListenAndServe will listen on a random high-numbered port and attach the given router.
|
||||||
|
// Returns the base URL to send requests to. Call `cancel` to shutdown the server, which will block until it has closed.
|
||||||
|
func ListenAndServe(t *testing.T, router http.Handler, useTLS bool) (apiURL string, cancel func()) {
|
||||||
|
listener, err := net.Listen("tcp", ":0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to listen: %s", err)
|
||||||
|
}
|
||||||
|
port := listener.Addr().(*net.TCPAddr).Port
|
||||||
|
srv := http.Server{}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
srv.Handler = router
|
||||||
|
var err error
|
||||||
|
if useTLS {
|
||||||
|
certFile := filepath.Join(os.TempDir(), "dendrite.cert")
|
||||||
|
keyFile := filepath.Join(os.TempDir(), "dendrite.key")
|
||||||
|
err = NewTLSKey(keyFile, certFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("failed to generate tls key/cert: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = srv.ServeTLS(listener, certFile, keyFile)
|
||||||
|
} else {
|
||||||
|
err = srv.Serve(listener)
|
||||||
|
}
|
||||||
|
if err != nil && err != http.ErrServerClosed {
|
||||||
|
t.Logf("Listen failed: %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
secure := ""
|
||||||
|
if useTLS {
|
||||||
|
secure = "s"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("http%s://localhost:%d", secure, port), func() {
|
||||||
|
_ = srv.Shutdown(context.Background())
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,16 +3,15 @@ package userapi_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
"github.com/matrix-org/dendrite/internal/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/internal/test"
|
||||||
"github.com/matrix-org/dendrite/userapi"
|
"github.com/matrix-org/dendrite/userapi"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/dendrite/userapi/inthttp"
|
"github.com/matrix-org/dendrite/userapi/inthttp"
|
||||||
@ -99,7 +98,7 @@ func TestQueryProfile(t *testing.T) {
|
|||||||
t.Run("HTTP API", func(t *testing.T) {
|
t.Run("HTTP API", func(t *testing.T) {
|
||||||
router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter()
|
router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter()
|
||||||
userapi.AddInternalRoutes(router, userAPI)
|
userapi.AddInternalRoutes(router, userAPI)
|
||||||
apiURL, cancel := listenAndServe(t, router)
|
apiURL, cancel := test.ListenAndServe(t, router, false)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
httpAPI, err := inthttp.NewUserAPIClient(apiURL, &http.Client{})
|
httpAPI, err := inthttp.NewUserAPIClient(apiURL, &http.Client{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -111,28 +110,3 @@ func TestQueryProfile(t *testing.T) {
|
|||||||
runCases(userAPI)
|
runCases(userAPI)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func listenAndServe(t *testing.T, router *mux.Router) (apiURL string, cancel func()) {
|
|
||||||
listener, err := net.Listen("tcp", ":0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to listen: %s", err)
|
|
||||||
}
|
|
||||||
port := listener.Addr().(*net.TCPAddr).Port
|
|
||||||
srv := http.Server{}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
srv.Handler = router
|
|
||||||
err := srv.Serve(listener)
|
|
||||||
if err != nil && err != http.ErrServerClosed {
|
|
||||||
t.Logf("Listen failed: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return fmt.Sprintf("http://localhost:%d", port), func() {
|
|
||||||
srv.Shutdown(context.Background())
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user