mirror of
https://activitypub.software/TransFem-org/Sharkey.git
synced 2025-04-13 09:44:40 +00:00
convert streaming rate limit to bucket
This commit is contained in:
parent
920bf71eb5
commit
18655386f3
1 changed files with 14 additions and 21 deletions
|
@ -10,7 +10,9 @@ import * as WebSocket from 'ws';
|
||||||
import proxyAddr from 'proxy-addr';
|
import proxyAddr from 'proxy-addr';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { UsersRepository, MiAccessToken } from '@/models/_.js';
|
import type { UsersRepository, MiAccessToken, MiUser } from '@/models/_.js';
|
||||||
|
import type { Config } from '@/config.js';
|
||||||
|
import type { Keyed, RateLimit } from '@/misc/rate-limit-utils.js';
|
||||||
import { NoteReadService } from '@/core/NoteReadService.js';
|
import { NoteReadService } from '@/core/NoteReadService.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -25,8 +27,6 @@ import { AuthenticateService, AuthenticationError } from './AuthenticateService.
|
||||||
import MainStreamConnection from './stream/Connection.js';
|
import MainStreamConnection from './stream/Connection.js';
|
||||||
import { ChannelsService } from './stream/ChannelsService.js';
|
import { ChannelsService } from './stream/ChannelsService.js';
|
||||||
import type * as http from 'node:http';
|
import type * as http from 'node:http';
|
||||||
import type { IEndpointMeta } from './endpoints.js';
|
|
||||||
import type { Config } from "@/config.js";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StreamingApiServerService {
|
export class StreamingApiServerService {
|
||||||
|
@ -58,17 +58,9 @@ export class StreamingApiServerService {
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async rateLimitThis(
|
private async rateLimitThis(
|
||||||
user: MiLocalUser | null | undefined,
|
limitActor: MiUser | string,
|
||||||
requestIp: string,
|
limit: Keyed<RateLimit>,
|
||||||
limit: IEndpointMeta['limit'] & { key: NonNullable<string> },
|
|
||||||
) : Promise<boolean> {
|
) : Promise<boolean> {
|
||||||
let limitActor: string | MiLocalUser;
|
|
||||||
if (user) {
|
|
||||||
limitActor = user;
|
|
||||||
} else {
|
|
||||||
limitActor = getIpHash(requestIp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rate limit
|
// Rate limit
|
||||||
const rateLimit = await this.rateLimiterService.limit(limit, limitActor);
|
const rateLimit = await this.rateLimiterService.limit(limit, limitActor);
|
||||||
return rateLimit.blocked;
|
return rateLimit.blocked;
|
||||||
|
@ -93,7 +85,8 @@ export class StreamingApiServerService {
|
||||||
// so we do the same
|
// so we do the same
|
||||||
const requestIp = proxyAddr(request, () => { return true; } );
|
const requestIp = proxyAddr(request, () => { return true; } );
|
||||||
|
|
||||||
if (await this.rateLimitThis(null, requestIp, {
|
const limitActor = getIpHash(requestIp);
|
||||||
|
if (await this.rateLimitThis(limitActor, {
|
||||||
key: 'wsconnect',
|
key: 'wsconnect',
|
||||||
duration: ms('5min'),
|
duration: ms('5min'),
|
||||||
max: 32,
|
max: 32,
|
||||||
|
@ -141,14 +134,14 @@ export class StreamingApiServerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const rateLimiter = () => {
|
const rateLimiter = () => {
|
||||||
// rather high limit, because when catching up at the top of a
|
const limitActor = user ?? getIpHash(requestIp);
|
||||||
// timeline, the frontend may render many many notes, each of
|
|
||||||
// which causes a message via `useNoteCapture` to ask for
|
// Rather high limit because when catching up at the top of a timeline, the frontend may render many many notes.
|
||||||
// realtime updates of that note
|
// Each of which causes a message via `useNoteCapture` to ask for realtime updates of that note.
|
||||||
return this.rateLimitThis(user, requestIp, {
|
return this.rateLimitThis(limitActor, {
|
||||||
key: 'wsmessage',
|
key: 'wsmessage',
|
||||||
duration: ms('2sec'),
|
max: 4096, // Allow spikes of up to 4096
|
||||||
max: 4096,
|
dripRate: 50, // Then once every 50ms (20/second rate)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue