blob: d0770ece3e447df22c948a91ae9397f451763fd1 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
using Blazored.SessionStorage;
using LibGit.Extensions;
using LibGit.Interfaces;
using Microsoft.AspNetCore.Components.WebAssembly.Http;
namespace GitRepoViewer;
public class WebRepoSource : IRepoSource
{
private const bool _debug = false;
public WebRepoSource(string basePath)
{
BasePath = basePath;
}
public string BasePath { get; set; }
public ISessionStorageService? SessionStorage { private get; set; }
public async Task<Stream> GetFileStream(string path)
{
if(_debug)Console.WriteLine("Fetching file: " + Path.Join(BasePath, path));
var _path = Path.Join(BasePath, path);
if (SessionStorage != null && await SessionStorage.ContainKeyAsync(_path))
{
//Console.WriteLine("Found file in session storage: " + _path);
return new MemoryStream((await SessionStorage.GetItemAsync<IEnumerable<byte>>(_path)).ToArray());
}
var request = new HttpRequestMessage(HttpMethod.Get, _path);
// request.SetBrowserRequestMode(BrowserRequestMode.NoCors);
var client = new HttpClient();
var response = await client.SendAsync(request);
if(!response.IsSuccessStatusCode) throw new Exception("Failed to fetch file: " + _path);
if(SessionStorage != null && response.Content.Headers.ContentLength.HasValue && response.Content.Headers.ContentLength.Value < 1_000_000 && !noCachePathPrefixes.Any(prefix => path.StartsWith(prefix)))
{
Console.WriteLine($"Liberally caching file: {_path} ({response.Content.Headers.ContentLength.Value} bytes)");
var stream = await response.Content.ReadAsStreamAsync();
await SessionStorage.SetItemAsync(_path, stream.Peek(response.Content.Headers.ContentLength.Value));
return stream;
}
if(!noCachePathPrefixes.Any(prefix => path.StartsWith(prefix)))
Console.WriteLine($"Not caching file: {_path} ({response.Content.Headers.ContentLength.Value} bytes): blacklisted prefix");
return await response.Content.ReadAsStreamAsync();
}
public Task<Stream> GetObjectStreamById(string objectId)
{
Console.WriteLine("Fetching object: " + objectId + " from " + BasePath + "objects/" + objectId[..2] + "/" + objectId[2..] + "");
return GetFileStream(Path.Join("objects", objectId[..2], objectId[2..]));
}
public async Task<bool> HasObjectCached(string objectId)
{
var _path = Path.Join(BasePath, "objects/", objectId[..2], "/", objectId[2..]);
return SessionStorage != null && await SessionStorage.ContainKeyAsync(_path);
}
private static readonly string[] noCachePathPrefixes = { "HEAD", "info", "refs" };
}
|