/// <summary> /// Raises the <see cref="E:ProgressChanged" /> event. /// </summary> /// <param name="e">The <see cref="WebRequestProgressChangedEventArgs"/> instance containing the event data.</param> protected virtual void OnProgressChanged(WebRequestProgressChangedEventArgs e) { var handler = _progressChanged; handler?.Invoke(this, e); }
/// <summary> /// Processes the response. /// </summary> private void ProcessResponse() { try { // Skip the request if the request contains error if (!IsSuccessful) { Exception = new InvalidOperationException("Failed to get the response stream!"); bufferRead = null; return; } // Skip the rest of the method for HEAD request (which needs only response headers) if (Request.Method.Equals(KnownHttpVerb.Head.ToString(), StringComparison.OrdinalIgnoreCase)) { bufferRead = new byte[0]; return; } // Get response stream streamResponse = Response?.GetResponseStream(); if (streamResponse == null) { Exception = new InvalidOperationException("Failed to get the response stream!"); bufferRead = null; return; } var charset = Response?.Headers[HttpResponseHeader.ContentType] ?? "windows-1252"; var contentType = new ContentType(charset); Encoding = contentType.CharSet?.CharsetToEncoding(); const short numReadsBeforeProgUpdateDefault = 32; var numReadsCounter = numReadsBeforeProgUpdateDefault / 2; var bytesReadSoFar = 0L; var totalBytesToRead = TotalBytes; var lastUpdateTime = DateTime.Now; var lastUpdateDownloadedSize = 0L; using (var ms = new MemoryStream()) { int bytesRead; do { // Read stream content bytesRead = streamResponse.Read(bufferRead, 0, bufferRead.Length); bytesReadSoFar += bytesRead; if (numReadsCounter > numReadsBeforeProgUpdateDefault) { // Calculate request progress and report it var dateTimeNow = DateTime.Now; var timeDiff = (dateTimeNow - lastUpdateTime).TotalSeconds; var sizeDiff = bytesReadSoFar - lastUpdateDownloadedSize; var transferSpeed = Math.Round(sizeDiff / timeDiff / 1024f, 2); lastUpdateDownloadedSize = bytesReadSoFar; lastUpdateTime = dateTimeNow; // Reset reads counter numReadsCounter = 0; // Report the progress var args = new WebRequestProgressChangedEventArgs(bytesReadSoFar, totalBytesToRead, DateTime.Now - transferStart, transferSpeed, 99); OnProgressChanged(args); } else { numReadsCounter++; } ms.Write(bufferRead, 0, bytesRead); CheckIfCancelled(bytesReadSoFar, totalBytesToRead); } // go if some amount of bytes has been read and stream can go on reading while (bytesRead > 0 && streamResponse.CanRead); content = ms.ToArray(); } OnProgressCompleted(new WebRequestProgressCompletedEventArgs(bytesReadSoFar, totalBytesToRead, DateTime.Now - transferStart, transferStart, false)); } catch (Exception ex) { Exception = ex; bufferRead = null; content = null; throw; } finally { streamResponse?.Close(); } }