Beispiel #1
0
 public DownloaderObjectModel(
     ref HttpClient httpClient,
     string url,
     string destination,
     bool enqueue,
     EventHandler downloadCreatedEventHandler,
     EventHandler downloadVerifyingEventHandler,
     EventHandler downloadVerifiedEventHandler,
     EventHandler downloadStartedEventHandler,
     EventHandler downloadStoppedEventHandler,
     EventHandler downloadEnqueuedEventHandler,
     EventHandler downloadDequeuedEventHandler,
     EventHandler downloadFinishedEventHandler,
     PropertyChangedEventHandler propertyChangedEventHandler,
     IProgress <long> bytesReporter,
     ref RequestThrottler requestThrottler) : this(
         ref httpClient,
         url,
         destination,
         enqueue,
         totalBytesToDownload : null,
         httpStatusCode : null,
         downloadCreatedEventHandler,
         downloadVerifyingEventHandler,
         downloadVerifiedEventHandler,
         downloadStartedEventHandler,
         downloadStoppedEventHandler,
         downloadEnqueuedEventHandler,
         downloadDequeuedEventHandler,
         downloadFinishedEventHandler,
         propertyChangedEventHandler,
         bytesReporter,
         ref requestThrottler)
 {
 }
Beispiel #2
0
        public void MultipleRequestWithSameApiKey()
        {
            //key TEST100 has rate Limit as 15
            apiKey = "TEST0000";

            int rateLimit = Config.GetRateLimitByAppId(apiKey);
            int successA = 0, successB = 0, successC = 0;

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successA++;
                }

                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successB++;
                }

                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successC++;
                }
            }

            Assert.IsTrue((successA + successB + successC) == rateLimit);
        }
Beispiel #3
0
        public async Task <HttpResponseMessage> FetchAllHotelAsync(DataSourceRequests request)
        {
            if (RequestThrottler.IsThrottled(request.ApiKey))
            {
                return(Request.CreateResponse((HttpStatusCode)429, "Too many requests."));
            }

            var result = await _hotelService.FetchAllHotels(request);

            return(Request.CreateResponse(HttpStatusCode.OK, result));
        }
Beispiel #4
0
        public void Throttle_AsManyRequestsAsLimit_NoException()
        {
            var request  = Substitute.For <IHttpRequest>();
            var response = Substitute.For <IHttpResponse>();

            authenticate(request);
            setupRepository(request);
            setupConfiguration(request, 2, 30.Seconds());

            var subject = new RequestThrottler();

            Assert.That(() => subject.Throttle(request, response), Throws.Nothing);
            Assert.That(() => subject.Throttle(request, response), Throws.Nothing);
        }
Beispiel #5
0
        public void WhenAppIdNotExistsInConfigAssignDefaultRate()
        {
            //Default rate limit is 10 in config.
            apiKey = "XXZZZZZ";
            int success = 0;

            int rateLimit = Config.GetRateLimitByAppId(apiKey);

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
            }

            Assert.IsTrue(success == rateLimit);
        }
Beispiel #6
0
        public void WhenRateLimitExceedsCheckIfKeyIsBlocked()
        {
            //key HD700 has default rate Limit 10
            apiKey = "HD700";
            bool isBlocked = false;

            for (int i = 1; i <= 11; i++)
            {
                if (RequestThrottler.IsThrottled(apiKey))
                {
                    if (RequestThrottler._cache.ContainsKey($"{apiKey}-BLOCKED"))
                    {
                        isBlocked = true;
                    }
                }
            }
            Assert.IsTrue(isBlocked);
        }
Beispiel #7
0
        public void WhenNumberOfRequestIsEqualToRateLimit()
        {
            //key TEST100 has rate Limit as 15
            apiKey = "TEST102";

            int rateLimit = Config.GetRateLimitByAppId(apiKey);
            int success   = 0;

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
            }

            Assert.IsTrue(rateLimit == success);
        }
Beispiel #8
0
        public void WhenNumberOfRequestIsGreaterThanRateLimit()
        {
            //key TEST101 has rate Limit as 20
            apiKey = "TEST100";
            int success = 0, failed = 0;

            int rateLimit = Config.GetRateLimitByAppId(apiKey);

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
                else
                {
                    failed++;
                }
            }

            Assert.IsTrue(rateLimit - success == failed);
        }
Beispiel #9
0
        public DownloaderViewModel(DisplayMessageDelegate displayMessage, ShowUrlsDelegate showUrls)
        {
            _client                           = new HttpClient();
            DownloadItemsList                 = new ObservableCollection <DownloaderObjectModel>();
            CategoriesList                    = new ObservableCollection <Category>();
            QueueProcessor                    = new QueueProcessor(Settings.Default.MaxParallelDownloads, QueueProcessor_PropertyChanged);
            _requestThrottler                 = new RequestThrottler(AppConstants.RequestThrottlerInterval);
            CollectionView                    = CollectionViewSource.GetDefaultView(DownloadItemsList);
            CollectionView.CurrentChanged    += CollectionView_CurrentChanged;
            _clipboardService                 = new ClipboardObserver();
            _semaphoreMeasuringSpeed          = new SemaphoreSlim(1);
            _semaphoreUpdatingList            = new SemaphoreSlim(1);
            _semaphoreRefreshingView          = new SemaphoreSlim(1);
            _ctsUpdatingList                  = null;
            _ctsRefreshView                   = null;
            _displayMessage                   = displayMessage;
            _lockDownloadItemsList            = DownloadItemsList;
            _lockBytesDownloaded              = this.BytesDownloaded;
            _lockBytesTransferredOverLifetime = Settings.Default.BytesTransferredOverLifetime;
            _showUrls                         = showUrls;
            this.Count                        = 0;
            this.DownloadingCount             = 0;
            this.ErroredCount                 = 0;
            this.FinishedCount                = 0;
            this.PausedCount                  = 0;
            this.QueuedCount                  = 0;
            this.ReadyCount                   = 0;
            this.VerifyingCount               = 0;
            this.BytesDownloaded              = 0;
            this.Status                       = "Ready";
            this.ProgressReporter             = new Progress <long>(value =>
            {
                Monitor.Enter(_lockBytesDownloaded);
                try
                {
                    this.BytesDownloaded += value;
                }
                finally
                {
                    Monitor.Exit(_lockBytesDownloaded);
                }
            });

            AddCommand                    = new RelayCommand <object>(Add);
            StartCommand                  = new RelayCommand <object>(Start);
            RemoveFromListCommand         = new RelayCommand <object>(RemoveFromList);
            CancelCommand                 = new RelayCommand <object>(Cancel);
            PauseCommand                  = new RelayCommand <object>(Pause);
            OpenCommand                   = new RelayCommand <object>(Open);
            OpenContainingFolderCommand   = new RelayCommand <object>(OpenContainingFolder);
            StartQueueCommand             = new RelayCommand <object>(StartQueue);
            StopQueueCommand              = new RelayCommand <object>(StopQueue);
            CloseAppCommand               = new RelayCommand <object>(CloseApp);
            CategoryChangedCommand        = new RelayCommand <object>(CategoryChanged);
            OptionsCommand                = new RelayCommand <object>(ShowOptions);
            EnqueueCommand                = new RelayCommand <object>(Enqueue);
            DequeueCommand                = new RelayCommand <object>(Dequeue);
            DeleteFileCommand             = new RelayCommand <object>(DeleteFile);
            RecheckCommand                = new RelayCommand <object>(Recheck);
            RedownloadCommand             = new RelayCommand <object>(Redownload);
            CopyLinkToClipboardCommand    = new RelayCommand <object>(CopyLinkToClipboard);
            ClearFinishedDownloadsCommand = new RelayCommand <object>(ClearFinishedDownloads);
            CancelBackgroundTaskCommand   = new RelayCommand <object>(
                CancelBackgroundTask, CancelBackgroundTask_CanExecute);
            CheckForUpdatesCommand = new RelayCommand <object>(CheckForUpdates);
            ShowHelpTopicsCommand  = new RelayCommand <object>(ShowHelpTopics);

            foreach (Category cat in (Category[])Enum.GetValues(typeof(Category)))
            {
                CategoriesList.Add(cat);
            }

            // Load last selected category
            if (string.IsNullOrEmpty(Settings.Default.LastSelectedCatagory))
            {
                SwitchCategory(Category.All);
            }
            else
            {
                SwitchCategory((Category)Enum.Parse(typeof(Category), Settings.Default.LastSelectedCatagory));
            }

            // Check for updates
            if (Settings.Default.AutoCheckForUpdates)
            {
                Task.Run(async() => await TriggerUpdateCheckAsync(true));
            }

            // Populate history
            Task.Run(async() =>
            {
                await _semaphoreUpdatingList.WaitAsync();

                _ctsUpdatingList = new CancellationTokenSource();
                var ct           = _ctsUpdatingList.Token;

                RaisePropertyChanged(nameof(this.IsBackgroundWorking));

                try
                {
                    if (Directory.Exists(AppPaths.LocalAppData))
                    {
                        this.Status = "Restoring data...";
                        RaisePropertyChanged(nameof(this.Status));
                    }
                    else
                    {
                        return;
                    }

                    SerializableDownloaderObjectModelList source;
                    var xmlReader = new XmlSerializer(typeof(SerializableDownloaderObjectModelList));

                    using (var streamReader = new StreamReader(AppPaths.DownloadsHistoryFile))
                    {
                        source = (SerializableDownloaderObjectModelList)xmlReader.Deserialize(streamReader);
                    }

                    var sourceObjects = source.Objects.ToArray();
                    var finalObjects  = new DownloaderObjectModel[sourceObjects.Count()];
                    var total         = sourceObjects.Count();

                    for (int i = 0; i < sourceObjects.Count(); i++)
                    {
                        if (ct.IsCancellationRequested)
                        {
                            break;
                        }
                        if (sourceObjects[i] == null)
                        {
                            continue;
                        }

                        int progress  = (int)((double)(i + 1) / total * 100);
                        this.Progress = progress;
                        this.Status   = "Restoring " + (i + 1) + " of " + total + ": " + sourceObjects[i].Url;
                        RaisePropertyChanged(nameof(this.Progress));
                        RaisePropertyChanged(nameof(this.Status));

                        var item = new DownloaderObjectModel(
                            ref _client,
                            sourceObjects[i].Url,
                            sourceObjects[i].Destination,
                            sourceObjects[i].IsQueued,
                            sourceObjects[i].TotalBytesToDownload,
                            sourceObjects[i].StatusCode,
                            Download_Created,
                            Download_Verifying,
                            Download_Verified,
                            Download_Started,
                            Download_Stopped,
                            Download_Enqueued,
                            Download_Dequeued,
                            Download_Finished,
                            Download_PropertyChanged,
                            ProgressReporter,
                            ref _requestThrottler);
                        item.SetCreationTime(sourceObjects[i].DateCreated);

                        finalObjects[i] = item;
                    }

                    this.Status = "Listing...";
                    RaisePropertyChanged(nameof(this.Status));

                    AddObjects(finalObjects);
                }
                catch
                {
                    return;
                }
                finally
                {
                    _ctsUpdatingList = null;

                    this.Progress = 0;
                    this.Status   = "Ready";
                    RaisePropertyChanged(nameof(this.Progress));
                    RaisePropertyChanged(nameof(this.Status));
                    RaisePropertyChanged(nameof(this.IsBackgroundWorking));

                    _semaphoreUpdatingList.Release();

                    RefreshCollection();
                }
            });
        }
Beispiel #10
0
        public DownloaderObjectModel(
            ref HttpClient httpClient,
            string url,
            string destination,
            bool enqueue,
            long?totalBytesToDownload,
            HttpStatusCode?httpStatusCode,
            EventHandler downloadCreatedEventHandler,
            EventHandler downloadVerifyingEventHandler,
            EventHandler downloadVerifiedEventHandler,
            EventHandler downloadStartedEventHandler,
            EventHandler downloadStoppedEventHandler,
            EventHandler downloadEnqueuedEventHandler,
            EventHandler downloadDequeuedEventHandler,
            EventHandler downloadFinishedEventHandler,
            PropertyChangedEventHandler propertyChangedEventHandler,
            IProgress <long> bytesReporter,
            ref RequestThrottler requestThrottler)
        {
            _httpClient           = httpClient;
            _semaphoreDownloading = new SemaphoreSlim(1);
            _reportBytesProgress  = bytesReporter;
            _requestThrottler     = requestThrottler;
            TempDestination       = destination + AppConstants.DownloaderSplitedPartExtension;

            PropertyChanged   += propertyChangedEventHandler;
            DownloadCreated   += downloadCreatedEventHandler;
            DownloadVerifying += downloadVerifyingEventHandler;
            DownloadVerified  += downloadVerifiedEventHandler;
            DownloadStarted   += downloadStartedEventHandler;
            DownloadStopped   += downloadStoppedEventHandler;
            DownloadEnqueued  += downloadEnqueuedEventHandler;
            DownloadDequeued  += downloadDequeuedEventHandler;
            DownloadFinished  += downloadFinishedEventHandler;

            this.Name                       = Path.GetFileName(destination);
            this.Url                        = url;
            this.Destination                = destination;
            this.Status                     = DownloadStatus.Ready;
            this.Progress                   = 0;
            this.TotalBytesCompleted        = 0;
            this.TotalBytesToDownload       = null;
            this.BytesDownloadedThisSession = 0;
            this.SupportsResume             = false;
            this.Speed                      = null;
            this.DateCreated                = DateTime.Now;
            this.NumberOfActiveStreams      = null;
            this.StatusCode                 = null;
            this.TimeRemaining              = null;
            this.IsQueued                   = false;

            if (enqueue)
            {
                this.Enqueue();
            }

            _semaphoreDownloading.Wait();
            Task.Run(async() =>
            {
                if (totalBytesToDownload > 0)
                {
                    var restore = new RequestModel();
                    restore.TotalBytesToDownload = totalBytesToDownload;
                    restore.StatusCode           = httpStatusCode;
                    restore.Url = url;
                    await VerifyDownloadAsync(url, restore);
                }
                else
                {
                    await VerifyDownloadAsync(url);
                }
                _semaphoreDownloading.Release();
            });

            RaiseEvent(DownloadCreated);
        }