mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-26 08:13:09 -06:00
Merge branch 'master' into eachchatmaster
This commit is contained in:
commit
3982ecdbcc
|
|
@ -1,7 +1,7 @@
|
|||
# Dendrite [](https://buildkite.com/matrix-dot-org/dendrite) [](https://matrix.to/#/#dendrite:matrix.org) [](https://matrix.to/#/#dendrite-dev:matrix.org)
|
||||
|
||||
Dendrite is a second-generation Matrix homeserver written in Go.
|
||||
It intends to provide an **efficient**, **reliable** and **scalable** alternative to Synapse:
|
||||
It intends to provide an **efficient**, **reliable** and **scalable** alternative to [Synapse](https://github.com/matrix-org/synapse):
|
||||
- Efficient: A small memory footprint with better baseline performance than an out-of-the-box Synapse.
|
||||
- Reliable: Implements the Matrix specification as written, using the
|
||||
[same test suite](https://github.com/matrix-org/sytest) as Synapse as well as
|
||||
|
|
|
|||
|
|
@ -32,14 +32,18 @@ INSERT OR IGNORE INTO appservice_counters (name, last_id) VALUES('txn_id', 1);
|
|||
`
|
||||
|
||||
const selectTxnIDSQL = `
|
||||
SELECT last_id FROM appservice_counters WHERE name='txn_id';
|
||||
UPDATE appservice_counters SET last_id=last_id+1 WHERE name='txn_id';
|
||||
SELECT last_id FROM appservice_counters WHERE name='txn_id'
|
||||
`
|
||||
|
||||
const updateTxnIDSQL = `
|
||||
UPDATE appservice_counters SET last_id=last_id+1 WHERE name='txn_id'
|
||||
`
|
||||
|
||||
type txnStatements struct {
|
||||
db *sql.DB
|
||||
writer sqlutil.Writer
|
||||
selectTxnIDStmt *sql.Stmt
|
||||
updateTxnIDStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (s *txnStatements) prepare(db *sql.DB, writer sqlutil.Writer) (err error) {
|
||||
|
|
@ -54,6 +58,10 @@ func (s *txnStatements) prepare(db *sql.DB, writer sqlutil.Writer) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
if s.updateTxnIDStmt, err = db.Prepare(updateTxnIDSQL); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +71,11 @@ func (s *txnStatements) selectTxnID(
|
|||
) (txnID int, err error) {
|
||||
err = s.writer.Do(s.db, nil, func(txn *sql.Tx) error {
|
||||
err := s.selectTxnIDStmt.QueryRowContext(ctx).Scan(&txnID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.updateTxnIDStmt.ExecContext(ctx)
|
||||
return err
|
||||
})
|
||||
return
|
||||
|
|
|
|||
|
|
@ -37,19 +37,21 @@ runtime config should come from. The mounted folder must contain:
|
|||
To generate keys:
|
||||
|
||||
```
|
||||
go run github.com/matrix-org/dendrite/cmd/generate-keys \
|
||||
--private-key=matrix_key.pem \
|
||||
--tls-cert=server.crt \
|
||||
--tls-key=server.key
|
||||
docker run --rm --entrypoint="" \
|
||||
-v $(pwd):/mnt \
|
||||
matrixdotorg/dendrite-monolith:latest \
|
||||
/usr/bin/generate-keys \
|
||||
-private-key /mnt/matrix_key.pem \
|
||||
-tls-cert /mnt/server.crt \
|
||||
-tls-key /mnt/server.key
|
||||
```
|
||||
|
||||
The key files will now exist in your current working directory, and can be mounted into place.
|
||||
|
||||
## Starting Dendrite as a monolith deployment
|
||||
|
||||
Create your config based on the `dendrite.yaml` configuration file in the `docker/config`
|
||||
folder in the [Dendrite repository](https://github.com/matrix-org/dendrite). Additionally,
|
||||
make the following changes to the configuration:
|
||||
|
||||
- Enable Naffka: `use_naffka: true`
|
||||
folder in the [Dendrite repository](https://github.com/matrix-org/dendrite).
|
||||
|
||||
Once in place, start the PostgreSQL dependency:
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ do
|
|||
case "$option"
|
||||
in
|
||||
a) gomobile bind -v -target android -trimpath -ldflags="-s -w" github.com/matrix-org/dendrite/build/gobind-pinecone ;;
|
||||
i) gomobile bind -v -target ios -trimpath -ldflags="-s -w" github.com/matrix-org/dendrite/build/gobind-pinecone ;;
|
||||
i) gomobile bind -v -target ios -trimpath -ldflags="" github.com/matrix-org/dendrite/build/gobind-pinecone ;;
|
||||
*) echo "No target specified, specify -a or -i"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -37,15 +36,16 @@ import (
|
|||
userapiAPI "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.uber.org/atomic"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/h2c"
|
||||
|
||||
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
||||
"github.com/matrix-org/pinecone/router"
|
||||
pineconeRouter "github.com/matrix-org/pinecone/router"
|
||||
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
||||
"github.com/matrix-org/pinecone/types"
|
||||
pineconeTypes "github.com/matrix-org/pinecone/types"
|
||||
|
||||
_ "golang.org/x/mobile/bind"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -55,19 +55,19 @@ const (
|
|||
)
|
||||
|
||||
type DendriteMonolith struct {
|
||||
logger logrus.Logger
|
||||
PineconeRouter *pineconeRouter.Router
|
||||
PineconeMulticast *pineconeMulticast.Multicast
|
||||
PineconeQUIC *pineconeSessions.Sessions
|
||||
StorageDirectory string
|
||||
CacheDirectory string
|
||||
staticPeerURI string
|
||||
staticPeerMutex sync.RWMutex
|
||||
staticPeerAttempts atomic.Uint32
|
||||
listener net.Listener
|
||||
httpServer *http.Server
|
||||
processContext *process.ProcessContext
|
||||
userAPI userapiAPI.UserInternalAPI
|
||||
logger logrus.Logger
|
||||
PineconeRouter *pineconeRouter.Router
|
||||
PineconeMulticast *pineconeMulticast.Multicast
|
||||
PineconeQUIC *pineconeSessions.Sessions
|
||||
StorageDirectory string
|
||||
CacheDirectory string
|
||||
staticPeerURI string
|
||||
staticPeerMutex sync.RWMutex
|
||||
staticPeerAttempt chan struct{}
|
||||
listener net.Listener
|
||||
httpServer *http.Server
|
||||
processContext *process.ProcessContext
|
||||
userAPI userapiAPI.UserInternalAPI
|
||||
}
|
||||
|
||||
func (m *DendriteMonolith) BaseURL() string {
|
||||
|
|
@ -97,7 +97,9 @@ func (m *DendriteMonolith) SetStaticPeer(uri string) {
|
|||
m.staticPeerMutex.Unlock()
|
||||
m.DisconnectType(pineconeRouter.PeerTypeRemote)
|
||||
if uri != "" {
|
||||
m.staticPeerConnect()
|
||||
go func() {
|
||||
m.staticPeerAttempt <- struct{}{}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -193,17 +195,27 @@ func (m *DendriteMonolith) RegisterDevice(localpart, deviceID string) (string, e
|
|||
}
|
||||
|
||||
func (m *DendriteMonolith) staticPeerConnect() {
|
||||
m.staticPeerMutex.RLock()
|
||||
uri := m.staticPeerURI
|
||||
m.staticPeerMutex.RUnlock()
|
||||
if uri == "" {
|
||||
return
|
||||
attempt := func() {
|
||||
if m.PineconeRouter.PeerCount(router.PeerTypeRemote) == 0 {
|
||||
m.staticPeerMutex.RLock()
|
||||
uri := m.staticPeerURI
|
||||
m.staticPeerMutex.RUnlock()
|
||||
if uri == "" {
|
||||
return
|
||||
}
|
||||
if err := conn.ConnectToPeer(m.PineconeRouter, uri); err != nil {
|
||||
logrus.WithError(err).Error("Failed to connect to static peer")
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := conn.ConnectToPeer(m.PineconeRouter, uri); err != nil {
|
||||
exp := time.Second * time.Duration(math.Exp2(float64(m.staticPeerAttempts.Inc())))
|
||||
time.AfterFunc(exp, m.staticPeerConnect)
|
||||
} else {
|
||||
m.staticPeerAttempts.Store(0)
|
||||
for {
|
||||
select {
|
||||
case <-m.processContext.Context().Done():
|
||||
case <-m.staticPeerAttempt:
|
||||
attempt()
|
||||
case <-time.After(time.Second * 5):
|
||||
attempt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,13 +258,6 @@ func (m *DendriteMonolith) Start() {
|
|||
m.PineconeQUIC = pineconeSessions.NewSessions(logger, m.PineconeRouter)
|
||||
m.PineconeMulticast = pineconeMulticast.NewMulticast(logger, m.PineconeRouter)
|
||||
|
||||
m.PineconeRouter.SetDisconnectedCallback(func(port pineconeTypes.SwitchPortID, public pineconeTypes.PublicKey, peertype int, err error) {
|
||||
if peertype == pineconeRouter.PeerTypeRemote {
|
||||
m.staticPeerAttempts.Store(0)
|
||||
time.AfterFunc(time.Second, m.staticPeerConnect)
|
||||
}
|
||||
})
|
||||
|
||||
prefix := hex.EncodeToString(pk)
|
||||
cfg := &config.Dendrite{}
|
||||
cfg.Defaults()
|
||||
|
|
@ -272,6 +277,7 @@ func (m *DendriteMonolith) Start() {
|
|||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-appservice.db", m.StorageDirectory, prefix))
|
||||
cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
||||
cfg.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
||||
cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
|
||||
if err := cfg.Derive(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -290,7 +296,7 @@ func (m *DendriteMonolith) Start() {
|
|||
)
|
||||
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, true,
|
||||
)
|
||||
|
||||
keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, fsAPI)
|
||||
|
|
@ -356,8 +362,12 @@ func (m *DendriteMonolith) Start() {
|
|||
},
|
||||
Handler: h2c.NewHandler(pMux, h2s),
|
||||
}
|
||||
|
||||
m.processContext = base.ProcessContext
|
||||
|
||||
m.staticPeerAttempt = make(chan struct{}, 1)
|
||||
go m.staticPeerConnect()
|
||||
|
||||
go func() {
|
||||
m.logger.Info("Listening on ", cfg.Global.ServerName)
|
||||
m.logger.Fatal(m.httpServer.Serve(m.PineconeQUIC))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"github.com/matrix-org/dendrite/userapi"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
_ "golang.org/x/mobile/bind"
|
||||
)
|
||||
|
||||
type DendriteMonolith struct {
|
||||
|
|
@ -118,7 +120,7 @@ func (m *DendriteMonolith) Start() {
|
|||
)
|
||||
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, true,
|
||||
)
|
||||
|
||||
keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, federation)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func GetAccountData(
|
|||
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.Forbidden("data not found"),
|
||||
JSON: jsonerror.NotFound("data not found"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,18 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/matrix-org/dendrite/setup"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
const usage = `Usage: %s
|
||||
|
|
@ -33,7 +38,15 @@ Creates a new user account on the homeserver.
|
|||
|
||||
Example:
|
||||
|
||||
./create-account --config dendrite.yaml --username alice --password foobarbaz
|
||||
# provide password by parameter
|
||||
%s --config dendrite.yaml -username alice -password foobarbaz
|
||||
# use password from file
|
||||
%s --config dendrite.yaml -username alice -passwordfile my.pass
|
||||
# ask user to provide password
|
||||
%s --config dendrite.yaml -username alice -ask-pass
|
||||
# read password from stdin
|
||||
%s --config dendrite.yaml -username alice -passwordstdin < my.pass
|
||||
cat my.pass | %s --config dendrite.yaml -username alice -passwordstdin
|
||||
|
||||
Arguments:
|
||||
|
||||
|
|
@ -42,11 +55,15 @@ Arguments:
|
|||
var (
|
||||
username = flag.String("username", "", "The username of the account to register (specify the localpart only, e.g. 'alice' for '@alice:domain.com')")
|
||||
password = flag.String("password", "", "The password to associate with the account (optional, account will be password-less if not specified)")
|
||||
pwdFile = flag.String("passwordfile", "", "The file to use for the password (e.g. for automated account creation)")
|
||||
pwdStdin = flag.Bool("passwordstdin", false, "Reads the password from stdin")
|
||||
askPass = flag.Bool("ask-pass", false, "Ask for the password to use")
|
||||
)
|
||||
|
||||
func main() {
|
||||
name := os.Args[0]
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, usage, os.Args[0])
|
||||
_, _ = fmt.Fprintf(os.Stderr, usage, name, name, name, name, name, name)
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
cfg := setup.ParseFlags(true)
|
||||
|
|
@ -56,6 +73,8 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
pass := getPassword(password, pwdFile, pwdStdin, askPass, os.Stdin)
|
||||
|
||||
accountDB, err := accounts.NewDatabase(&config.DatabaseOptions{
|
||||
ConnectionString: cfg.UserAPI.AccountDatabase.ConnectionString,
|
||||
}, cfg.Global.ServerName, bcrypt.DefaultCost, cfg.UserAPI.OpenIDTokenLifetimeMS)
|
||||
|
|
@ -63,10 +82,61 @@ func main() {
|
|||
logrus.Fatalln("Failed to connect to the database:", err.Error())
|
||||
}
|
||||
|
||||
_, err = accountDB.CreateAccount(context.Background(), *username, *password, "")
|
||||
_, err = accountDB.CreateAccount(context.Background(), *username, pass, "")
|
||||
if err != nil {
|
||||
logrus.Fatalln("Failed to create the account:", err.Error())
|
||||
}
|
||||
|
||||
logrus.Infoln("Created account", *username)
|
||||
}
|
||||
|
||||
func getPassword(password, pwdFile *string, pwdStdin, askPass *bool, r io.Reader) string {
|
||||
// no password option set, use empty password
|
||||
if password == nil && pwdFile == nil && pwdStdin == nil && askPass == nil {
|
||||
return ""
|
||||
}
|
||||
// password defined as parameter
|
||||
if password != nil && *password != "" {
|
||||
return *password
|
||||
}
|
||||
|
||||
// read password from file
|
||||
if pwdFile != nil && *pwdFile != "" {
|
||||
pw, err := ioutil.ReadFile(*pwdFile)
|
||||
if err != nil {
|
||||
logrus.Fatalln("Unable to read password from file:", err)
|
||||
}
|
||||
return strings.TrimSpace(string(pw))
|
||||
}
|
||||
|
||||
// read password from stdin
|
||||
if pwdStdin != nil && *pwdStdin {
|
||||
data, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
logrus.Fatalln("Unable to read password from stdin:", err)
|
||||
}
|
||||
return strings.TrimSpace(string(data))
|
||||
}
|
||||
|
||||
// ask the user to provide the password
|
||||
if *askPass {
|
||||
fmt.Print("Enter Password: ")
|
||||
bytePassword, err := term.ReadPassword(syscall.Stdin)
|
||||
if err != nil {
|
||||
logrus.Fatalln("Unable to read password:", err)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Print("Confirm Password: ")
|
||||
bytePassword2, err := term.ReadPassword(syscall.Stdin)
|
||||
if err != nil {
|
||||
logrus.Fatalln("Unable to read password:", err)
|
||||
}
|
||||
fmt.Println()
|
||||
if strings.TrimSpace(string(bytePassword)) != strings.TrimSpace(string(bytePassword2)) {
|
||||
logrus.Fatalln("Entered passwords don't match")
|
||||
}
|
||||
return strings.TrimSpace(string(bytePassword))
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
|
|||
62
cmd/create-account/main_test.go
Normal file
62
cmd/create-account/main_test.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_getPassword(t *testing.T) {
|
||||
type args struct {
|
||||
password *string
|
||||
pwdFile *string
|
||||
pwdStdin *bool
|
||||
askPass *bool
|
||||
reader io.Reader
|
||||
}
|
||||
|
||||
pass := "mySecretPass"
|
||||
passwordFile := "testdata/my.pass"
|
||||
passwordStdin := true
|
||||
reader := &bytes.Buffer{}
|
||||
_, err := reader.WriteString(pass)
|
||||
if err != nil {
|
||||
t.Errorf("unable to write to buffer: %+v", err)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "no password defined",
|
||||
args: args{},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "password defined",
|
||||
args: args{password: &pass},
|
||||
want: pass,
|
||||
},
|
||||
{
|
||||
name: "pwdFile defined",
|
||||
args: args{pwdFile: &passwordFile},
|
||||
want: pass,
|
||||
},
|
||||
{
|
||||
name: "read pass from stdin defined",
|
||||
args: args{
|
||||
pwdStdin: &passwordStdin,
|
||||
reader: reader,
|
||||
},
|
||||
want: pass,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getPassword(tt.args.password, tt.args.pwdFile, tt.args.pwdStdin, tt.args.askPass, tt.args.reader); got != tt.want {
|
||||
t.Errorf("getPassword() = '%v', want '%v'", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
1
cmd/create-account/testdata/my.pass
vendored
Normal file
1
cmd/create-account/testdata/my.pass
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
mySecretPass
|
||||
|
|
@ -166,7 +166,7 @@ func main() {
|
|||
asAPI := appservice.NewInternalAPI(&base.Base, userAPI, rsAPI)
|
||||
rsAPI.SetAppserviceAPI(asAPI)
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
&base.Base, federation, rsAPI, keyRing,
|
||||
&base.Base, federation, rsAPI, keyRing, true,
|
||||
)
|
||||
rsAPI.SetFederationSenderAPI(fsAPI)
|
||||
provider := newPublicRoomsProvider(base.LibP2PPubsub, rsAPI)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -48,12 +47,11 @@ import (
|
|||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"go.uber.org/atomic"
|
||||
|
||||
pineconeMulticast "github.com/matrix-org/pinecone/multicast"
|
||||
"github.com/matrix-org/pinecone/router"
|
||||
pineconeRouter "github.com/matrix-org/pinecone/router"
|
||||
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
||||
pineconeTypes "github.com/matrix-org/pinecone/types"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -123,27 +121,23 @@ func main() {
|
|||
pMulticast := pineconeMulticast.NewMulticast(logger, pRouter)
|
||||
pMulticast.Start()
|
||||
|
||||
var staticPeerAttempts atomic.Uint32
|
||||
var connectToStaticPeer func()
|
||||
connectToStaticPeer = func() {
|
||||
uri := *instancePeer
|
||||
if uri == "" {
|
||||
return
|
||||
connectToStaticPeer := func() {
|
||||
attempt := func() {
|
||||
if pRouter.PeerCount(router.PeerTypeRemote) == 0 {
|
||||
uri := *instancePeer
|
||||
if uri == "" {
|
||||
return
|
||||
}
|
||||
if err := conn.ConnectToPeer(pRouter, uri); err != nil {
|
||||
logrus.WithError(err).Error("Failed to connect to static peer")
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := conn.ConnectToPeer(pRouter, uri); err != nil {
|
||||
exp := time.Second * time.Duration(math.Exp2(float64(staticPeerAttempts.Inc())))
|
||||
time.AfterFunc(exp, connectToStaticPeer)
|
||||
} else {
|
||||
staticPeerAttempts.Store(0)
|
||||
for {
|
||||
attempt()
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}
|
||||
pRouter.SetDisconnectedCallback(func(port pineconeTypes.SwitchPortID, public pineconeTypes.PublicKey, peertype int, err error) {
|
||||
if peertype == pineconeRouter.PeerTypeRemote && err != nil {
|
||||
staticPeerAttempts.Store(0)
|
||||
time.AfterFunc(time.Second, connectToStaticPeer)
|
||||
}
|
||||
})
|
||||
go connectToStaticPeer()
|
||||
|
||||
cfg := &config.Dendrite{}
|
||||
cfg.Defaults()
|
||||
|
|
@ -161,6 +155,7 @@ func main() {
|
|||
cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName))
|
||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
|
||||
cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
|
||||
if err := cfg.Derive(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -179,7 +174,7 @@ func main() {
|
|||
)
|
||||
rsAPI := rsComponent
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, true,
|
||||
)
|
||||
|
||||
keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, fsAPI)
|
||||
|
|
@ -256,6 +251,7 @@ func main() {
|
|||
Handler: pMux,
|
||||
}
|
||||
|
||||
go connectToStaticPeer()
|
||||
go func() {
|
||||
pubkey := pRouter.PublicKey()
|
||||
logrus.Info("Listening on ", hex.EncodeToString(pubkey[:]))
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func main() {
|
|||
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
|
||||
rsAPI.SetAppserviceAPI(asAPI)
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, true,
|
||||
)
|
||||
|
||||
ygg.SetSessionFunc(func(address string) {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func main() {
|
|||
}
|
||||
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, false,
|
||||
)
|
||||
if base.UseHTTPAPIs {
|
||||
federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ func FederationSender(base *setup.BaseDendrite, cfg *config.Dendrite) {
|
|||
|
||||
rsAPI := base.RoomserverHTTPClient()
|
||||
fsAPI := federationsender.NewInternalAPI(
|
||||
base, federation, rsAPI, keyRing,
|
||||
base, federation, rsAPI, keyRing, false,
|
||||
)
|
||||
federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI)
|
||||
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ func main() {
|
|||
base, userAPI, rsAPI,
|
||||
)
|
||||
rsAPI.SetAppserviceAPI(asQuery)
|
||||
fedSenderAPI := federationsender.NewInternalAPI(base, federation, rsAPI, &keyRing)
|
||||
fedSenderAPI := federationsender.NewInternalAPI(base, federation, rsAPI, &keyRing, true)
|
||||
rsAPI.SetFederationSenderAPI(fedSenderAPI)
|
||||
p2pPublicRoomProvider := NewLibP2PPublicRoomsProvider(node, fedSenderAPI, federation)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
server {
|
||||
listen 443 ssl; # IPv4
|
||||
listen [::]:443; # IPv6
|
||||
listen [::]:443 ssl; # IPv6
|
||||
server_name my.hostname.com;
|
||||
|
||||
ssl_certificate /path/to/fullchain.pem;
|
||||
|
|
@ -16,6 +16,9 @@ server {
|
|||
}
|
||||
|
||||
location /.well-known/matrix/client {
|
||||
# If your sever_name here doesn't match your matrix homeserver URL
|
||||
# (e.g. hostname.com as server_name and matrix.hostname.com as homeserver URL)
|
||||
# add_header Access-Control-Allow-Origin '*';
|
||||
return 200 '{ "m.homeserver": { "base_url": "https://my.hostname.com" } }';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
server {
|
||||
listen 443 ssl; # IPv4
|
||||
listen [::]:443; # IPv6
|
||||
listen [::]:443 ssl; # IPv6
|
||||
server_name my.hostname.com;
|
||||
|
||||
ssl_certificate /path/to/fullchain.pem;
|
||||
|
|
@ -16,6 +16,9 @@ server {
|
|||
}
|
||||
|
||||
location /.well-known/matrix/client {
|
||||
# If your sever_name here doesn't match your matrix homeserver URL
|
||||
# (e.g. hostname.com as server_name and matrix.hostname.com as homeserver URL)
|
||||
# add_header Access-Control-Allow-Origin '*';
|
||||
return 200 '{ "m.homeserver": { "base_url": "https://my.hostname.com" } }';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ func NewInternalAPI(
|
|||
federation *gomatrixserverlib.FederationClient,
|
||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||
keyRing *gomatrixserverlib.KeyRing,
|
||||
resetBlacklist bool,
|
||||
) api.FederationSenderInternalAPI {
|
||||
cfg := &base.Cfg.FederationSender
|
||||
|
||||
|
|
@ -51,6 +52,10 @@ func NewInternalAPI(
|
|||
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
||||
}
|
||||
|
||||
if resetBlacklist {
|
||||
_ = federationSenderDB.RemoveAllServersFromBlacklist()
|
||||
}
|
||||
|
||||
stats := &statistics.Statistics{
|
||||
DB: federationSenderDB,
|
||||
FailuresUntilBlacklist: cfg.FederationMaxRetries,
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ func (r *FederationSenderInternalAPI) PerformServersAlive(
|
|||
response *api.PerformServersAliveResponse,
|
||||
) (err error) {
|
||||
for _, srv := range request.Servers {
|
||||
_ = r.db.RemoveServerFromBlacklist(srv)
|
||||
r.queues.RetryServer(srv)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ type Database interface {
|
|||
// these don't have contexts passed in as we want things to happen regardless of the request context
|
||||
AddServerToBlacklist(serverName gomatrixserverlib.ServerName) error
|
||||
RemoveServerFromBlacklist(serverName gomatrixserverlib.ServerName) error
|
||||
RemoveAllServersFromBlacklist() error
|
||||
IsServerBlacklisted(serverName gomatrixserverlib.ServerName) (bool, error)
|
||||
|
||||
AddOutboundPeek(ctx context.Context, serverName gomatrixserverlib.ServerName, roomID, peekID string, renewalInterval int64) error
|
||||
|
|
|
|||
|
|
@ -40,11 +40,15 @@ const selectBlacklistSQL = "" +
|
|||
const deleteBlacklistSQL = "" +
|
||||
"DELETE FROM federationsender_blacklist WHERE server_name = $1"
|
||||
|
||||
const deleteAllBlacklistSQL = "" +
|
||||
"TRUNCATE federationsender_blacklist"
|
||||
|
||||
type blacklistStatements struct {
|
||||
db *sql.DB
|
||||
insertBlacklistStmt *sql.Stmt
|
||||
selectBlacklistStmt *sql.Stmt
|
||||
deleteBlacklistStmt *sql.Stmt
|
||||
db *sql.DB
|
||||
insertBlacklistStmt *sql.Stmt
|
||||
selectBlacklistStmt *sql.Stmt
|
||||
deleteBlacklistStmt *sql.Stmt
|
||||
deleteAllBlacklistStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func NewPostgresBlacklistTable(db *sql.DB) (s *blacklistStatements, err error) {
|
||||
|
|
@ -65,11 +69,12 @@ func NewPostgresBlacklistTable(db *sql.DB) (s *blacklistStatements, err error) {
|
|||
if s.deleteBlacklistStmt, err = db.Prepare(deleteBlacklistSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.deleteAllBlacklistStmt, err = db.Prepare(deleteAllBlacklistSQL); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// insertRoom inserts the room if it didn't already exist.
|
||||
// If the room didn't exist then last_event_id is set to the empty string.
|
||||
func (s *blacklistStatements) InsertBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) error {
|
||||
|
|
@ -78,9 +83,6 @@ func (s *blacklistStatements) InsertBlacklist(
|
|||
return err
|
||||
}
|
||||
|
||||
// selectRoomForUpdate locks the row for the room and returns the last_event_id.
|
||||
// The row must already exist in the table. Callers can ensure that the row
|
||||
// exists by calling insertRoom first.
|
||||
func (s *blacklistStatements) SelectBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) (bool, error) {
|
||||
|
|
@ -96,8 +98,6 @@ func (s *blacklistStatements) SelectBlacklist(
|
|||
return res.Next(), nil
|
||||
}
|
||||
|
||||
// updateRoom updates the last_event_id for the room. selectRoomForUpdate should
|
||||
// have already been called earlier within the transaction.
|
||||
func (s *blacklistStatements) DeleteBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) error {
|
||||
|
|
@ -105,3 +105,11 @@ func (s *blacklistStatements) DeleteBlacklist(
|
|||
_, err := stmt.ExecContext(ctx, serverName)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *blacklistStatements) DeleteAllBlacklist(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.deleteAllBlacklistStmt)
|
||||
_, err := stmt.ExecContext(ctx)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,12 @@ func (d *Database) RemoveServerFromBlacklist(serverName gomatrixserverlib.Server
|
|||
})
|
||||
}
|
||||
|
||||
func (d *Database) RemoveAllServersFromBlacklist() error {
|
||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
return d.FederationSenderBlacklist.DeleteAllBlacklist(context.TODO(), txn)
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Database) IsServerBlacklisted(serverName gomatrixserverlib.ServerName) (bool, error) {
|
||||
return d.FederationSenderBlacklist.SelectBlacklist(context.TODO(), nil, serverName)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,11 +40,15 @@ const selectBlacklistSQL = "" +
|
|||
const deleteBlacklistSQL = "" +
|
||||
"DELETE FROM federationsender_blacklist WHERE server_name = $1"
|
||||
|
||||
const deleteAllBlacklistSQL = "" +
|
||||
"DELETE FROM federationsender_blacklist"
|
||||
|
||||
type blacklistStatements struct {
|
||||
db *sql.DB
|
||||
insertBlacklistStmt *sql.Stmt
|
||||
selectBlacklistStmt *sql.Stmt
|
||||
deleteBlacklistStmt *sql.Stmt
|
||||
db *sql.DB
|
||||
insertBlacklistStmt *sql.Stmt
|
||||
selectBlacklistStmt *sql.Stmt
|
||||
deleteBlacklistStmt *sql.Stmt
|
||||
deleteAllBlacklistStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func NewSQLiteBlacklistTable(db *sql.DB) (s *blacklistStatements, err error) {
|
||||
|
|
@ -65,11 +69,12 @@ func NewSQLiteBlacklistTable(db *sql.DB) (s *blacklistStatements, err error) {
|
|||
if s.deleteBlacklistStmt, err = db.Prepare(deleteBlacklistSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.deleteAllBlacklistStmt, err = db.Prepare(deleteAllBlacklistSQL); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// insertRoom inserts the room if it didn't already exist.
|
||||
// If the room didn't exist then last_event_id is set to the empty string.
|
||||
func (s *blacklistStatements) InsertBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) error {
|
||||
|
|
@ -78,9 +83,6 @@ func (s *blacklistStatements) InsertBlacklist(
|
|||
return err
|
||||
}
|
||||
|
||||
// selectRoomForUpdate locks the row for the room and returns the last_event_id.
|
||||
// The row must already exist in the table. Callers can ensure that the row
|
||||
// exists by calling insertRoom first.
|
||||
func (s *blacklistStatements) SelectBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) (bool, error) {
|
||||
|
|
@ -96,8 +98,6 @@ func (s *blacklistStatements) SelectBlacklist(
|
|||
return res.Next(), nil
|
||||
}
|
||||
|
||||
// updateRoom updates the last_event_id for the room. selectRoomForUpdate should
|
||||
// have already been called earlier within the transaction.
|
||||
func (s *blacklistStatements) DeleteBlacklist(
|
||||
ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName,
|
||||
) error {
|
||||
|
|
@ -105,3 +105,11 @@ func (s *blacklistStatements) DeleteBlacklist(
|
|||
_, err := stmt.ExecContext(ctx, serverName)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *blacklistStatements) DeleteAllBlacklist(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.deleteAllBlacklistStmt)
|
||||
_, err := stmt.ExecContext(ctx)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ type FederationSenderBlacklist interface {
|
|||
InsertBlacklist(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName) error
|
||||
SelectBlacklist(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName) (bool, error)
|
||||
DeleteBlacklist(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName) error
|
||||
DeleteAllBlacklist(ctx context.Context, txn *sql.Tx) error
|
||||
}
|
||||
|
||||
type FederationSenderOutboundPeeks interface {
|
||||
|
|
|
|||
7
go.mod
7
go.mod
|
|
@ -23,9 +23,9 @@ require (
|
|||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
|
||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210302161955-6142fe3f8c2c
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210525110027-8cb7699aa64a
|
||||
github.com/matrix-org/naffka v0.0.0-20201009174903-d26a3b9cb161
|
||||
github.com/matrix-org/pinecone v0.0.0-20210510160342-a1dfbcf4bd47
|
||||
github.com/matrix-org/pinecone v0.0.0-20210614122540-33ce3bd0f3ac
|
||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
||||
github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
|
|
@ -42,8 +42,9 @@ require (
|
|||
github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20210218094457-e77ca8019daa
|
||||
go.uber.org/atomic v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
gopkg.in/h2non/bimg.v1 v1.1.5
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
|
|
|||
28
go.sum
28
go.sum
|
|
@ -13,6 +13,7 @@ github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0 h1:p3puK8Sl2xK+2Fnn
|
|||
github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
|
|
@ -701,12 +702,12 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1
|
|||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210302161955-6142fe3f8c2c h1:vW3jBp1PnZ4uUqyS+JatJRYIl73ZLHkUkRzf1JdGxOI=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210302161955-6142fe3f8c2c/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210525110027-8cb7699aa64a h1:pVhOeJpD0gv5boUnihefPDuYkQ6xSdEVbH5ld5Vvve0=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20210525110027-8cb7699aa64a/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||
github.com/matrix-org/naffka v0.0.0-20201009174903-d26a3b9cb161 h1:h1XVh05pLoC+nJjP3GIpj5wUsuC8WdHP3He0RTkRJTs=
|
||||
github.com/matrix-org/naffka v0.0.0-20201009174903-d26a3b9cb161/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
|
||||
github.com/matrix-org/pinecone v0.0.0-20210510160342-a1dfbcf4bd47 h1:kWLnEcQoqJWlBtgtooa7ixyGNL3fy4CsyfR8M6b8vdI=
|
||||
github.com/matrix-org/pinecone v0.0.0-20210510160342-a1dfbcf4bd47/go.mod h1:/75aR0l7umUnMBk02Q5+QC2IPY58S21BLpoPR9BUr0k=
|
||||
github.com/matrix-org/pinecone v0.0.0-20210614122540-33ce3bd0f3ac h1:qgEfJzulYUVDGh1PGzeGxYMGDtKSxMS+6eQG6E37pgM=
|
||||
github.com/matrix-org/pinecone v0.0.0-20210614122540-33ce3bd0f3ac/go.mod h1:UQzJS6UVyVwfkr+RLrdvBB1vLyECqe3fLYNcbRxv8SA=
|
||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
|
||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||
|
|
@ -1036,7 +1037,9 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV
|
|||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
|
||||
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
|
||||
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
|
||||
|
|
@ -1123,6 +1126,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
|
|||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
|
|
@ -1130,8 +1136,13 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 h1:h+GZ3ubjuWaQjGe8owMGcmMVCqs0xYJtRG5y2bpHaqU=
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
@ -1203,6 +1214,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -1225,11 +1237,12 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169 h1:fpeMGRM6A+XFcw4RPCO8s8hH7ppgrGR22pSIjwM7YUI=
|
||||
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -1251,6 +1264,7 @@ golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
|
|
@ -1260,6 +1274,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69 h1:yBHHx+XZqXJBm6Exke3N7V9gnlsyXxoCPEb1yVenjfk=
|
||||
|
|
@ -1271,6 +1286,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
|
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210203165646-9c7bd73be2cc/go.mod h1:r0ExowOoGFfDoLDxx+M9SYbNVsoZ0xviLL+K4f2mt+A=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210212170059-7a0fb5bbb172/go.mod h1:r0ExowOoGFfDoLDxx+M9SYbNVsoZ0xviLL+K4f2mt+A=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
||||
golang.zx2c4.com/wireguard/windows v0.3.5/go.mod h1:ATrIFNoq3rsK735WJiQzfWYyNFc9xLBhMMjW9DWIvnU=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
|
|
@ -47,7 +48,7 @@ const upsertKeysSQL = "" +
|
|||
" DO UPDATE SET key_json = $6"
|
||||
|
||||
const selectKeysSQL = "" +
|
||||
"SELECT key_id, algorithm, key_json FROM keyserver_one_time_keys WHERE user_id=$1 AND device_id=$2"
|
||||
"SELECT concat(algorithm, ':', key_id) as algorithmwithid, key_json FROM keyserver_one_time_keys WHERE user_id=$1 AND device_id=$2 AND concat(algorithm, ':', key_id) = ANY($3);"
|
||||
|
||||
const selectKeysCountSQL = "" +
|
||||
"SELECT algorithm, COUNT(key_id) FROM keyserver_one_time_keys WHERE user_id=$1 AND device_id=$2 GROUP BY algorithm"
|
||||
|
|
@ -94,29 +95,22 @@ func NewPostgresOneTimeKeysTable(db *sql.DB) (tables.OneTimeKeys, error) {
|
|||
}
|
||||
|
||||
func (s *oneTimeKeysStatements) SelectOneTimeKeys(ctx context.Context, userID, deviceID string, keyIDsWithAlgorithms []string) (map[string]json.RawMessage, error) {
|
||||
rows, err := s.selectKeysStmt.QueryContext(ctx, userID, deviceID)
|
||||
rows, err := s.selectKeysStmt.QueryContext(ctx, userID, deviceID, pq.Array(keyIDsWithAlgorithms))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer internal.CloseAndLogIfError(ctx, rows, "selectKeysStmt: rows.close() failed")
|
||||
|
||||
wantSet := make(map[string]bool, len(keyIDsWithAlgorithms))
|
||||
for _, ka := range keyIDsWithAlgorithms {
|
||||
wantSet[ka] = true
|
||||
}
|
||||
|
||||
result := make(map[string]json.RawMessage)
|
||||
var (
|
||||
algorithmWithID string
|
||||
keyJSONStr string
|
||||
)
|
||||
for rows.Next() {
|
||||
var keyID string
|
||||
var algorithm string
|
||||
var keyJSONStr string
|
||||
if err := rows.Scan(&keyID, &algorithm, &keyJSONStr); err != nil {
|
||||
if err := rows.Scan(&algorithmWithID, &keyJSONStr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyIDWithAlgo := algorithm + ":" + keyID
|
||||
if wantSet[keyIDWithAlgo] {
|
||||
result[keyIDWithAlgo] = json.RawMessage(keyJSONStr)
|
||||
}
|
||||
result[algorithmWithID] = json.RawMessage(keyJSONStr)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,20 @@ func (r *uploadRequest) doUpload(
|
|||
// r.storeFileAndMetadata(ctx, tmpDir, ...)
|
||||
// before you return from doUpload else we will leak a temp file. We could make this nicer with a `WithTransaction` style of
|
||||
// nested function to guarantee either storage or cleanup.
|
||||
hash, bytesWritten, tmpDir, err := fileutils.WriteTempFile(ctx, reqReader, cfg.AbsBasePath)
|
||||
|
||||
// should not happen, but prevents any int overflows
|
||||
if cfg.MaxFileSizeBytes != nil && *cfg.MaxFileSizeBytes+1 <= 0 {
|
||||
r.Logger.WithFields(log.Fields{
|
||||
"MaxFileSizeBytes": *cfg.MaxFileSizeBytes + 1,
|
||||
}).Error("Error while transferring file, configured max_file_size_bytes overflows int64")
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown("Failed to upload"),
|
||||
}
|
||||
}
|
||||
|
||||
lr := io.LimitReader(reqReader, int64(*cfg.MaxFileSizeBytes)+1)
|
||||
hash, bytesWritten, tmpDir, err := fileutils.WriteTempFile(ctx, lr, cfg.AbsBasePath)
|
||||
if err != nil {
|
||||
r.Logger.WithError(err).WithFields(log.Fields{
|
||||
"MaxFileSizeBytes": *cfg.MaxFileSizeBytes,
|
||||
|
|
|
|||
132
mediaapi/routing/upload_test.go
Normal file
132
mediaapi/routing/upload_test.go
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/mediaapi/fileutils"
|
||||
"github.com/matrix-org/dendrite/mediaapi/storage"
|
||||
"github.com/matrix-org/dendrite/mediaapi/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func Test_uploadRequest_doUpload(t *testing.T) {
|
||||
type fields struct {
|
||||
MediaMetadata *types.MediaMetadata
|
||||
Logger *log.Entry
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
reqReader io.Reader
|
||||
cfg *config.MediaAPI
|
||||
db storage.Database
|
||||
activeThumbnailGeneration *types.ActiveThumbnailGeneration
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Errorf("failed to get current working directory: %v", err)
|
||||
}
|
||||
|
||||
maxSize := config.FileSizeBytes(8)
|
||||
logger := log.New().WithField("mediaapi", "test")
|
||||
testdataPath := filepath.Join(wd, "./testdata")
|
||||
|
||||
cfg := &config.MediaAPI{
|
||||
MaxFileSizeBytes: &maxSize,
|
||||
BasePath: config.Path(testdataPath),
|
||||
AbsBasePath: config.Path(testdataPath),
|
||||
DynamicThumbnails: false,
|
||||
}
|
||||
|
||||
// create testdata folder and remove when done
|
||||
_ = os.Mkdir(testdataPath, os.ModePerm)
|
||||
defer fileutils.RemoveDir(types.Path(testdataPath), nil)
|
||||
|
||||
db, err := storage.Open(&config.DatabaseOptions{
|
||||
ConnectionString: "file::memory:?cache=shared",
|
||||
MaxOpenConnections: 100,
|
||||
MaxIdleConnections: 2,
|
||||
ConnMaxLifetimeSeconds: -1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("error opening mediaapi database: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want *util.JSONResponse
|
||||
}{
|
||||
{
|
||||
name: "upload ok",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
reqReader: strings.NewReader("test"),
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
},
|
||||
fields: fields{
|
||||
Logger: logger,
|
||||
MediaMetadata: &types.MediaMetadata{
|
||||
MediaID: "1337",
|
||||
UploadName: "test ok",
|
||||
},
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "upload ok (exact size)",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
reqReader: strings.NewReader("testtest"),
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
},
|
||||
fields: fields{
|
||||
Logger: logger,
|
||||
MediaMetadata: &types.MediaMetadata{
|
||||
MediaID: "1338",
|
||||
UploadName: "test ok (exact size)",
|
||||
},
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "upload not ok",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
reqReader: strings.NewReader("test test test"),
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
},
|
||||
fields: fields{
|
||||
Logger: logger,
|
||||
MediaMetadata: &types.MediaMetadata{
|
||||
MediaID: "1339",
|
||||
UploadName: "test fail",
|
||||
},
|
||||
},
|
||||
want: requestEntityTooLargeJSONResponse(maxSize),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &uploadRequest{
|
||||
MediaMetadata: tt.fields.MediaMetadata,
|
||||
Logger: tt.fields.Logger,
|
||||
}
|
||||
if got := r.doUpload(tt.args.ctx, tt.args.reqReader, tt.args.cfg, tt.args.db, tt.args.activeThumbnailGeneration); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("doUpload() = %+v, want %+v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ func (a *ApplicationService) IsInterestedInRoomID(
|
|||
) bool {
|
||||
if namespaceSlice, ok := a.NamespaceMap["rooms"]; ok {
|
||||
for _, namespace := range namespaceSlice {
|
||||
if namespace.RegexpObject.MatchString(roomID) {
|
||||
if namespace.RegexpObject != nil && namespace.RegexpObject.MatchString(roomID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -222,6 +222,10 @@ func setupRegexps(asAPI *AppServiceAPI, derived *Derived) (err error) {
|
|||
case "aliases":
|
||||
appendExclusiveNamespaceRegexs(&exclusiveAliasStrings, namespaceSlice)
|
||||
}
|
||||
|
||||
if err = compileNamespaceRegexes(namespaceSlice); err != nil {
|
||||
return fmt.Errorf("invalid regex in appservice %q, namespace %q: %w", appservice.ID, key, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,18 +262,31 @@ func setupRegexps(asAPI *AppServiceAPI, derived *Derived) (err error) {
|
|||
func appendExclusiveNamespaceRegexs(
|
||||
exclusiveStrings *[]string, namespaces []ApplicationServiceNamespace,
|
||||
) {
|
||||
for index, namespace := range namespaces {
|
||||
for _, namespace := range namespaces {
|
||||
if namespace.Exclusive {
|
||||
// We append parenthesis to later separate each regex when we compile
|
||||
// i.e. "app1.*", "app2.*" -> "(app1.*)|(app2.*)"
|
||||
*exclusiveStrings = append(*exclusiveStrings, "("+namespace.Regex+")")
|
||||
}
|
||||
|
||||
// Compile this regex into a Regexp object for later use
|
||||
namespaces[index].RegexpObject, _ = regexp.Compile(namespace.Regex)
|
||||
}
|
||||
}
|
||||
|
||||
// compileNamespaceRegexes turns strings into regex objects and complains
|
||||
// if some of there are bad
|
||||
func compileNamespaceRegexes(namespaces []ApplicationServiceNamespace) (err error) {
|
||||
for index, namespace := range namespaces {
|
||||
// Compile this regex into a Regexp object for later use
|
||||
r, err := regexp.Compile(namespace.Regex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("regex at namespace %d: %w", index, err)
|
||||
}
|
||||
|
||||
namespaces[index].RegexpObject = r
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkErrors checks for any configuration errors amongst the loaded
|
||||
// application services according to the application service spec.
|
||||
func checkErrors(config *AppServiceAPI, derived *Derived) (err error) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package config
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type MediaAPI struct {
|
||||
|
|
@ -57,6 +58,11 @@ func (c *MediaAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
|||
checkNotEmpty(configErrs, "media_api.database.connection_string", string(c.Database.ConnectionString))
|
||||
|
||||
checkNotEmpty(configErrs, "media_api.base_path", string(c.BasePath))
|
||||
// allow "unlimited" file size
|
||||
if c.MaxFileSizeBytes != nil && *c.MaxFileSizeBytes <= 0 {
|
||||
unlimitedSize := FileSizeBytes(math.MaxInt64 - 1)
|
||||
c.MaxFileSizeBytes = &unlimitedSize
|
||||
}
|
||||
checkPositive(configErrs, "media_api.max_file_size_bytes", int64(*c.MaxFileSizeBytes))
|
||||
checkPositive(configErrs, "media_api.max_thumbnail_generators", int64(c.MaxThumbnailGenerators))
|
||||
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ConstCreateEventContentKey = "org.matrix.msc1772.type"
|
||||
ConstSpaceChildEventType = "org.matrix.msc1772.space.child"
|
||||
ConstSpaceParentEventType = "org.matrix.msc1772.space.parent"
|
||||
ConstCreateEventContentKey = "type"
|
||||
ConstSpaceChildEventType = "m.space.child"
|
||||
ConstSpaceParentEventType = "m.space.parent"
|
||||
)
|
||||
|
||||
// Defaults sets the request defaults
|
||||
|
|
|
|||
Loading…
Reference in a new issue