mirror of
https://github.com/volodymyrsmirnov/MalwareMultiScan.git
synced 2025-08-24 05:22:22 +00:00
111 lines
3.8 KiB
C#
111 lines
3.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MalwareMultiScan.Api.Data.Configuration;
|
|
using MalwareMultiScan.Shared.Data.Requests;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using YamlDotNet.Serialization;
|
|
using YamlDotNet.Serialization.NamingConventions;
|
|
|
|
namespace MalwareMultiScan.Api.Services
|
|
{
|
|
public class ScanBackendService
|
|
{
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly ILogger<ScanBackendService> _logger;
|
|
|
|
public ScanBackendService(IConfiguration configuration, IHttpClientFactory httpClientFactory,
|
|
ILogger<ScanBackendService> logger)
|
|
{
|
|
_httpClientFactory = httpClientFactory;
|
|
_logger = logger;
|
|
var configurationPath = configuration.GetValue<string>("BackendsConfiguration");
|
|
|
|
if (!File.Exists(configurationPath))
|
|
throw new FileNotFoundException("Missing BackendsConfiguration YAML file", configurationPath);
|
|
|
|
var configurationContent = File.ReadAllText(configurationPath);
|
|
|
|
var deserializer = new DeserializerBuilder()
|
|
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
|
.Build();
|
|
|
|
List = deserializer.Deserialize<ScanBackend[]>(configurationContent);
|
|
}
|
|
|
|
public ScanBackend[] List { get; }
|
|
|
|
public async Task<bool> Ping(ScanBackend backend)
|
|
{
|
|
var cancellationTokenSource = new CancellationTokenSource(
|
|
TimeSpan.FromSeconds(1));
|
|
|
|
try
|
|
{
|
|
using var httpClient = _httpClientFactory.CreateClient();
|
|
|
|
var pingResponse = await httpClient.GetAsync(
|
|
new Uri(new Uri(backend.Endpoint), "/ping"), cancellationTokenSource.Token);
|
|
|
|
pingResponse.EnsureSuccessStatusCode();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
_logger.LogError(
|
|
exception, $"Failed to ping {backend.Id}");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task<bool> QueueScan(ScanBackend backend, string uri, HttpContent content)
|
|
{
|
|
var cancellationTokenSource = new CancellationTokenSource(
|
|
TimeSpan.FromSeconds(5));
|
|
|
|
using var httpClient = _httpClientFactory.CreateClient();
|
|
|
|
try
|
|
{
|
|
var response = await httpClient.PostAsync(
|
|
new Uri(new Uri(backend.Endpoint), uri), content, cancellationTokenSource.Token);
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
_logger.LogError(
|
|
exception, $"Failed to initiate scan against {backend.Id}");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public async Task<bool> QueueFileScan(
|
|
ScanBackend backend, string fileName, Stream fileStream, string callbackUrl)
|
|
{
|
|
return await QueueScan(backend, "/scan/file", new MultipartFormDataContent
|
|
{
|
|
{new StringContent(callbackUrl), nameof(FileRequest.CallbackUrl)},
|
|
{new StreamContent(fileStream), nameof(FileRequest.InputFile), fileName}
|
|
});
|
|
}
|
|
|
|
public async Task<bool> QueueUrlScan(
|
|
ScanBackend backend, string url, string callbackUrl)
|
|
{
|
|
return await QueueScan(backend, "/scan/url", new MultipartFormDataContent
|
|
{
|
|
{new StringContent(callbackUrl), nameof(UrlRequest.CallbackUrl)},
|
|
{new StringContent(url), nameof(UrlRequest.InputUrl)}
|
|
});
|
|
}
|
|
}
|
|
} |