protected virtual BpWebResponse internal_GET_or_POST(string url, byte[] postBody, string contentType, string[] headers, int earlyTerminationBytes) { BpWebResponse response = new BpWebResponse(); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Timeout = requestTimeout; webRequest.Proxy = null; //if (skipCertificateValidation) // webRequest.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; if (!string.IsNullOrEmpty(UserAgentString)) { webRequest.UserAgent = UserAgentString; } if (headers != null) { for (int i = 0; i + 1 < headers.Length; i += 2) { string key = headers[i]; string keyLower = key.ToLower(); string value = headers[i + 1]; if (keyLower == "user-agent") { webRequest.UserAgent = value; } else if (key == "STARTBYTE") { webRequest.AddRange(int.Parse(value)); } else { webRequest.Headers[key] = value; } } } if (BasicAuthCredentials != null) { webRequest.Credentials = BasicAuthCredentials; webRequest.PreAuthenticate = true; } try { if (postBody != null && postBody.Length > 1 && !string.IsNullOrWhiteSpace(contentType)) { webRequest.Method = "POST"; webRequest.ContentType = contentType; webRequest.ContentLength = postBody.Length; using (Stream reqStream = webRequest.GetRequestStream()) { reqStream.Write(postBody, 0, postBody.Length); } } using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) { using (MemoryStream ms = new MemoryStream()) { using (Stream responseStream = webResponse.GetResponseStream()) { foreach (string key in webResponse.Headers.AllKeys) { response.headers[key] = webResponse.Headers[key]; } response.ContentType = webResponse.ContentType; response.StatusCode = (int)webResponse.StatusCode; // Dump the response stream into the MemoryStream ms int bytesRead = 1; byte[] buffer = new byte[8000]; while (bytesRead > 0) { if (earlyTerminationBytes - ms.Length < buffer.Length) { buffer = new byte[earlyTerminationBytes - ms.Length]; } bytesRead = responseStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); } if (ms.Length >= earlyTerminationBytes) { break; } } // Dump the data into the byte array response.data = ms.ToArray(); } } } } catch (WebException ex) { if (ex.Response == null) { response.StatusCode = 0; } else { response.StatusCode = (int)((HttpWebResponse)ex.Response).StatusCode; } } return(response); }
protected virtual async Task <BpWebResponse> internal_send(HttpMethod method, string url, byte[] uploadBody, string contentType, string[] headers, int earlyTerminationBytes) { BpWebResponse response = new BpWebResponse(); HttpRequestMessage requestMessage = new HttpRequestMessage(method, url); if (headers != null) { for (int i = 0; i + 1 < headers.Length; i += 2) { string key = headers[i]; string value = headers[i + 1]; requestMessage.Headers.TryAddWithoutValidation(key, value); } } if (uploadBody != null && uploadBody.Length > 1 && !string.IsNullOrWhiteSpace(contentType)) { ByteArrayContent uploadBodyContent = new ByteArrayContent(uploadBody); uploadBodyContent.Headers.Add("Content-Type", contentType); //uploadBodyContent.Headers.Add("Content-Length", uploadBody.Length.ToString()); requestMessage.Content = uploadBodyContent; } try { HttpResponseMessage httpResponse = await client.SendAsync(requestMessage).ConfigureAwait(false); response.StatusCode = (int)httpResponse.StatusCode; foreach (var kvp in httpResponse.Headers) { response.headers[kvp.Key] = string.Join(",", kvp.Value); } foreach (var kvp in httpResponse.Content.Headers) { response.headers[kvp.Key] = string.Join(",", kvp.Value); } if (httpResponse.Content.Headers.ContentType != null) { response.ContentType = httpResponse.Content.Headers.ContentType.ToString(); } else if (response.headers.ContainsKey("Content-Type")) { response.ContentType = response.headers["Content-Type"]; } else { response.ContentType = ""; } if (earlyTerminationBytes == int.MaxValue) { response.data = await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false); } else { using (MemoryStream ms = new MemoryStream()) { using (Stream responseStream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false)) { // Dump the response stream into the MemoryStream ms int bytesRead = 1; byte[] buffer = new byte[8000]; while (bytesRead > 0) { if (earlyTerminationBytes - ms.Length < buffer.Length) { buffer = new byte[earlyTerminationBytes - ms.Length]; } bytesRead = responseStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); } if (ms.Length >= earlyTerminationBytes) { break; } } // Dump the data into the byte array response.data = ms.ToArray(); } } } } catch (Exception ex) { response.StatusCode = 0; response.ex = ex; if (ex.GetExceptionWhere(e2 => e2 is ThreadAbortException || e2.Message.Contains("The request was aborted: The request was canceled")) != null) { response.canceled = true; } } return(response); }
/// <summary> /// Sends the request and retrieves the response. /// </summary> /// <param name="method">The HTTP method to use for the request.</param> /// <param name="url">The URL to access.</param> /// <param name="uploadBody">The content to POST or PUT. Null if using GET.</param> /// <param name="contentType">The value of the content-type header to set. Null if using GET.</param> /// <param name="headers">Additional header keys and values to set in the request, provided as an array of strings ordered as [key, value, key, value] and so on. e.g.: { "User-Agent", "Mozilla", "Server", "MyServer" }</param> /// <param name="earlyTerminationBytes">If specified, the connection will be dropped as soon as this many bytes are read, and this much data will be returned. If the full response is shorter than this, then the full response will be returned.</param> /// <param name="fileDownloadPath">If specified, the response body will be streamed into this file and the response returned by this method will have a null data field. If the file already exists, it will be overwritten.</param> /// <returns></returns> protected virtual async Task <BpWebResponse> internal_send(HttpMethod method, string url, byte[] uploadBody, string contentType, string[] headers, int earlyTerminationBytes, string fileDownloadPath) { TimeSpan timeout = RequestTimeout; Stopwatch sw = Stopwatch.StartNew(); BpWebResponse response = new BpWebResponse(); HttpRequestMessage requestMessage = new HttpRequestMessage(method, url); if (headers != null) { for (int i = 0; i + 1 < headers.Length; i += 2) { string key = headers[i]; string value = headers[i + 1]; requestMessage.Headers.TryAddWithoutValidation(key, value); } } if (uploadBody != null && uploadBody.Length > 1 && !string.IsNullOrWhiteSpace(contentType)) { ByteArrayContent uploadBodyContent = new ByteArrayContent(uploadBody); uploadBodyContent.Headers.Add("Content-Type", contentType); //uploadBodyContent.Headers.Add("Content-Length", uploadBody.Length.ToString()); requestMessage.Content = uploadBodyContent; } try { HttpResponseMessage httpResponse = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); response.StatusCode = (int)httpResponse.StatusCode; foreach (var kvp in httpResponse.Headers) { response.headers[kvp.Key] = string.Join(",", kvp.Value); } foreach (var kvp in httpResponse.Content.Headers) { response.headers[kvp.Key] = string.Join(",", kvp.Value); } if (httpResponse.Content.Headers.ContentType != null) { response.ContentType = httpResponse.Content.Headers.ContentType.ToString(); } else if (response.headers.ContainsKey("Content-Type")) { response.ContentType = response.headers["Content-Type"]; } else { response.ContentType = ""; } if (earlyTerminationBytes == int.MaxValue || earlyTerminationBytes < 0) { if (string.IsNullOrEmpty(fileDownloadPath)) { response.data = await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false); } else { using (Stream stream = CreateStreamToSaveTo(fileDownloadPath)) await httpResponse.Content.CopyToAsync(stream).ConfigureAwait(false); } } else { using (Stream ms = CreateStreamToSaveTo(fileDownloadPath)) { using (Stream responseStream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false)) { // Dump the response stream into the MemoryStream ms int bytesRead = 1; byte[] buffer = new byte[32768]; while (bytesRead > 0) { if (earlyTerminationBytes - ms.Length < buffer.Length) { buffer = new byte[earlyTerminationBytes - ms.Length]; } bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); } if (ms.Length >= earlyTerminationBytes) { break; } } // Dump the data into the byte array if (ms is MemoryStream) { response.data = (ms as MemoryStream).ToArray(); } } } } } catch (Exception ex) { response.StatusCode = 0; response.ex = ex; Exception cancelEx = ex.GetExceptionWhere(e2 => e2 is ThreadAbortException || e2 is TaskCanceledException || e2.Message.Contains("The request was aborted: The request was canceled")); if (cancelEx != null) { if (cancelEx is TaskCanceledException) // This utility doesn't support cancellation, and request timeouts look like cancellation.. { response.ex = new Exception("The web request failed, likely having timed out (Execution Time: " + sw.Elapsed + ", Timeout: " + timeout + ")", cancelEx); } response.canceled = true; } } return(response); }