private HttpWebResponse GetOrCreateWebStream() { if (lastResponse != null) { return(lastResponse); } HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Uri); if (Progress > 0) { httpRequest.AddRange(Progress); } lastResponse = GetUnredirectedResponse(httpRequest); // The content disposition header will often contain the filename of the download // We can use this to update the output filename in the case of redirects var contentDispositionHeader = lastResponse.Headers.Get("Content-Disposition"); if (!string.IsNullOrEmpty(contentDispositionHeader)) { ContentDisposition contentDisposition = new ContentDisposition(contentDispositionHeader); ResponseFilename = contentDisposition.FileName; ReceivedResponseFilename?.Invoke(this, new ResponseFilenameEventArgs(ResponseFilename)); } return(lastResponse); }
private HttpWebResponse GetUnredirectedResponse(WebRequest req) { try { var res = req.GetResponse(); return((HttpWebResponse)res); } catch (WebException ex) { // We have to manually deal with redirects here because .NET Core does not // auto redirect https to http in the name of safety. While this is a noble // effort, and probably the correct to handle it, unfortunately some sites // do not do this and redirect down to http. So this will hopefully handle // that. var httpResp = ((HttpWebResponse)ex.Response); if ((int)httpResp.StatusCode >= 300 && (int)httpResp.StatusCode < 400) { var redirect = httpResp.GetResponseHeader("Location"); if (!string.IsNullOrEmpty(redirect)) { Log.WriteLine("Following redirect to: " + redirect); var newUrl = new Uri(redirect); var newFn = newUrl.Segments.Last(); ReceivedResponseFilename?.Invoke(this, new ResponseFilenameEventArgs(HttpUtility.UrlDecode(newFn))); HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(newUrl); if (Progress > 0) { newRequest.AddRange(Progress); } return(GetUnredirectedResponse(newRequest)); } } // Rethrow error if it's not a 300-type redirect throw ex; } }