/// <summary> /// Create a Threat List Update Response. /// </summary> /// <param name="this"> /// A <see cref="ThreatListUpdateResponseModel" />. /// </param> /// <param name="request"> /// The <see cref="ThreatListUpdateRequest" /> made to the Google Safe Browsing API for which the /// <see cref="ThreatListUpdateResponse" /> has been returned. /// </param> /// <returns> /// A <see cref="ThreatListUpdateResponse" /> if <paramref name="this" /> is not a null reference. A null /// reference otherwise. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="request" /> is a null reference. /// </exception> internal static ThreatListUpdateResponse AsThreatListUpdateResponse(this ThreatListUpdateResponseModel @this, ThreatListUpdateRequest request) { ThreatListUpdateResponse threatListUpdateResponse = null; if (@this != null) { // ... // // Throws an exception if the operation fails. var threatListUpdateResponseBuilder = ThreatListUpdateResponse.Build(); threatListUpdateResponseBuilder.SetRequest(request); SetResults(@this, threatListUpdateResponseBuilder, request); threatListUpdateResponse = threatListUpdateResponseBuilder.Build(); } return(threatListUpdateResponse); // <summary> // Create Wait to Date. // </summary> DateTime?CreateWaitToDate(ThreatListUpdateResponseModel cThis) { DateTime?cWaitToDate = null; if (cThis.WaitDuration != null) { var cWaitDuration = cThis.WaitDuration.Substring(0, cThis.WaitDuration.Length - 1); var cIsWaitDurationParsed = double.TryParse(cWaitDuration, out var cWaitDurationDouble); if (cIsWaitDurationParsed) { cWaitToDate = DateTime.UtcNow.AddSeconds(cWaitDurationDouble); } } return(cWaitToDate); } // <summary> // Set Results. // </summary> void SetResults(ThreatListUpdateResponseModel cThis, ThreatListUpdateResponseBuilder cBuilder, ThreatListUpdateRequest cRequest) { if (cThis.Results != null) { var cThreatListRetrieveDate = DateTime.UtcNow; var cThreatListWaitToDate = CreateWaitToDate(cThis); foreach (var cResultModel in cThis.Results) { var cResult = cResultModel.AsThreatListUpdateResult(cRequest, cThreatListRetrieveDate, cThreatListWaitToDate); cBuilder.AddResult(cResult); } } } }
private async Task SynchronizeDatabaseAsync() { var cancellationToken = this._synchronizationTaskCancellationTokenSource.Token; while (!cancellationToken.IsCancellationRequested) { var getThreatListUpdatesTask = GetThreatListUpdatesAsync(this); var(threatListUpdateResponse, delayToDate) = await getThreatListUpdatesTask.ConfigureAwait(false); if (threatListUpdateResponse != null) { foreach (var threatListUpdateResult in threatListUpdateResponse.Results) { var threatListWaitToDate = threatListUpdateResult.RetrievedThreatList.WaitToDate; if (threatListWaitToDate != null && threatListWaitToDate < delayToDate) { delayToDate = threatListWaitToDate.Value; } var synchronizeThreatListTask = SynchronizeThreatListAsync(this, threatListUpdateResult); await synchronizeThreatListTask.ConfigureAwait(false); } } var delayToTask = DelayToAsync(this, delayToDate); await delayToTask.ConfigureAwait(false); } // <summary> // Delay to a Date Asynchronously. // </summary> async Task DelayToAsync(BrowsingDatabaseManager @this, DateTime cDate) { try { var cCancellationToken = @this._synchronizationTaskCancellationTokenSource.Token; var cDelayToTask = TaskExtension.DelayTo(cDate, cCancellationToken); await cDelayToTask.ConfigureAwait(false); } catch (OperationCanceledException) { // ... // // We don't care if the cancellation token is cancelled. } } // <summary> // Get Threat List Updates Asynchronously. // </summary> async Task <(ThreatListUpdateResponse, DateTime)> GetThreatListUpdatesAsync(BrowsingDatabaseManager @this) { var cDelayToDate = DateTime.UtcNow.AddMinutes(30); try { IEnumerable <ThreatListDescriptor> cThreatListDescriptors = @this._updateConstraints.Keys; if (@this._updateConstraints.Count == 0) { // ... // // If the database synchronizer is not restricted to specific threat lists, we retrieve all // available threat lists from the Google Safe Browsing API. We don't cache the result in case // new threat lists are made available between synchronization iterations. // // Throws an exception if the operation fails. var cGetThreatListDescriptorsTask = @this._client.GetThreatListDescriptorsAsync(); cThreatListDescriptors = await cGetThreatListDescriptorsTask.ConfigureAwait(false); } // ... // // Retrieve the threat lists from the database. Throws an exception if the operation fails. var cGetThreatListsTask = @this._database.GetThreatListsAsync(cThreatListDescriptors); var cThreatLists = await cGetThreatListsTask.ConfigureAwait(false); ThreatListUpdateRequestBuilder cThreatListUpdateRequestBuilder = null; foreach (var cThreatList in cThreatLists) { if (cThreatList.Expired) { cThreatListUpdateRequestBuilder = cThreatListUpdateRequestBuilder ?? ThreatListUpdateRequest.Build(); var cThreatListDescriptor = cThreatList.Descriptor; var cThreatListState = cThreatList.State; @this._updateConstraints.TryGetValue(cThreatListDescriptor, out var cThreatListUpdateConstraints); cThreatListUpdateRequestBuilder.AddQuery(b => { b.SetThreatListDescriptor(cThreatListDescriptor); b.SetThreatListState(cThreatListState); b.SetUpdateConstraints(cThreatListUpdateConstraints); return(b.Build()); }); } else { if (cThreatList.WaitToDate != null && cThreatList.WaitToDate < cDelayToDate) { // ... // // If the current threat list's wait to date is earlier than the previous threat // list's wait to date, take the current the threat list's wait to date instead. cDelayToDate = cThreatList.WaitToDate.Value; } } } ThreatListUpdateResponse cThreatListUpdateResponse = null; if (cThreatListUpdateRequestBuilder != null) { // ... // // Throws an exception if the operation fails. var cThreatListUpdateRequest = cThreatListUpdateRequestBuilder.Build(); var cGetThreatListUpdatesTask = @this._client.GetThreatListUpdatesAsync(cThreatListUpdateRequest); cThreatListUpdateResponse = await cGetThreatListUpdatesTask.ConfigureAwait(false); } return(cThreatListUpdateResponse, cDelayToDate); } catch { return(null, cDelayToDate); } } // <summary> // Synchronize Threat List Asynchronously. // </summary> async Task SynchronizeThreatListAsync(BrowsingDatabaseManager @this, ThreatListUpdateResult cThreatListUpdateResult) { var cSynchronizationStartDate = DateTime.UtcNow; var cThreatList = cThreatListUpdateResult.RetrievedThreatList; try { var cSha256HashPrefixes = cThreatListUpdateResult.ThreatsToAdd; if (cThreatListUpdateResult.IsFullUpdate) { // ... // // Throws an exception if the operation fails. var cModifyThreatListTask = @this._database.StoreThreatListAsync(cThreatList, cSha256HashPrefixes); await cModifyThreatListTask.ConfigureAwait(false); } else if (cThreatListUpdateResult.IsPartialUpdate) { // ... // // Throws an exception if the operation fails. var cIndices = cThreatListUpdateResult.ThreatsToRemove; var cModifyThreatListTask = @this._database.ModifyThreatListAsync(cThreatList, cSha256HashPrefixes, cIndices); await cModifyThreatListTask.ConfigureAwait(false); } // ... // // Throws an exception if the operation fails. var cComputeThreatListChecksumTask = @this._database.ComputeThreatListChecksumAsync(cThreatList.Descriptor); var cThreatListChecksum = await cComputeThreatListChecksumTask.ConfigureAwait(false); if (cThreatListChecksum != cThreatListUpdateResult.RetrievedThreatListChecksum) { // ... // // Throws an exception if the operation fails. cThreatList = ThreatList.CreateInvalid(cThreatList.Descriptor); var cUpdateConstraints = cThreatListUpdateResult.Query.UpdateConstraints; var cGetThreatListUpdatesTask = @this._client.GetThreatListUpdatesAsync(cThreatList, cUpdateConstraints); var cThreatListUpdateRequest = await cGetThreatListUpdatesTask.ConfigureAwait(false); cThreatListUpdateResult = cThreatListUpdateRequest.Results.First(); cSha256HashPrefixes = cThreatListUpdateResult.ThreatsToAdd; if (cThreatListUpdateResult.IsFullUpdate) { // ... // // Throws an exception if the operation fails. cThreatList = cThreatListUpdateResult.RetrievedThreatList; var cModifyThreatListTask = @this._database.StoreThreatListAsync(cThreatList, cSha256HashPrefixes); await cModifyThreatListTask.ConfigureAwait(false); } } // ... // // Invoke threat list synchronization completed event. var cSynchronizationCompletionDate = DateTime.UtcNow; @this.OnThreatListSynchronizationCompleted(new ThreatListSynchronizationCompletedEventArgs( cThreatList, cSynchronizationStartDate, cSynchronizationCompletionDate )); } catch (Exception cEx) { // ... // // Invoke threat list synchronization failed event. var cSynchronizationFailureDate = DateTime.UtcNow; @this.OnThreatListSynchronizationFailed(new ThreatListSynchronizationFailedEventArgs( cThreatList, cSynchronizationStartDate, cSynchronizationFailureDate, cEx )); } } }