/// <summary> /// Initializes a new instance of the <see cref="WebRequester"/> class. /// </summary> /// <param name="createHandler"></param> /// <param name="options"></param> /// <param name="contentType">Type of the content.</param> public WebRequester(Func <string, HttpMessageHandler> createHandler, RequestOptions options, string contentType = "application/x-protobuf") { options.Validate(); _createHttpClient = () => { var httpClient = new HttpClient(createHandler(GetType().FullName), false) { BaseAddress = options.BaseUri }; if (options.Timeout > TimeSpan.Zero) { httpClient.Timeout = options.Timeout; } httpClient.DefaultRequestHeaders.Accept.TryParseAdd(contentType); if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpClient.DefaultRequestHeaders.TryAddWithoutValidation(kv.Key, kv.Value); } } return(httpClient); }; }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task <Response> IssueWebRequestAsync( string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( _credentials.ClusterUri.Scheme, _credentials.ClusterUri.Host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from using (Stream req = await httpWebRequest.GetRequestStreamAsync()) { await input.CopyToAsync(req); } } var response = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse; return(new Response() { WebResponse = response, RequestLatency = watch.Elapsed }); }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync( string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( _credentials.ClusterUri.Scheme, _credentials.ClusterUri.Host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from using (Stream req = await httpWebRequest.GetRequestStreamAsync()) { await input.CopyToAsync(req); } } var response = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse; return new Response() { WebResponse = response, RequestLatency = watch.Elapsed }; }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="query">The query.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync( string endpoint, string method, string query, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( _credentials.ClusterUri.Scheme, _credentials.ClusterUri.Host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } if (input != null) { // seek to the beginning, so we copy everything in this buffer input.Seek(0, SeekOrigin.Begin); using (Stream req = httpWebRequest.GetRequestStream()) { await input.CopyToAsync(req); } } var response = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse; return new Response() { WebResponse = response, RequestLatency = watch.Elapsed }; }
static async Task Main(string[] args) { var options = new RequestOptions(); bool showHelp = false; OptionSet os = new OptionSet() { { "h|?|help", "Displays the help", v => showHelp = true }, { "r|repository=", "Github repository to consider.", r => options.Repository = r }, { "t|token=", "Token to use to communicate with Github via OctoKit", t => options.Pat = t }, { "d|days=", "Show mentions in last given Days (Default 14)", d => options.Days = Int32.Parse(d) }, { "l|label=", "Show mentions on issues with given Label (Default ci-failure)", l => options.Label = l }, { "c|count=", "Show given top cross referenced items (Default 10)", c => options.Count = Int32.Parse(c) }, }; try { IList <string> unprocessed = os.Parse(args); } catch (Exception e) { Console.Error.WriteLine("Could not parse the command line arguments: {0}", e.Message); return; } if (showHelp) { ShowHelp(os); return; } options.Validate(); var crossRefCount = await Issues.Create(options).Find(); foreach (var issue in crossRefCount.OrderBy(x => x.ReferenceCount).Reverse().Take(options.Count)) { Console.WriteLine($"{issue.ID} {issue.Title} {issue.ReferenceCount}"); } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="query">The query to append.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task <Response> IssueWebRequestAsync( string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); var watch = Stopwatch.StartNew(); var builder = new UriBuilder( _credentials.ClusterUri.Scheme, _credentials.ClusterUri.Host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, builder.Uri); var httpWebRequest = WebRequest.CreateHttp(builder.Uri); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.Timeout = options.TimeoutMillis; // This has no influence for calls that are made Async httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { if (req != null) { req.Close(); } } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } var response = (HttpWebResponse)await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); return(new Response { WebResponse = response, RequestLatency = watch.Elapsed }); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync(string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); Trace.CorrelationManager.ActivityId = Guid.NewGuid(); var balancedEndpoint = _balancer.GetEndpoint(); // Grab the host. Use the alternative host if one is specified string host = (options.AlternativeHost != null) ? options.AlternativeHost : balancedEndpoint.Host; UriBuilder builder = new UriBuilder( balancedEndpoint.Scheme, host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } var target = builder.Uri; try { Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(target); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; // This has no influence for calls that are made Async httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { req?.Close(); } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } Debug.WriteLine("Waiting for response for request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); HttpWebResponse response = (HttpWebResponse)await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); Debug.WriteLine("Web request {0} to endpoint {1} successful!", Trace.CorrelationManager.ActivityId, target); return new Response() { WebResponse = response, RequestLatency = watch.Elapsed, PostRequestAction = (r) => { if (r.WebResponse.StatusCode == HttpStatusCode.OK || r.WebResponse.StatusCode == HttpStatusCode.Created || r.WebResponse.StatusCode == HttpStatusCode.NotModified) { _balancer.RecordSuccess(balancedEndpoint); } else { _balancer.RecordFailure(balancedEndpoint); } } }; } catch (TimeoutException) { httpWebRequest.Abort(); throw; } } catch(WebException we) { // 404 is valid response var resp = we.Response as HttpWebResponse; if(resp.StatusCode == HttpStatusCode.NotFound) { _balancer.RecordSuccess(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} successful!", Trace.CorrelationManager.ActivityId, target); } else { _balancer.RecordFailure(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} failed!", Trace.CorrelationManager.ActivityId, target); } throw we; } catch (Exception e) { _balancer.RecordFailure(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} failed!", Trace.CorrelationManager.ActivityId, target); throw e; } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task <Response> IssueWebRequestAsync( string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( "http", options.AlternativeHost, options.Port, options.AlternativeEndpoint); Debug.WriteLine("Issuing request to endpoint {0}", builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); //httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = null; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { if (req != null) { req.Close(); } } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } HttpWebResponse response = (HttpWebResponse)await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); return(new Response() { WebResponse = response, RequestLatency = watch.Elapsed }); } catch (Exception ex) { if (ex is WebException) { WebException we = (WebException)ex; var resp = we.Response as HttpWebResponse; return(new Response() { WebResponse = resp, RequestLatency = watch.Elapsed }); } else { httpWebRequest.Abort(); throw; } } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task <Response> IssueWebRequestAsync(string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); var watch = Stopwatch.StartNew(); Trace.CorrelationManager.ActivityId = Guid.NewGuid(); var balancedEndpoint = _balancer.GetEndpoint(); // Grab the host. Use the alternative host if one is specified var host = options.AlternativeHost != null ? options.AlternativeHost : balancedEndpoint.Host; var builder = new UriBuilder( balancedEndpoint.Scheme, host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } var target = builder.Uri; try { Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); var httpWebRequest = WebRequest.CreateHttp(target); //httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; //httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; // This has no influence for calls that are made Async httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { if (req != null) { req.Close(); } } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } Debug.WriteLine("Waiting for response for request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); var response = (HttpWebResponse)await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); Debug.WriteLine("Web request {0} to endpoint {1} successful!", Trace.CorrelationManager.ActivityId, target); return(new Response { WebResponse = response, RequestLatency = watch.Elapsed, PostRequestAction = r => { if (r.WebResponse.StatusCode == HttpStatusCode.OK || r.WebResponse.StatusCode == HttpStatusCode.Created || r.WebResponse.StatusCode == HttpStatusCode.NotModified) { _balancer.RecordSuccess(balancedEndpoint); } else { _balancer.RecordFailure(balancedEndpoint); } } }); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } } catch (WebException we) { // 404 is valid response var resp = we.Response as HttpWebResponse; if (resp.StatusCode == HttpStatusCode.NotFound) { _balancer.RecordSuccess(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} successful!", Trace.CorrelationManager.ActivityId, target); } else { _balancer.RecordFailure(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} failed!", Trace.CorrelationManager.ActivityId, target); } throw we; } catch (Exception e) { _balancer.RecordFailure(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} failed!", Trace.CorrelationManager.ActivityId, target); throw e; } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync( string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( "http", options.AlternativeHost, options.Port, options.AlternativeEndpoint); Debug.WriteLine("Issuing request to endpoint {0}", builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); //httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = null; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { if (req != null) { req.Close(); } } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } HttpWebResponse response = (HttpWebResponse)await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); return new Response() { WebResponse = response, RequestLatency = watch.Elapsed }; } catch (Exception ex) { if (ex is WebException) { WebException we = (WebException)ex; var resp = we.Response as HttpWebResponse; return new Response() { WebResponse = resp, RequestLatency = watch.Elapsed }; } else { httpWebRequest.Abort(); throw; } } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync(string endpoint, string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); Trace.CorrelationManager.ActivityId = Guid.NewGuid(); var balancedEndpoint = _balancer.GetEndpoint(); UriBuilder builder = new UriBuilder( balancedEndpoint.Scheme, balancedEndpoint.Host, options.Port, options.AlternativeEndpoint + endpoint); var target = builder.Uri; try { Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(target); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } if (input != null) { // seek to the beginning, so we copy everything in this buffer input.Seek(0, SeekOrigin.Begin); using (Stream req = httpWebRequest.GetRequestStream()) { await input.CopyToAsync(req); } } Debug.WriteLine("Waiting for response for request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, target); var response = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse; Debug.WriteLine("Web request {0} to endpoint {1} successful!", Trace.CorrelationManager.ActivityId, target); return new Response() { WebResponse = response, RequestLatency = watch.Elapsed, PostRequestAction = (r) => { if (r.WebResponse.StatusCode == HttpStatusCode.OK || r.WebResponse.StatusCode == HttpStatusCode.Created) { _balancer.RecordSuccess(balancedEndpoint); } else { _balancer.RecordFailure(balancedEndpoint); } } }; } catch (Exception e) { _balancer.RecordFailure(balancedEndpoint); Debug.WriteLine("Web request {0} to endpoint {1} failed!", Trace.CorrelationManager.ActivityId, target); throw e; } }
/// <summary> /// Issues the web request asynchronous. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="query">The query to append.</param> /// <param name="method">The method.</param> /// <param name="input">The input.</param> /// <param name="options">request options</param> /// <returns></returns> public async Task<Response> IssueWebRequestAsync( string endpoint, string query, string method, Stream input, RequestOptions options) { options.Validate(); Stopwatch watch = Stopwatch.StartNew(); UriBuilder builder = new UriBuilder( _credentials.ClusterUri.Scheme, _credentials.ClusterUri.Host, options.Port, options.AlternativeEndpoint + endpoint); if (query != null) { builder.Query = query; } Debug.WriteLine("Issuing request {0} to endpoint {1}", Trace.CorrelationManager.ActivityId, builder.Uri); HttpWebRequest httpWebRequest = WebRequest.CreateHttp(builder.Uri); httpWebRequest.ServicePoint.ReceiveBufferSize = options.ReceiveBufferSize; httpWebRequest.ServicePoint.UseNagleAlgorithm = options.UseNagle; httpWebRequest.Timeout = options.TimeoutMillis; // This has no influence for calls that are made Async httpWebRequest.KeepAlive = options.KeepAlive; httpWebRequest.Credentials = _credentialCache; httpWebRequest.PreAuthenticate = true; httpWebRequest.Method = method; httpWebRequest.Accept = _contentType; httpWebRequest.ContentType = _contentType; // This allows 304 (NotModified) requests to catch //https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect(v=vs.110).aspx httpWebRequest.AllowAutoRedirect = false; if (options.AdditionalHeaders != null) { foreach (var kv in options.AdditionalHeaders) { httpWebRequest.Headers.Add(kv.Key, kv.Value); } } long remainingTime = options.TimeoutMillis; if (input != null) { // expecting the caller to seek to the beginning or to the location where it needs to be copied from Stream req = null; try { req = await httpWebRequest.GetRequestStreamAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for RequestStream"); remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if(remainingTime <= 0) { remainingTime = 0; } await input.CopyToAsync(req).WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for CopyToAsync", CancellationToken.None); } catch (TimeoutException) { httpWebRequest.Abort(); throw; } finally { req?.Close(); } } try { remainingTime = options.TimeoutMillis - watch.ElapsedMilliseconds; if (remainingTime <= 0) { remainingTime = 0; } HttpWebResponse response = (HttpWebResponse) await httpWebRequest.GetResponseAsync().WithTimeout( TimeSpan.FromMilliseconds(remainingTime), "Waiting for GetResponseAsync"); return new Response() { WebResponse = response, RequestLatency = watch.Elapsed }; } catch (TimeoutException) { httpWebRequest.Abort(); throw; } }