Skip to content

Commit

Permalink
[WIP] (#102) Content Proxy: add initial cache settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Aug 19, 2022
1 parent 55137e9 commit 1270ab1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
22 changes: 14 additions & 8 deletions Emulsion.ContentProxy/FileCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ open System.Text

open Serilog

// TODO: Total cache limit
type FileCache(logger: ILogger,
settings: FileCacheSettings,
sha256: SHA256) =

let getFromCache uri (cacheKey: string) = async {
let hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(cacheKey)) |> Convert.ToBase64String
let hash =
cacheKey
|> Encoding.UTF8.GetBytes
|> sha256.ComputeHash
|> Convert.ToBase64String
let path = Path.Combine(settings.CacheDirectory, hash)
do! Async.SwitchToThreadPool()
return
if File.Exists path then
Some(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Delete))
Expand All @@ -23,26 +29,26 @@ type FileCache(logger: ILogger,

let ensureFreeCache size = async {
if size > settings.FileSizeLimit then
return None
return false
else
failwith "TODO"
failwith "TODO: Sanity check that cache only has files"
}

member _.DownloadLink(uri: Uri, cacheKey: string, size: int64): Async<Stream option> = async {
logger.Information("Cache lookup for content {Uri} (cache key {CacheKey})", uri, cacheKey)
match! getFromCache uri cacheKey with
| Some content ->
logger.Information("Cache hit for content {Uri} (cache key {CacheKey})", uri, cacheKey,)
logger.Information("Cache hit for content {Uri} (cache key {CacheKey})", uri, cacheKey)
return Some content
| None ->
logger.Information("No cache hit for content {Uri} (cache key {CacheKey}), will download", uri, cacheKey,)
let! cache = ensureFreeCache size
logger.Information("No cache hit for content {Uri} (cache key {CacheKey}), will download", uri, cacheKey)
let! shouldCache = ensureFreeCache size
if shouldCache then
logger.Information("Resource {Uri} (cache key {CacheKey}, {Size} bytes) will fit into cache, caching", uri, cacheKey, size)
let! result = downloadIntoCacheAndGet uri
logger.Information("Resource {Uri} (cache key {CacheKey}, {Size} bytes) downloaded", uri, cacheKey,, size)
logger.Information("Resource {Uri} (cache key {CacheKey}, {Size} bytes) downloaded", uri, cacheKey, size)
return result
else
logger.Information("Resource {Uri} (cache key {CacheKey}) won't fit into cache, directly downloading", uri, cacheKey,)
logger.Information("Resource {Uri} (cache key {CacheKey}) won't fit into cache, directly downloading", uri, cacheKey)
return! download uri
}
18 changes: 17 additions & 1 deletion Emulsion.Settings/Settings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ type HostingSettings = {
HashIdSalt: string
}

type FileCacheSettings = {
FileSizeLimitBytes: uint64
}

type EmulsionSettings = {
Xmpp: XmppSettings
Telegram: TelegramSettings
Log: LogSettings
Database: DatabaseSettings option
Hosting: HostingSettings option
FileCache: FileCacheSettings option
}

let defaultConnectionTimeout = TimeSpan.FromMinutes 5.0
Expand All @@ -56,6 +61,12 @@ let private readTimeSpan defaultVal key section =
|> Option.defaultValue defaultVal

let read (config : IConfiguration) : EmulsionSettings =
let uint64OrDefault value ``default`` =
value
|> Option.ofObj
|> Option.map uint64
|> Option.defaultValue ``default``

let readXmpp (section : IConfigurationSection) = {
Login = section["login"]
Password = section["password"]
Expand Down Expand Up @@ -91,9 +102,14 @@ let read (config : IConfiguration) : EmulsionSettings =
}
| None, None, None -> None
| other -> failwith $"Parameter pack {other} represents invalid hosting settings."
let readFileCache(section: IConfigurationSection) = Some {
// TODO: should be None if the directory is not defined
FileSizeLimitBytes = uint64OrDefault section["fileSizeLimitBytes"] 1048576UL
}

{ Xmpp = readXmpp <| config.GetSection("xmpp")
Telegram = readTelegram <| config.GetSection("telegram")
Log = readLog <| config.GetSection "log"
Database = readDatabase <| config.GetSection "database"
Hosting = readHosting <| config.GetSection "hosting" }
Hosting = readHosting <| config.GetSection "hosting"
FileCache = readFileCache <| config.GetSection "fileCache" }
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ settings, there're defaults:
"messageTimeout": "00:05:00",
"pingInterval": null,
"pingTimeout": "00:00:30"
},
"fileCache": {
"fileSizeLimitBytes": 1048576
}
}
```
Expand All @@ -36,7 +39,7 @@ Note that `pingInterval` of `null` disables XMPP ping support.

### Telegram Content Proxy

There's **unfinished** Telegram content proxy support, for XMPP users to access Telegram content without directly opening links on t.me. Right now, it will only generate a redirect to the corresponding t.me URI, so it doesn't help a lot. But in the future, proper content proxy will be supported.
There's Telegram content proxy support, for XMPP users to access Telegram content without directly opening links on t.me.

To enable it, configure the `database` and `hosting` configuration file sections:

Expand All @@ -49,7 +52,8 @@ To enable it, configure the `database` and `hosting` configuration file sections
"externalUriBase": "https://example.com/api/",
"bindUri": "http://*:5000/",
"hashIdSalt": "test"
}
},
"fileCache": {}
}
```

Expand All @@ -61,6 +65,8 @@ If all the parameters are set, then Emulsion will save the incoming messages int

The content identifiers in question are generated from the database ones using the [hashids.net][hashids.net] library, `hashIdSalt` is used in generation. This should complicate guessing of content ids for any external party not reading the chat directly.

If the `fileCache` section is not set, then the content proxy will only generate redirects to corresponding t.me URIs.

### Recommended Network Configuration

Current configuration system allows the following:
Expand Down
3 changes: 2 additions & 1 deletion emulsion.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
"externalUriBase": "https://example.com/api/",
"bindUri": "http://*:5000",
"hashIdSalt": "test"
}
},
"fileCache": {}
}

0 comments on commit 1270ab1

Please sign in to comment.