mirror of
https://github.com/volodymyrsmirnov/MalwareMultiScan.git
synced 2025-08-24 05:22:22 +00:00
90 lines
3.1 KiB
C#
90 lines
3.1 KiB
C#
|
using System;
|
||
|
using System.IO;
|
||
|
using System.Net.Http;
|
||
|
using System.Threading;
|
||
|
using System.Threading.Tasks;
|
||
|
using MalwareMultiScan.Api.Data.Models;
|
||
|
using Microsoft.Extensions.Logging;
|
||
|
using MongoDB.Driver;
|
||
|
using MongoDB.Driver.GridFS;
|
||
|
|
||
|
namespace MalwareMultiScan.Api.Services
|
||
|
{
|
||
|
public class ScanRequestService
|
||
|
{
|
||
|
private const string CollectionName = "ScanRequests";
|
||
|
|
||
|
private readonly GridFSBucket _bucket;
|
||
|
private readonly IMongoCollection<ScanRequest> _collection;
|
||
|
private readonly BackendConfigurationReader _configurationReader;
|
||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||
|
private readonly ILogger<ScanRequestService> _logger;
|
||
|
|
||
|
public ScanRequestService(IMongoDatabase db, BackendConfigurationReader configurationReader,
|
||
|
IHttpClientFactory httpClientFactory, ILogger<ScanRequestService> logger)
|
||
|
{
|
||
|
_configurationReader = configurationReader;
|
||
|
_httpClientFactory = httpClientFactory;
|
||
|
_logger = logger;
|
||
|
|
||
|
_bucket = new GridFSBucket(db);
|
||
|
_collection = db.GetCollection<ScanRequest>(CollectionName);
|
||
|
}
|
||
|
|
||
|
private async Task QueueScans(string requestId, string fileName, Stream fileStream)
|
||
|
{
|
||
|
foreach (var backend in _configurationReader.Backends)
|
||
|
{
|
||
|
var cancellationTokenSource = new CancellationTokenSource(
|
||
|
TimeSpan.FromSeconds(5));
|
||
|
|
||
|
using var httpClient = _httpClientFactory.CreateClient();
|
||
|
|
||
|
try
|
||
|
{
|
||
|
var endpointUri = new Uri(
|
||
|
new Uri(backend.Endpoint), "/scan/file");
|
||
|
|
||
|
var formContent = new MultipartFormDataContent
|
||
|
{
|
||
|
{new StringContent("value1"), "callbackUrl"},
|
||
|
{new StreamContent(fileStream), "inputFile", fileName}
|
||
|
};
|
||
|
|
||
|
var response = await httpClient.PostAsync(
|
||
|
endpointUri, formContent, cancellationTokenSource.Token);
|
||
|
|
||
|
response.EnsureSuccessStatusCode();
|
||
|
|
||
|
// TODO: update scan request
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
_logger.LogError(e,
|
||
|
$"Failed to queue scanning job on {backend.Id} ({backend.Endpoint})");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public async Task<string> InitializeNewRequest(string fileName, Stream fileStream,
|
||
|
CancellationToken cancellationToken = default)
|
||
|
{
|
||
|
var fileId = await _bucket.UploadFromStreamAsync(fileName, fileStream,
|
||
|
cancellationToken: cancellationToken);
|
||
|
|
||
|
var scanRequest = new ScanRequest
|
||
|
{
|
||
|
FileId = fileId.ToString()
|
||
|
};
|
||
|
|
||
|
await _collection.InsertOneAsync(scanRequest, new InsertOneOptions
|
||
|
{
|
||
|
BypassDocumentValidation = false
|
||
|
}, cancellationToken);
|
||
|
|
||
|
await QueueScans(scanRequest.Id, fileName, fileStream);
|
||
|
|
||
|
return scanRequest.Id;
|
||
|
}
|
||
|
}
|
||
|
}
|