Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
- `app/controllers/api/v1/statuses_controller.rb`:
  Conflict due to upstream adding a new parameter (with_rate_limit),
  too close to glitch-soc's own additional parameter (content_type).
  Added upstream's parameter.
- `app/services/post_status_service.rb`:
  Conflict due to upstream adding a new parameter (rate_limit),
  too close to glitch-soc's own additional parameter (content_type).
  Added upstream's parameter.
- `app/views/settings/preferences/appearance/show.html.haml`:
  Conflict due to us not exposing theme settings here (as we have
  a different flavour/skin menu).
  Took upstream change, while still not exposing theme settings.
- `config/webpack/shared.js`:
  Coding style fixes for a part we have rewritten.
  Discarded upstream changes.
This commit is contained in:
Thibaut Girka
2020-03-08 19:38:53 +01:00
138 changed files with 573 additions and 317 deletions

View File

@@ -8,6 +8,7 @@ module Mastodon
class LengthValidationError < ValidationError; end
class DimensionsValidationError < ValidationError; end
class RaceConditionError < Error; end
class RateLimitExceededError < Error; end
class UnexpectedResponseError < Error
def initialize(response = nil)

64
app/lib/rate_limiter.rb Normal file
View File

@@ -0,0 +1,64 @@
# frozen_string_literal: true
class RateLimiter
include Redisable
FAMILIES = {
follows: {
limit: 400,
period: 24.hours.freeze,
}.freeze,
statuses: {
limit: 300,
period: 3.hours.freeze,
}.freeze,
media: {
limit: 30,
period: 30.minutes.freeze,
}.freeze,
}.freeze
def initialize(by, options = {})
@by = by
@family = options[:family]
@limit = FAMILIES[@family][:limit]
@period = FAMILIES[@family][:period].to_i
end
def record!
count = redis.get(key)
if count.nil?
redis.set(key, 0)
redis.expire(key, (@period - (last_epoch_time % @period) + 1).to_i)
end
raise Mastodon::RateLimitExceededError if count.present? && count.to_i >= @limit
redis.incr(key)
end
def rollback!
redis.decr(key)
end
def to_headers(now = Time.now.utc)
{
'X-RateLimit-Limit' => @limit.to_s,
'X-RateLimit-Remaining' => (@limit - (redis.get(key) || 0).to_i).to_s,
'X-RateLimit-Reset' => (now + (@period - now.to_i % @period)).iso8601(6),
}
end
private
def key
@key ||= "rate_limit:#{@by.id}:#{@family}:#{(last_epoch_time / @period).to_i}"
end
def last_epoch_time
@last_epoch_time ||= Time.now.to_i
end
end