22using Flow . Launcher . Infrastructure . Logger ;
33using System ;
44using System . Collections . Generic ;
5+ using System . Net ;
6+ using System . Net . Http ;
57using System . Text . Json ;
68using System . Threading ;
79using System . Threading . Tasks ;
@@ -10,43 +12,43 @@ namespace Flow.Launcher.Core.ExternalPlugins
1012{
1113 public static class PluginsManifest
1214 {
13- static PluginsManifest ( )
14- {
15- UpdateTask = UpdateManifestAsync ( ) ;
16- }
17-
18- public static List < UserPlugin > UserPlugins { get ; private set ; } = new List < UserPlugin > ( ) ;
19-
20- public static Task UpdateTask { get ; private set ; }
15+ private const string manifestFileUrl = "https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json" ;
2116
2217 private static readonly SemaphoreSlim manifestUpdateLock = new ( 1 ) ;
2318
24- public static Task UpdateManifestAsync ( )
25- {
26- if ( manifestUpdateLock . CurrentCount == 0 )
27- {
28- return UpdateTask ;
29- }
19+ private static string latestEtag = "" ;
3020
31- return UpdateTask = DownloadManifestAsync ( ) ;
32- }
21+ public static List < UserPlugin > UserPlugins { get ; private set ; } = new List < UserPlugin > ( ) ;
3322
34- private static async Task DownloadManifestAsync ( )
23+ public static async Task UpdateManifestAsync ( CancellationToken token = default )
3524 {
3625 try
3726 {
38- await manifestUpdateLock . WaitAsync ( ) . ConfigureAwait ( false ) ;
27+ await manifestUpdateLock . WaitAsync ( token ) . ConfigureAwait ( false ) ;
28+
29+ var request = new HttpRequestMessage ( HttpMethod . Get , manifestFileUrl ) ;
30+ request . Headers . Add ( "If-None-Match" , latestEtag ) ;
31+
32+ var response = await Http . SendAsync ( request , token ) . ConfigureAwait ( false ) ;
3933
40- await using var jsonStream = await Http . GetStreamAsync ( "https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json" )
41- . ConfigureAwait ( false ) ;
34+ if ( response . StatusCode == HttpStatusCode . OK )
35+ {
36+ Log . Info ( $ "|PluginsManifest.{ nameof ( UpdateManifestAsync ) } |Fetched plugins from manifest repo") ;
4237
43- UserPlugins = await JsonSerializer . DeserializeAsync < List < UserPlugin > > ( jsonStream ) . ConfigureAwait ( false ) ;
38+ var json = await response . Content . ReadAsStreamAsync ( token ) . ConfigureAwait ( false ) ;
39+
40+ UserPlugins = await JsonSerializer . DeserializeAsync < List < UserPlugin > > ( json , cancellationToken : token ) . ConfigureAwait ( false ) ;
41+
42+ latestEtag = response . Headers . ETag . Tag ;
43+ }
44+ else if ( response . StatusCode != HttpStatusCode . NotModified )
45+ {
46+ Log . Warn ( $ "|PluginsManifest.{ nameof ( UpdateManifestAsync ) } |Http response for manifest file was { response . StatusCode } ") ;
47+ }
4448 }
4549 catch ( Exception e )
4650 {
47- Log . Exception ( "|PluginManagement.GetManifest|Encountered error trying to download plugins manifest" , e ) ;
48-
49- UserPlugins = new List < UserPlugin > ( ) ;
51+ Log . Exception ( $ "|PluginsManifest.{ nameof ( UpdateManifestAsync ) } |Http request failed", e ) ;
5052 }
5153 finally
5254 {
0 commit comments