Anyone could mint signed proxy URLs (a remote account changes its icon, an anonymous lookup returns the URL), and each anonymous request held up to 40 MB in memory; the cache grew without bound between hourly trims; two clients asking for the same new file downloaded it twice and wrote over each other in place, so a reader could get half a file with a 7-day cache header; a file over the limit was downloaded twice on every request; a failed fetch, a 404, was cached by browsers for a week; cached media of a server suspended later were still served, and RejectMedia skipped avatars, emoji, covers, video variants, link cards and remote edits; /clientapi/group/members returned remote pictures raw. Now a download is shared by everyone asking at once, streamed into a .part file and renamed into place (FederationHttp.DownloadMedia copies bounded, never into memory), at most eight at a time; a file too big to cache is remembered for an hour and only streamed, a failure for five minutes; the cache's size is counted as it grows and trimmed as soon as it passes the cap; a cached file is opened before it is answered; browsers may cache only a success; nothing of a suspended server, or of one whose media are rejected, is proxied (everything remote a client sees goes through the proxy, so that covers every kind), and blocking one purges its cache; the proxy has its own rate limit per client address; group members' pictures are proxied; the proxy's key is loaded once, the oldest if two were made. This changes what PrivaPub serves its clients, not what it sends to other servers. Tests: clients asking at once share one download, a failure isn't cached by browsers, an over-limit file is fetched three times for two requests instead of four, a blocked server's media are refused and its cache purged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
38 lines
1.3 KiB
JSON
38 lines
1.3 KiB
JSON
{
|
|
"MongoSettings": {
|
|
"Database": "PrivaPub",
|
|
"LogsDatabase": "logs",
|
|
"ConnectionString": "mongodb://mongo:27017"
|
|
},
|
|
"AppConfiguration": {
|
|
"Version": "0.0.0",
|
|
"MaxAllowedUploadFiles": 3,
|
|
"MaxAllowedFileSize": 2097152,
|
|
"SupportedLanguages": [ "en" ],
|
|
"BackendBaseAddress": "https://privapub.test",
|
|
"FrontendBaseAddress": "https://privapub.test",
|
|
"HashingOptions": { "Iterations": 10101 },
|
|
"Jwt": {
|
|
"Key": "pasture-only-key-not-a-secret-pasture-only-key-not-a-secret-0123456789",
|
|
"Issuer": "http://privapub.test",
|
|
"Audience": "http://privapub.test",
|
|
"HoursTimeout": 24
|
|
}
|
|
},
|
|
"Federation": {
|
|
"AllowPrivateNetworks": true,
|
|
"AllowPlainHttp": true,
|
|
"AcceptAnyCertificate": true,
|
|
"Relays": [ "https://relay.test/actor", "https://aoderelay.test/actor" ]
|
|
},
|
|
"Media": { "Root": "/tmp/privapub-media" },
|
|
"RateLimits": { "AccountsPerMinute": 1000, "UploadsBurst": 1000, "UploadsPerMinute": 1000, "ProxyBurst": 100000, "ProxyPerMinute": 100000 },
|
|
"Registrations": { "Mode": "Open" },
|
|
"Statistics": { "Geo": { "AutoUpdate": false } },
|
|
"Kestrel": { "Endpoints": { "Http": { "Url": "http://0.0.0.0:80", "Protocols": "Http1AndHttp2" } } },
|
|
"Serilog": {
|
|
"MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } },
|
|
"WriteTo": [ { "Name": "Console" } ]
|
|
}
|
|
}
|