public static async Task <SpeedtestResult> DoSpeedTestHttpAsync(HttpClient httpClient, string url, int seconds = 25) { Logger.Info($"Do HTTP speedtest for {url}"); HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); if (!httpResponseMessage.IsSuccessStatusCode || httpResponseMessage.RequestMessage.RequestUri.ToString() != url) { httpClient.DefaultRequestHeaders.Referrer = GetUrlDirectory(url); httpResponseMessage.Dispose(); httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); } try { using (Stream stream = await httpResponseMessage.Content.ReadAsStreamAsync()) { SpeedtestResult speedtestResult = SpeedtestFromStream(stream, seconds); return(speedtestResult); } } finally { httpResponseMessage.Dispose(); } }
public static async Task <SpeedtestResult> DoSpeedTestFtpAsync(FtpClient ftpClient, string url, int seconds = 25) { Logger.Info($"Do FTP speedtest for {url}"); Uri uri = new Uri(url); using (Stream stream = await ftpClient.OpenReadAsync(uri.LocalPath)) { SpeedtestResult speedtestResult = SpeedtestFromStream(stream, seconds); return(speedtestResult); } }
public static async Task <SpeedtestResult> DoSpeedTestHttpAsync(HttpClient httpClient, string url, int seconds = 25) { Logger.Info($"Do HTTP speedtest for {url}"); HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); if (!httpResponseMessage.IsSuccessStatusCode || httpResponseMessage.RequestMessage.RequestUri.ToString() != url) { httpClient.DefaultRequestHeaders.Referrer = GetUrlDirectory(url); httpResponseMessage.Dispose(); httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); } if (!httpResponseMessage.IsSuccessStatusCode || httpResponseMessage.RequestMessage.RequestUri.ToString() != url) { string retrievedUrl = null; if (httpResponseMessage.RequestMessage.RequestUri.ToString() != url) { retrievedUrl = httpResponseMessage.RequestMessage.RequestUri.ToString(); } else if (httpResponseMessage.Headers.Location is not null) { retrievedUrl = httpResponseMessage.Headers.Location.ToString(); } Logger.Warn($"Speedtest cancelled because it returns HTTP {(int)httpResponseMessage.StatusCode}{(retrievedUrl is not null ? $" with URL {retrievedUrl}" : string.Empty)}"); return(new SpeedtestResult()); } try { using (Stream stream = await httpResponseMessage.Content.ReadAsStreamAsync()) { SpeedtestResult speedtestResult = SpeedtestFromStream(stream, seconds); return(speedtestResult); } } finally { httpResponseMessage.Dispose(); } }
private static SpeedtestResult SpeedtestFromStream(Stream stream, int seconds) { int miliseconds = seconds * 1000; Stopwatch stopwatch = Stopwatch.StartNew(); long totalBytesRead = 0; byte[] buffer = new byte[2048]; int bytesRead; List <KeyValuePair <long, long> > measurements = new List <KeyValuePair <long, long> >(10_000); long previousTime = 0; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { if (stopwatch.ElapsedMilliseconds >= miliseconds) { break; } if (previousTime / 1000 < stopwatch.ElapsedMilliseconds / 1000) { ClearCurrentLine(); long maxBytesPerSecond = measurements.Any() ? measurements.GroupBy(m => m.Key / 1000).Max(s => GetSpeedInBytes(s, 1000)) : 0; Console.Write($"Downloaded: {FileSizeHelper.ToHumanReadable(totalBytesRead)}, Time: {stopwatch.ElapsedMilliseconds / 1000}s, Speed: {FileSizeHelper.ToHumanReadable(maxBytesPerSecond):F1)}/s ({FileSizeHelper.ToHumanReadable(maxBytesPerSecond * 8, true):F0}/s)"); } if (stopwatch.ElapsedMilliseconds >= 10_000) { // Second changed if (previousTime / 1000 < stopwatch.ElapsedMilliseconds / 1000) { List <IGrouping <long, KeyValuePair <long, long> > > perSecond = measurements.GroupBy(m => m.Key / 1000).ToList(); if (!perSecond.Any()) { break; } double maxSpeedLastSeconds = perSecond.TakeLast(3).Max(s => GetSpeedInBytes(s, 1000)); double maxSpeedBefore = perSecond.Take(perSecond.Count - 3).Max(s => GetSpeedInBytes(s, 1000)); // If no improvement in speed if (maxSpeedBefore > maxSpeedLastSeconds) { break; } } } totalBytesRead += bytesRead; measurements.Add(new KeyValuePair <long, long>(stopwatch.ElapsedMilliseconds, totalBytesRead)); previousTime = stopwatch.ElapsedMilliseconds; } Console.WriteLine(); stopwatch.Stop(); SpeedtestResult speedtestResult = new SpeedtestResult { DownloadedBytes = totalBytesRead, ElapsedMilliseconds = stopwatch.ElapsedMilliseconds, MaxBytesPerSecond = measurements.Any() ? measurements.GroupBy(m => m.Key / 1000).Max(s => GetSpeedInBytes(s, 1000)) : 0 }; if (measurements.Any()) { Logger.Info($"Downloaded: {speedtestResult.DownloadedMBs:F2} MB, Time: {speedtestResult.ElapsedMilliseconds} ms, Speed: {FileSizeHelper.ToHumanReadable(speedtestResult.MaxBytesPerSecond):F1)}/s ({FileSizeHelper.ToHumanReadable(speedtestResult.MaxBytesPerSecond * 8, true):F0}/s)"); } else { Logger.Warn($"Speedtest failed, nothing downloaded."); } return(speedtestResult); }
public static async Task <SpeedtestResult> DoSpeedTestAsync(HttpClient httpClient, string url, int seconds = 25) { Logger.Info($"Do speedtest for {url}"); HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); if (!httpResponseMessage.IsSuccessStatusCode || httpResponseMessage.RequestMessage.RequestUri.ToString() != url) { httpClient.DefaultRequestHeaders.Referrer = GetUrlDirectory(url); httpResponseMessage.Dispose(); httpResponseMessage = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); } try { using (Stream stream = await httpResponseMessage.Content.ReadAsStreamAsync()) { int miliseconds = seconds * 1000; Stopwatch stopwatch = Stopwatch.StartNew(); long totalBytesRead = 0; byte[] buffer = new byte[2048]; int bytesRead; List <KeyValuePair <long, long> > measurements = new List <KeyValuePair <long, long> >(10_000); long previousTime = 0; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { if (stopwatch.ElapsedMilliseconds >= miliseconds) { break; } if (stopwatch.ElapsedMilliseconds >= 10_000) { // Second changed if (previousTime / 1000 < stopwatch.ElapsedMilliseconds / 1000) { List <IGrouping <long, KeyValuePair <long, long> > > perSecond = measurements.GroupBy(m => m.Key / 1000).ToList(); double maxSpeedLastSeconds = perSecond.TakeLast(3).Max(s => GetSpeedInMBs(s, 1000)); double maxSpeedBefore = perSecond.Take(perSecond.Count - 3).Max(s => GetSpeedInMBs(s, 1000)); // If no improvement in speed if (maxSpeedBefore > maxSpeedLastSeconds) { break; } } } totalBytesRead += bytesRead; measurements.Add(new KeyValuePair <long, long>(stopwatch.ElapsedMilliseconds, totalBytesRead)); previousTime = stopwatch.ElapsedMilliseconds; } stopwatch.Stop(); SpeedtestResult speedtestResult = new SpeedtestResult { DownloadedBytes = totalBytesRead, ElapsedMiliseconds = stopwatch.ElapsedMilliseconds, MaxMBsPerSecond = measurements.GroupBy(m => m.Key / 1000).Max(s => GetSpeedInMBs(s, 1000)) }; Logger.Info($"Downloaded: {speedtestResult.DownloadedMBs:F2} MB, Time: {speedtestResult.ElapsedMiliseconds} ms, Speed: {speedtestResult.MaxMBsPerSecond:F1} MB/s ({speedtestResult.MaxMBsPerSecond * 8:F0} mbit)"); return(speedtestResult); } } finally { httpResponseMessage.Dispose(); } }