From fc0e74ae0f02b7bb9d71d739660deef824ddbd33 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 16 Jun 2020 14:29:11 +0100 Subject: [PATCH] Fix media API for demos and possibly Synapse (#1134) * Fix media API for demos and possibly Synapse * User API * goimports --- cmd/dendrite-demo-libp2p/main.go | 13 ++++++++ cmd/dendrite-demo-yggdrasil/main.go | 34 ++++++++++----------- cmd/dendrite-demo-yggdrasil/yggconn/node.go | 18 +++++++++++ cmd/dendrite-media-api-server/main.go | 4 ++- cmd/dendrite-monolith-server/main.go | 2 ++ cmd/dendritejs/main.go | 6 ++++ internal/setup/monolith.go | 3 +- mediaapi/mediaapi.go | 6 ++-- mediaapi/routing/routing.go | 10 ++++-- 9 files changed, 71 insertions(+), 25 deletions(-) diff --git a/cmd/dendrite-demo-libp2p/main.go b/cmd/dendrite-demo-libp2p/main.go index 51e1e2d5..6fb3003c 100644 --- a/cmd/dendrite-demo-libp2p/main.go +++ b/cmd/dendrite-demo-libp2p/main.go @@ -80,6 +80,17 @@ func createFederationClient( ) } +func createClient( + base *P2PDendrite, +) *gomatrixserverlib.Client { + tr := &http.Transport{} + tr.RegisterProtocol( + "matrix", + p2phttp.NewTransport(base.LibP2P, p2phttp.ProtocolOption("/matrix")), + ) + return gomatrixserverlib.NewClientWithTransport(tr) +} + func main() { instanceName := flag.String("name", "dendrite-p2p", "the name of this P2P demo instance") instancePort := flag.Int("port", 8080, "the port that the client API will listen on") @@ -102,6 +113,7 @@ func main() { } cfg := config.Dendrite{} + cfg.SetDefaults() cfg.Matrix.ServerName = "p2p" cfg.Matrix.PrivateKey = privKey cfg.Matrix.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName)) @@ -159,6 +171,7 @@ func main() { Config: base.Base.Cfg, AccountDB: accountDB, DeviceDB: deviceDB, + Client: createClient(base), FedClient: federation, KeyRing: keyRing, KafkaConsumer: base.Base.KafkaConsumer, diff --git a/cmd/dendrite-demo-yggdrasil/main.go b/cmd/dendrite-demo-yggdrasil/main.go index c6a7286e..87e2246f 100644 --- a/cmd/dendrite-demo-yggdrasil/main.go +++ b/cmd/dendrite-demo-yggdrasil/main.go @@ -16,18 +16,14 @@ package main import ( "context" - "crypto/ed25519" "crypto/tls" - "encoding/hex" "flag" "fmt" "net" "net/http" - "strings" "time" "github.com/matrix-org/dendrite/appservice" - "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert" "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/embed" "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/signing" "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/yggconn" @@ -63,26 +59,13 @@ func (y *yggroundtripper) RoundTrip(req *http.Request) (*http.Response, error) { func createFederationClient( base *setup.BaseDendrite, n *yggconn.Node, ) *gomatrixserverlib.FederationClient { - yggdialer := func(_, address string) (net.Conn, error) { - tokens := strings.Split(address, ":") - raw, err := hex.DecodeString(tokens[0]) - if err != nil { - return nil, fmt.Errorf("hex.DecodeString: %w", err) - } - converted := convert.Ed25519PublicKeyToCurve25519(ed25519.PublicKey(raw)) - convhex := hex.EncodeToString(converted) - return n.Dial("curve25519", convhex) - } - yggdialerctx := func(ctx context.Context, network, address string) (net.Conn, error) { - return yggdialer(network, address) - } tr := &http.Transport{} tr.RegisterProtocol( "matrix", &yggroundtripper{ inner: &http.Transport{ ResponseHeaderTimeout: 15 * time.Second, IdleConnTimeout: 60 * time.Second, - DialContext: yggdialerctx, + DialContext: n.DialerContext, }, }, ) @@ -91,6 +74,20 @@ func createFederationClient( ) } +func createClient(n *yggconn.Node) *gomatrixserverlib.Client { + tr := &http.Transport{} + tr.RegisterProtocol( + "matrix", &yggroundtripper{ + inner: &http.Transport{ + ResponseHeaderTimeout: 15 * time.Second, + IdleConnTimeout: 60 * time.Second, + DialContext: n.DialerContext, + }, + }, + ) + return gomatrixserverlib.NewClientWithTransport(tr) +} + // nolint:gocyclo func main() { flag.Parse() @@ -162,6 +159,7 @@ func main() { Config: base.Cfg, AccountDB: accountDB, DeviceDB: deviceDB, + Client: createClient(ygg), FedClient: federation, KeyRing: keyRing, KafkaConsumer: base.KafkaConsumer, diff --git a/cmd/dendrite-demo-yggdrasil/yggconn/node.go b/cmd/dendrite-demo-yggdrasil/yggconn/node.go index a625f8d8..b225e1cf 100644 --- a/cmd/dendrite-demo-yggdrasil/yggconn/node.go +++ b/cmd/dendrite-demo-yggdrasil/yggconn/node.go @@ -15,13 +15,16 @@ package yggconn import ( + "context" "crypto/ed25519" "encoding/hex" "encoding/json" "fmt" "io/ioutil" "log" + "net" "os" + "strings" "sync" "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert" @@ -48,6 +51,21 @@ type Node struct { incoming chan *yamux.Stream } +func (n *Node) Dialer(_, address string) (net.Conn, error) { + tokens := strings.Split(address, ":") + raw, err := hex.DecodeString(tokens[0]) + if err != nil { + return nil, fmt.Errorf("hex.DecodeString: %w", err) + } + converted := convert.Ed25519PublicKeyToCurve25519(ed25519.PublicKey(raw)) + convhex := hex.EncodeToString(converted) + return n.Dial("curve25519", convhex) +} + +func (n *Node) DialerContext(ctx context.Context, network, address string) (net.Conn, error) { + return n.Dialer(network, address) +} + // nolint:gocyclo func Setup(instanceName, instancePeer string) (*Node, error) { n := &Node{ diff --git a/cmd/dendrite-media-api-server/main.go b/cmd/dendrite-media-api-server/main.go index 8fd80d7b..1582a33a 100644 --- a/cmd/dendrite-media-api-server/main.go +++ b/cmd/dendrite-media-api-server/main.go @@ -17,6 +17,7 @@ package main import ( "github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/mediaapi" + "github.com/matrix-org/gomatrixserverlib" ) func main() { @@ -25,8 +26,9 @@ func main() { defer base.Close() // nolint: errcheck userAPI := base.UserAPIClient() + client := gomatrixserverlib.NewClient() - mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI) + mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI, client) base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI)) diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go index 675474b8..16e274fc 100644 --- a/cmd/dendrite-monolith-server/main.go +++ b/cmd/dendrite-monolith-server/main.go @@ -31,6 +31,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/serverkeyapi" "github.com/matrix-org/dendrite/userapi" + "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) @@ -126,6 +127,7 @@ func main() { Config: base.Cfg, AccountDB: accountDB, DeviceDB: deviceDB, + Client: gomatrixserverlib.NewClient(), FedClient: federation, KeyRing: keyRing, KafkaConsumer: base.KafkaConsumer, diff --git a/cmd/dendritejs/main.go b/cmd/dendritejs/main.go index 7930c28d..aa919212 100644 --- a/cmd/dendritejs/main.go +++ b/cmd/dendritejs/main.go @@ -145,6 +145,11 @@ func createFederationClient(cfg *config.Dendrite, node *go_http_js_libp2p.P2pLoc return fed } +func createClient(node *go_http_js_libp2p.P2pLocalNode) *gomatrixserverlib.Client { + tr := go_http_js_libp2p.NewP2pTransport(node) + return gomatrixserverlib.NewClientWithTransport(tr) +} + func createP2PNode(privKey ed25519.PrivateKey) (serverName string, node *go_http_js_libp2p.P2pLocalNode) { hosted := "/dns4/rendezvous.matrix.org/tcp/8443/wss/p2p-websocket-star/" node = go_http_js_libp2p.NewP2pLocalNode("org.matrix.p2p.experiment", privKey.Seed(), []string{hosted}, "p2p") @@ -218,6 +223,7 @@ func main() { Config: base.Cfg, AccountDB: accountDB, DeviceDB: deviceDB, + Client: createClient(node), FedClient: federation, KeyRing: &keyRing, KafkaConsumer: base.KafkaConsumer, diff --git a/internal/setup/monolith.go b/internal/setup/monolith.go index f28fea8f..b202aa71 100644 --- a/internal/setup/monolith.go +++ b/internal/setup/monolith.go @@ -45,6 +45,7 @@ type Monolith struct { DeviceDB devices.Database AccountDB accounts.Database KeyRing *gomatrixserverlib.KeyRing + Client *gomatrixserverlib.Client FedClient *gomatrixserverlib.FederationClient KafkaConsumer sarama.Consumer KafkaProducer sarama.SyncProducer @@ -80,7 +81,7 @@ func (m *Monolith) AddAllPublicRoutes(publicMux *mux.Router) { m.KeyRing, m.RoomserverAPI, m.AppserviceAPI, m.FederationSenderAPI, m.EDUInternalAPI, ) - mediaapi.AddPublicRoutes(publicMux, m.Config, m.UserAPI) + mediaapi.AddPublicRoutes(publicMux, m.Config, m.UserAPI, m.Client) publicroomsapi.AddPublicRoutes( publicMux, m.Config, m.KafkaConsumer, m.UserAPI, m.PublicRoomsDB, m.RoomserverAPI, m.FedClient, m.ExtPublicRoomsProvider, diff --git a/mediaapi/mediaapi.go b/mediaapi/mediaapi.go index 9219ba20..290ef46e 100644 --- a/mediaapi/mediaapi.go +++ b/mediaapi/mediaapi.go @@ -26,7 +26,9 @@ import ( // AddPublicRoutes sets up and registers HTTP handlers for the MediaAPI component. func AddPublicRoutes( - router *mux.Router, cfg *config.Dendrite, userAPI userapi.UserInternalAPI, + router *mux.Router, cfg *config.Dendrite, + userAPI userapi.UserInternalAPI, + client *gomatrixserverlib.Client, ) { mediaDB, err := storage.Open(string(cfg.Database.MediaAPI), cfg.DbProperties()) if err != nil { @@ -34,6 +36,6 @@ func AddPublicRoutes( } routing.Setup( - router, cfg, mediaDB, userAPI, gomatrixserverlib.NewClient(), + router, cfg, mediaDB, userAPI, client, ) } diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go index 71804606..13f84c33 100644 --- a/mediaapi/routing/routing.go +++ b/mediaapi/routing/routing.go @@ -32,6 +32,7 @@ import ( ) const pathPrefixR0 = "/media/r0" +const pathPrefixV1 = "/media/v1" // TODO: remove when synapse is fixed // Setup registers the media API HTTP handlers // @@ -46,6 +47,7 @@ func Setup( client *gomatrixserverlib.Client, ) { r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter() + v1mux := publicAPIMux.PathPrefix(pathPrefixV1).Subrouter() activeThumbnailGeneration := &types.ActiveThumbnailGeneration{ PathToResult: map[string]*types.ThumbnailGenerationResult{}, @@ -60,9 +62,11 @@ func Setup( activeRemoteRequests := &types.ActiveRemoteRequests{ MXCToResult: map[string]*types.RemoteRequestResult{}, } - r0mux.Handle("/download/{serverName}/{mediaId}", - makeDownloadAPI("download", cfg, db, client, activeRemoteRequests, activeThumbnailGeneration), - ).Methods(http.MethodGet, http.MethodOptions) + + downloadHandler := makeDownloadAPI("download", cfg, db, client, activeRemoteRequests, activeThumbnailGeneration) + r0mux.Handle("/download/{serverName}/{mediaId}", downloadHandler).Methods(http.MethodGet, http.MethodOptions) + v1mux.Handle("/download/{serverName}/{mediaId}", downloadHandler).Methods(http.MethodGet, http.MethodOptions) // TODO: remove when synapse is fixed + r0mux.Handle("/thumbnail/{serverName}/{mediaId}", makeDownloadAPI("thumbnail", cfg, db, client, activeRemoteRequests, activeThumbnailGeneration), ).Methods(http.MethodGet, http.MethodOptions)