1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-28 14:46:14 -05:00
bitwarden/src/Icons/Services/IconFetchingService.cs
Matt Gibson 4377c7a897
Rewrite Icon fetching (#3023)
* Rewrite Icon fetching

* Move validation to IconUri, Uri, or UriBuilder

* `dotnet format` 🤖

* PR suggestions

* Add not null compiler hint

* Add twitter to test case

* Move Uri manipulation to UriService

* Implement MockedHttpClient

Presents better, fluent handling of message matching and response
building.

* Add redirect handling tests

* Add testing to models

* More aggressively dispose content in icon link

* Format 🤖

* Update icon lockfile

* Convert to cloned stream for HttpResponseBuilder

Content was being disposed when HttResponseMessage was being disposed.
This avoids losing our reference to our content and allows multiple
usages of the same `MockedHttpMessageResponse`

* Move services to extension

Extension is shared by testing and allows access to services from
our service tests

* Remove unused `using`

* Prefer awaiting asyncs for better exception handling

* `dotnet format` 🤖

* Await async

* Update tests to use test TLD and ip ranges

* Remove unused interfaces

* Make assignments static when possible

* Prefer invariant comparer to downcasing

* Prefer injecting interface services to implementations

* Prefer comparer set in HashSet initialization

* Allow SVG icons

* Filter out icons with unknown formats

* Seek to beginning of MemoryStream after writing it

* More appropriate to not return icon if it's invalid

* Add svg icon test
2023-08-08 19:29:40 +00:00

48 lines
1.5 KiB
C#

#nullable enable
using AngleSharp.Html.Parser;
using Bit.Icons.Extensions;
using Bit.Icons.Models;
namespace Bit.Icons.Services;
public class IconFetchingService : IIconFetchingService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<IIconFetchingService> _logger;
private readonly IHtmlParser _parser;
private readonly IUriService _uriService;
public IconFetchingService(ILogger<IIconFetchingService> logger, IHttpClientFactory httpClientFactory, IHtmlParser parser, IUriService uriService)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
_parser = parser;
_uriService = uriService;
}
public async Task<Icon?> GetIconAsync(string domain)
{
var domainIcons = await DomainIcons.FetchAsync(domain, _logger, _httpClientFactory, _parser, _uriService);
var result = domainIcons.Where(result => result != null).FirstOrDefault();
return result ?? await GetFaviconAsync(domain);
}
private async Task<Icon?> GetFaviconAsync(string domain)
{
// Fall back to favicon
var faviconUriBuilder = new UriBuilder
{
Scheme = "https",
Host = domain,
Path = "/favicon.ico"
};
if (faviconUriBuilder.TryBuild(out var faviconUri))
{
return await new IconLink(faviconUri!).FetchAsync(_logger, _httpClientFactory, _uriService);
}
return null;
}
}