EnableRateVisitor flag
This commit is contained in:
parent
ecff7258ba
commit
1c4420bca8
5 changed files with 38 additions and 6 deletions
|
@ -133,6 +133,7 @@ type Config struct {
|
|||
EnableSignup bool // Enable creation of accounts via API and UI
|
||||
EnableLogin bool
|
||||
EnableReservations bool // Allow users with role "user" to own/reserve topics
|
||||
EnableRateVisitor bool // Enable subscriber-based rate limiting for UnifiedPush topics
|
||||
AccessControlAllowOrigin string // CORS header field to restrict access from web clients
|
||||
Version string // injected by App
|
||||
}
|
||||
|
|
|
@ -597,7 +597,7 @@ func (s *Server) handlePublishWithoutResponse(r *http.Request, v *visitor) (*mes
|
|||
if e != nil {
|
||||
return nil, e.With(t)
|
||||
}
|
||||
if unifiedpush && t.RateVisitor() == nil {
|
||||
if unifiedpush && s.config.EnableRateVisitor && t.RateVisitor() == nil {
|
||||
// UnifiedPush clients must subscribe before publishing to allow proper subscriber-based rate limiting (see
|
||||
// Rate-Topics header). The 5xx response is because some app servers (in particular Mastodon) will remove
|
||||
// the subscription as invalid if any 400-499 code (except 429/408) is returned.
|
||||
|
@ -1188,14 +1188,19 @@ func parseSubscribeParams(r *http.Request) (poll bool, since sinceMarker, schedu
|
|||
// maybeSetRateVisitors sets the rate visitor on a topic (v.SetRateVisitor), indicating that all messages published
|
||||
// to that topic will be rate limited against the rate visitor instead of the publishing visitor.
|
||||
//
|
||||
// Setting the rate visitor is ony allowed if
|
||||
// Setting the rate visitor is ony allowed if the `enable-rate-visitor` setting is enabled, AND
|
||||
// - auth-file is not set (everything is open by default)
|
||||
// - the topic is reserved, and v.user is the owner
|
||||
// - the topic is not reserved, and v.user has write access
|
||||
// - or the topic is reserved, and v.user is the owner
|
||||
// - or the topic is not reserved, and v.user has write access
|
||||
//
|
||||
// Note: This TEMPORARILY also registers all topics starting with "up" (= UnifiedPush). This is to ease the transition
|
||||
// until the Android app will send the "Rate-Topics" header.
|
||||
func (s *Server) maybeSetRateVisitors(r *http.Request, v *visitor, topics []*topic, rateTopics []string) error {
|
||||
// Bail out if not enabled
|
||||
if !s.config.EnableRateVisitor {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Make a list of topics that we'll actually set the RateVisitor on
|
||||
eligibleRateTopics := make([]*topic, 0)
|
||||
for _, t := range topics {
|
||||
|
|
|
@ -235,6 +235,20 @@
|
|||
# visitor-attachment-total-size-limit: "100M"
|
||||
# visitor-attachment-daily-bandwidth-limit: "500M"
|
||||
|
||||
# Rate limiting: Enable subscriber-based rate limiting (mostly used for UnifiedPush)
|
||||
#
|
||||
# If enabled, subscribers may opt to have published messages counted against their own rate limits, as opposed
|
||||
# to the publisher's rate limits. This is especially useful to increase the amount of messages that UnifiedPush
|
||||
# publishers (e.g. Matrix/Mastodon servers) are allowed to send.
|
||||
#
|
||||
# Once enabled, a client may send a "Rate-Topics: <topic1>,<topic2>,..." header when subscribing to topics via
|
||||
# HTTP stream, or websockets, thereby registering itself as the "rate visitor", i.e. the visitor whose rate limits
|
||||
# to use when publishing on this topic.
|
||||
#
|
||||
# For your home server, you likely DO NOT NEED THIS setting.
|
||||
#
|
||||
# enable-rate-visitors: false
|
||||
|
||||
# Payments integration via Stripe
|
||||
#
|
||||
# - stripe-secret-key is the key used for the Stripe API communication. Setting this values
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
@ -1291,7 +1292,9 @@ func TestServer_MatrixGateway_Push_Success(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServer_MatrixGateway_Push_Failure_NoSubscriber(t *testing.T) {
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
c := newTestConfig(t)
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
notification := `{"notification":{"devices":[{"pushkey":"http://127.0.0.1:12345/mytopic?up=1"}]}}`
|
||||
response := request(t, s, "POST", "/_matrix/push/v1/notify", notification, nil)
|
||||
require.Equal(t, 507, response.Code)
|
||||
|
@ -2029,6 +2032,7 @@ func TestServer_AnonymousUser_And_NonTierUser_Are_Same_Visitor(t *testing.T) {
|
|||
func TestServer_SubscriberRateLimiting_Success(t *testing.T) {
|
||||
c := newTestConfigWithAuthFile(t)
|
||||
c.VisitorRequestLimitBurst = 3
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// "Register" visitor 1.2.3.4 to topic "subscriber1topic" as a rate limit visitor
|
||||
|
@ -2082,6 +2086,7 @@ func TestServer_SubscriberRateLimiting_Success(t *testing.T) {
|
|||
func TestServer_SubscriberRateLimiting_UP_Only(t *testing.T) {
|
||||
c := newTestConfigWithAuthFile(t)
|
||||
c.VisitorRequestLimitBurst = 3
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// "Register" 5 different UnifiedPush visitors
|
||||
|
@ -2105,6 +2110,7 @@ func TestServer_SubscriberRateLimiting_UP_Only(t *testing.T) {
|
|||
func TestServer_Matrix_SubscriberRateLimiting_UP_Only(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.VisitorRequestLimitBurst = 3
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// "Register" 5 different UnifiedPush visitors
|
||||
|
@ -2132,6 +2138,7 @@ func TestServer_Matrix_SubscriberRateLimiting_UP_Only(t *testing.T) {
|
|||
func TestServer_SubscriberRateLimiting_VisitorExpiration(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.VisitorRequestLimitBurst = 3
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// "Register" rate visitor
|
||||
|
@ -2167,6 +2174,7 @@ func TestServer_SubscriberRateLimiting_VisitorExpiration(t *testing.T) {
|
|||
func TestServer_SubscriberRateLimiting_ProtectedTopics(t *testing.T) {
|
||||
c := newTestConfigWithAuthFile(t)
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// Create some ACLs
|
||||
|
@ -2214,6 +2222,7 @@ func TestServer_SubscriberRateLimiting_ProtectedTopics(t *testing.T) {
|
|||
func TestServer_SubscriberRateLimiting_ProtectedTopics_WithDefaultReadWrite(t *testing.T) {
|
||||
c := newTestConfigWithAuthFile(t)
|
||||
c.AuthDefault = user.PermissionReadWrite
|
||||
c.EnableRateVisitor = true
|
||||
s := newTestServer(t, c)
|
||||
|
||||
// Create some ACLs
|
||||
|
@ -2333,5 +2342,5 @@ func waitForWithMaxWait(t *testing.T, maxWait time.Duration, f func() bool) {
|
|||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
t.Fatalf("Function f did not succeed after %v", maxWait)
|
||||
t.Fatalf("Function f did not succeed after %v: %s", maxWait, debug.Stack())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue