Skip to content

Commit 685d58b

Browse files
authored
Remove code-based rate limit from search and report API. (#9010)
1 parent 155c09a commit 685d58b

File tree

10 files changed

+2
-216
lines changed

10 files changed

+2
-216
lines changed

app/lib/frontend/handlers/custom_api.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,7 @@ const _commonLicenses = [
452452
/// Handles requests for /api/search
453453
Future<shelf.Response> apiSearchHandler(shelf.Request request) async {
454454
final searchForm = SearchForm.parse(request.requestedUri.queryParameters);
455-
final sr = await searchClient.search(
456-
searchForm.toServiceQuery(),
457-
sourceIp: request.sourceIp,
458-
);
455+
final sr = await searchClient.search(searchForm.toServiceQuery());
459456
final packages = sr.packageHits.map((ps) => {'package': ps.package}).toList();
460457
final hasNextPage = sr.totalCount > searchForm.pageSize! + searchForm.offset;
461458
final result = <String, dynamic>{

app/lib/frontend/handlers/report.dart

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:pub_dev/admin/backend.dart';
1111
import 'package:pub_dev/shared/configuration.dart';
1212
import 'package:shelf/shelf.dart' as shelf;
1313

14-
import '../../../service/rate_limit/rate_limit.dart';
1514
import '../../account/backend.dart';
1615
import '../../admin/models.dart';
1716
import '../../frontend/handlers/cache_control.dart';
@@ -25,11 +24,6 @@ import '../../shared/handlers.dart';
2524
import '../request_context.dart';
2625
import '../templates/report.dart';
2726

28-
/// The number of requests allowed over [_reportRateLimitWindow]
29-
const _reportRateLimit = 5;
30-
const _reportRateLimitWindow = Duration(minutes: 10);
31-
const _reportRateLimitWindowAsText = 'last 10 minutes';
32-
3327
/// Handles GET /report
3428
Future<shelf.Response> reportPageHandler(shelf.Request request) async {
3529
final feedback = request.requestedUri.queryParameters['feedback'];
@@ -175,17 +169,6 @@ Future<Message> processReportPageHandler(
175169
shelf.Request request,
176170
ReportForm form,
177171
) async {
178-
final sourceIp = request.sourceIp;
179-
if (sourceIp != null) {
180-
await verifyRequestCounts(
181-
sourceIp: sourceIp,
182-
operation: 'report',
183-
limit: _reportRateLimit,
184-
window: _reportRateLimitWindow,
185-
windowAsText: _reportRateLimitWindowAsText,
186-
);
187-
}
188-
189172
final now = clock.now().toUtc();
190173
final caseId = ModerationCase.generateCaseId(now: now);
191174

app/lib/package/search_adapter.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ class SearchAdapter {
6262
) async {
6363
PackageSearchResult? result;
6464
try {
65-
result = await searchClient.search(
66-
searchForm.toServiceQuery(),
67-
sourceIp: sourceIp,
68-
);
65+
result = await searchClient.search(searchForm.toServiceQuery());
6966
} on RateLimitException {
7067
rethrow;
7168
} catch (e, st) {

app/lib/search/backend.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,6 @@ class SearchBackend {
495495
// Do not cache response at the search client level, as we'll be caching
496496
// it in a processed form much longer.
497497
skipCache: true,
498-
// Do not apply rate limit here.
499-
sourceIp: null,
500498
);
501499
return {'packages': rs.packageHits.map((p) => p.package).toList()};
502500
}

app/lib/search/search_client.dart

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:_pub_shared/utils/http.dart';
1010
import 'package:clock/clock.dart';
1111
import 'package:gcloud/service_scope.dart' as ss;
1212

13-
import '../../../service/rate_limit/rate_limit.dart';
1413
import '../../account/like_backend.dart';
1514
import '../../frontend/request_context.dart';
1615
import '../shared/configuration.dart';
@@ -19,11 +18,6 @@ import '../shared/utils.dart';
1918

2019
import 'search_service.dart';
2120

22-
/// The number of requests allowed over [_searchRateLimitWindow]
23-
const _searchRateLimit = 120;
24-
const _searchRateLimitWindow = Duration(minutes: 2);
25-
const _searchRateLimitWindowAsText = 'last 2 minutes';
26-
2721
/// Sets the search client.
2822
void registerSearchClient(SearchClient client) =>
2923
ss.register(#_searchClient, client);
@@ -45,7 +39,6 @@ class SearchClient {
4539
/// Calls the search service (or uses cache) to serve the [query].
4640
Future<PackageSearchResult> search(
4741
ServiceSearchQuery query, {
48-
required String? sourceIp,
4942
bool skipCache = false,
5043
}) async {
5144
// check validity first
@@ -170,16 +163,6 @@ class SearchClient {
170163
);
171164
}
172165

173-
if (sourceIp != null) {
174-
await verifyRequestCounts(
175-
sourceIp: sourceIp,
176-
operation: 'search',
177-
limit: _searchRateLimit,
178-
window: _searchRateLimitWindow,
179-
windowAsText: _searchRateLimitWindowAsText,
180-
);
181-
}
182-
183166
if (skipCache) {
184167
return await searchFn();
185168
} else {

app/lib/service/rate_limit/models.dart

Lines changed: 0 additions & 51 deletions
This file was deleted.

app/lib/service/rate_limit/models.g.dart

Lines changed: 0 additions & 21 deletions
This file was deleted.

app/lib/service/rate_limit/rate_limit.dart

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import 'package:clock/clock.dart';
66
import 'package:collection/collection.dart';
77
import 'package:logging/logging.dart';
88
import 'package:pub_dev/audit/backend.dart';
9-
import 'package:pub_dev/service/rate_limit/models.dart';
109

1110
import '../../account/agent.dart';
1211
import '../../audit/models.dart';
@@ -184,24 +183,3 @@ bool _containsUserId(List<String>? users, String userId) {
184183
}
185184
return users.contains(userId);
186185
}
187-
188-
Future<void> verifyRequestCounts({
189-
required String sourceIp,
190-
required String operation,
191-
required int limit,
192-
required Duration window,
193-
required String windowAsText,
194-
}) async {
195-
final counterCacheEntry = cache.rateLimitRequestCounter(sourceIp, operation);
196-
final cachedCounter = await counterCacheEntry.get();
197-
if (cachedCounter == null) {
198-
await counterCacheEntry.set(RateLimitRequestCounter.init(1));
199-
} else {
200-
final nextCounter = cachedCounter.incrementOrThrow(
201-
limit: limit,
202-
window: window,
203-
windowAsText: windowAsText,
204-
);
205-
await counterCacheEntry.set(nextCounter);
206-
}
207-
}

app/lib/shared/redis_cache.dart

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import 'package:neat_cache/neat_cache.dart';
1717
import 'package:pub_dev/service/download_counts/download_counts.dart';
1818

1919
import '../../../service/async_queue/async_queue.dart';
20-
import '../../../service/rate_limit/models.dart';
2120
import '../../../service/security_advisories/models.dart';
2221
import '../../dartdoc/models.dart';
2322
import '../../shared/env_config.dart';
@@ -213,24 +212,6 @@ class CachePatterns {
213212
)[url];
214213
}
215214

216-
Entry<RateLimitRequestCounter> rateLimitRequestCounter(
217-
String sourceIp,
218-
String operation,
219-
) {
220-
return _cache
221-
.withPrefix('rate-limit-request-counter/')
222-
.withTTL(const Duration(minutes: 3))
223-
.withCodec(utf8)
224-
.withCodec(json)
225-
.withCodec(
226-
wrapAsCodec(
227-
encode: (RateLimitRequestCounter r) => r.toJson(),
228-
decode: (d) =>
229-
RateLimitRequestCounter.fromJson(d as Map<String, dynamic>),
230-
),
231-
)['$sourceIp/$operation'];
232-
}
233-
234215
Entry<ScoreCardData> scoreCardData(String package, String version) => _cache
235216
.withPrefix('scorecard-data/')
236217
.withTTL(Duration(hours: 2))

app/test/search/search_rate_limit_test.dart

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)