public void SendAsync_Redirect_FollowRedirectFalse() { const int tries = 12; var location = "https://google.com"; var redirectHandler = new RedirectMessageHandler(location); var configurableHanlder = new ConfigurableMessageHandler(redirectHandler) { NumTries = tries, FollowRedirect = false }; using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, location); request.Headers.IfModifiedSince = new DateTimeOffset(DateTime.Now); request.Headers.IfUnmodifiedSince = new DateTimeOffset(DateTime.Now); request.Headers.IfMatch.Add(new EntityTagHeaderValue("\"a\"")); request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"b\"")); HttpResponseMessage response = client.SendAsync(request).Result; // there should be only one request because follow redirect is false Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redirect)); Assert.That(response.Headers.Location, Is.EqualTo(new Uri(location + 1))); Assert.That(redirectHandler.Calls, Is.EqualTo(1)); } }
public void SendAsync_Redirect() { var location = "https://google.com"; var redirectHandler = new RedirectMessageHandler(location); var configurableHanlder = new ConfigurableMessageHandler(redirectHandler) { NumRedirects = 5 }; using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, location); request.Headers.IfModifiedSince = DateTimeOffset.UtcNow; request.Headers.IfUnmodifiedSince = DateTimeOffset.UtcNow; request.Headers.IfMatch.Add(new EntityTagHeaderValue("\"a\"")); request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"b\"")); HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redirect)); Assert.That(response.Headers.Location, Is.EqualTo( new Uri(location + (configurableHanlder.NumRedirects + 1)))); Assert.That(redirectHandler.Calls, Is.EqualTo(configurableHanlder.NumRedirects + 1)); } }
/// <summary> Test helper for testing unsuccessful response handlers. </summary> private void SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode code) { var handler = new UnsuccessfulResponseMessageHandler { ResponseStatusCode = code }; var configurableHanlder = new ConfigurableMessageHandler(handler); var unsuccessfulHandler = new UnsuccessfulResponseMessageHandler.ServiceUnavailableResponseHandler(); configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfulHandler); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-unsuccessful-handler"); HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(response.StatusCode, Is.EqualTo(code)); // if service unavailable, retry will occur because we plugged unsuccessful response handler which // handles service unavailable responses if (code == HttpStatusCode.ServiceUnavailable) { Assert.That(unsuccessfulHandler.Calls, Is.EqualTo(configurableHanlder.NumTries)); Assert.That(handler.Calls, Is.EqualTo(configurableHanlder.NumTries)); } else { // if status is OK, there isn't any call to unsuccessful response handler Assert.That(unsuccessfulHandler.Calls, Is.EqualTo(code != HttpStatusCode.OK ? 1 : 0)); Assert.That(handler.Calls, Is.EqualTo(1)); } } }
public void SendAsync_ThrowException_WithoutExceptionHandler() { var handler = new ExceptionMessageHandler { ThrowException = true }; var configurableHanlder = new ConfigurableMessageHandler(handler); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler"); try { HttpResponseMessage response = client.SendAsync(request).Result; Assert.Fail("SendAsync should throw an exception"); } catch (AggregateException ae) { Assert.That(ae.InnerException.Message, Is.EqualTo(ExceptionMessageHandler.ExceptionMessage)); } catch (Exception) { Assert.Fail("AggregateException was suppose to be thrown"); } Assert.That(handler.Calls, Is.EqualTo(1)); } }
public void TestGetWithUrlTooLongByUserSpecified() { uint maxUrlLength = 1000; var query = "q=" + new String('x', 900) + "&x=" + new String('y', 72); var uri = "http://www.example.com/"; var requestUri = uri + "?" + query; var request = new HttpRequestMessage(HttpMethod.Get, requestUri); var mockHandler = new MockMessageHandler(); var handler = new ConfigurableMessageHandler(mockHandler); handler.ExecuteInterceptors.Add(new MaxUrlLengthInterceptor(maxUrlLength)); using (var httpClient = new HttpClient(handler)) { httpClient.SendAsync(request); // Confirm the test URI is one character too long Assert.That(requestUri.Length, Is.EqualTo(maxUrlLength + 1)); // Confirm the request was modified correctly: Assert.That(request.Method, Is.EqualTo(HttpMethod.Post)); Assert.That(request.Headers.GetValues("X-HTTP-Method-Override").Single(), Is.EqualTo("GET")); Assert.That(request.Content.Headers.ContentType, Is.EqualTo(new MediaTypeHeaderValue("application/x-www-form-urlencoded"))); Assert.That(request.RequestUri, Is.EqualTo(new Uri(uri))); Assert.That(mockHandler.RequestContent, Is.EqualTo(query)); } }
private async Task RunUsingServiceAccount() { var requestUri = "path to server resource we want"; IAuthorizationCodeFlow authFLow = null; var userId = ""; TokenResponse token = null; var authUri = ""; ConfigurableMessageHandler messageHandler = new ConfigurableMessageHandler( new MyHandler() ); var cancellationToken = new CancellationToken(); cancellationToken.Register(() => { }); var credential = new UserCredential(authFLow, userId, token) { }; var accessToken = await credential.GetAccessTokenForRequestAsync(authUri, cancellationToken); // Create the service. var service = new Google.Apis.Datastore.v1beta3.DatastoreService(new BaseClientService.Initializer { ApplicationName = "Discovery Sample", ApiKey = "[YOUR_API_KEY_HERE]", }); var httpClient = new ConfigurableHttpClient(messageHandler); service.HttpClientInitializer.Initialize(httpClient); var res = await httpClient.GetAsync(requestUri); }
/// <summary>Subtest that back-off handler works as expected when exception is or isn't thrown.</summary> private void SubtestSendAsync_BackOffExceptionHandler(bool throwException, BackOffHandler.Initializer initializer, Exception exceptionToThrow = null) { var handler = new ExceptionMessageHandler { ThrowException = throwException }; if (exceptionToThrow != null) { handler.Exception = exceptionToThrow; } var configurableHanlder = new ConfigurableMessageHandler(handler); var boHandler = new MockBackOffHandler(initializer); configurableHanlder.AddExceptionHandler(boHandler); int boHandleCount = 0; // if an exception should be thrown and the handler can handle it then calculate the handle count by the // lg(MaxTimeSpan) if (throwException && initializer.HandleExceptionFunc(exceptionToThrow)) { boHandleCount = Math.Min((int)Math.Floor(Math.Log(boHandler.MaxTimeSpan.TotalSeconds, 2)) + 1, configurableHanlder.NumTries - 1); boHandleCount = boHandleCount >= 0 ? boHandleCount : 0; } using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler"); try { HttpResponseMessage response = client.SendAsync(request).Result; Assert.False(throwException); } catch (AggregateException ae) { Assert.True(throwException); // Don't compare exception messages because for TaskCanceledException the message // on Mono is different if there is a task associated with the exception. Assert.AreEqual(handler.Exception.GetType(), ae.InnerException.GetType()); } Assert.That(boHandler.Waits.Count, Is.EqualTo(boHandleCount)); // check the exponential behavior - wait 1, 2, 4, 8, ... seconds. if (throwException) { for (int i = 0; i < boHandler.Waits.Count; ++i) { Assert.That(boHandler.Waits[i].TotalSeconds, Is.EqualTo((int)Math.Pow(2, i))); } } Assert.That(handler.Calls, Is.EqualTo(boHandleCount + 1)); } }
private static Initializer GetInitializer(Func <HttpRequestMessage, HttpResponseMessage> handler) { var httpMessageHandler = new MockableMessageHandler(handler); var configurableHandler = new ConfigurableMessageHandler(httpMessageHandler); var clientFactory = new FakeHttpClientFactory(configurableHandler); return(new Initializer { HttpClientFactory = clientFactory }); }
public ConfigurableHttpClient CreateHttpClient(CreateHttpClientArgs args) { HttpClientHandler httpClientHandler = new HttpClientHandler() { UseProxy = true, Proxy = webProxy }; ConfigurableMessageHandler httpMessageHandler = new ConfigurableMessageHandler(httpClientHandler); return(new ConfigurableHttpClient(httpMessageHandler)); }
private async Task <IList <string> > LogTest(ConfigurableMessageHandler.LogEventType logEvents, bool errorResponse = false) { var clock = new MockClock { UtcNow = new DateTime(2017, 1, 2, 3, 4, 5, DateTimeKind.Utc) }; var logger = new MemoryLogger(LogLevel.All, clock: clock); HttpMessageHandler handler; if (errorResponse) { handler = new MockMessageHandler { Response = new HttpResponseMessage { StatusCode = HttpStatusCode.ServiceUnavailable } }; } else { handler = new MockMessageHandler { Response = new HttpResponseMessage { Headers = { { "header1", "One" }, { "header2", "Two" } }, Content = new ByteArrayContent(new byte[] { 65, 66, 67, 0, 1, 255, 68, 69 }) // ABC...DE } }; } var configurableHandler = new ConfigurableMessageHandler(handler) { LogEvents = logEvents, InstanceLogger = logger }; using (var client = new HttpClient(configurableHandler)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-host/") { Headers = { Host = "test-host", Referrer = new Uri("https://referrer/") }, Content = new ByteArrayContent(new byte[] { 88, 89, 90, 0, 1, 255, 68, 69 }) // XYZ...DE }; await client.SendAsync(request); } return(logger.LogEntries); }
public void SendAsync_AbnormalResponse_WithoutUnsuccessfulReponseHandler() { var handler = new UnsuccessfulResponseMessageHandler { ResponseStatusCode = HttpStatusCode.ServiceUnavailable }; var configurableHanlder = new ConfigurableMessageHandler(handler); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-unsuccessful-handler"); HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.ServiceUnavailable)); Assert.That(handler.Calls, Is.EqualTo(1)); } }
public ConfigurableHttpClient CreateHttpClient(CreateHttpClientArgs args) { var handler = CreateHandler(args); var configurableHandler = new ConfigurableMessageHandler(handler) { ApplicationName = args.ApplicationName }; var client = new ConfigurableHttpClient(configurableHandler); client.DefaultRequestHeaders.Referrer = new Uri("https://youtubeuploader.daram.me"); foreach (var initializer in args.Initializers) { initializer.Initialize(client); } return(client); }
/// <summary> /// Helper for regression tests that URLs less than or equal to 2048 characters, or requests that are not GET, /// are not modified. If you are testing with GET, the length should be less than 2048. /// </summary> private void SubtestGetWithUrlOkayLengthByDefault(uint length, HttpMethod method) { var requestUri = "http://www.example.com/?q=" + new String('x', (int)length - 26); var request = new HttpRequestMessage(method, requestUri); var mockHandler = new MockMessageHandler(); var handler = new ConfigurableMessageHandler(mockHandler); handler.ExecuteInterceptors.Add(new MaxUrlLengthInterceptor(DefaultMaxUrlLength)); using (var httpClient = new HttpClient(handler)) { httpClient.SendAsync(request); Assert.That(request.RequestUri.ToString().Length, Is.EqualTo(length)); Assert.That(request.Method, Is.EqualTo(method)); Assert.That(request.Headers.Contains("X-HTTP-Method-Override"), Is.False); Assert.That(request.Content, Is.Null); Assert.That(request.RequestUri, Is.EqualTo(new Uri(requestUri))); } }
/// <summary> Subtest for exception handler which tests that exception handler is invoked. </summary> private void SubtestSendAsyncExceptionHandler(bool throwException, bool handle) { var handler = new ExceptionMessageHandler { ThrowException = throwException }; var configurableHanlder = new ConfigurableMessageHandler(handler); var exceptionHandler = new ExceptionMessageHandler.ExceptionHandler { Handle = handle }; configurableHanlder.ExceptionHandlers.Add(exceptionHandler); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler"); try { HttpResponseMessage response = client.SendAsync(request).Result; if (throwException) { Assert.Fail("SendAsync should throw an exception"); } } catch (AggregateException ae) { Assert.That(ae.InnerException.Message, Is.EqualTo(ExceptionMessageHandler.ExceptionMessage)); } // if exception is thrown, check if it's handles. if so, there should be num tries calls, otherwise // only 1 if (throwException) { Assert.That(exceptionHandler.Calls, Is.EqualTo(handle ? configurableHanlder.NumTries : 1)); } // exception wasn't supposed to be thrown, so no call to exception handler should be made else { Assert.That(exceptionHandler.Calls, Is.EqualTo(0)); } Assert.That(handler.Calls, Is.EqualTo(throwException & handle ? configurableHanlder.NumTries : 1)); } }
public void TestGetPathQueryWithUrlOkayLengthByDefault() { uint maxUrlLength = 1000; var query = "q=" + new String('x', 1000); var uri = "http://www.googleapis.com/language/translate/v2"; var requestUri = uri + "?" + query; var request = new HttpRequestMessage(HttpMethod.Get, requestUri); var mockHandler = new MockMessageHandler(); var handler = new ConfigurableMessageHandler(mockHandler); handler.AddExecuteInterceptor(new MaxUrlLengthInterceptor(maxUrlLength)); using (var httpClient = new HttpClient(handler)) { httpClient.SendAsync(request); // Confirm the request was modified correctly, and the uri was set correctly. Assert.That(request.RequestUri, Is.EqualTo(new Uri(uri))); Assert.That(mockHandler.RequestContent, Is.EqualTo(query)); } }
/// <summary>Tests that retry works with different kind of contents (String, Stream and ByteArray).</summary> private void SubtestSendAsyncRetryContent(ContentType type) { var content = "test-content"; var contentHandler = new ContentMessageHandler(); var configurableHanlder = new ConfigurableMessageHandler(contentHandler) { NumTries = 10 }; configurableHanlder.AddUnsuccessfulResponseHandler(new TrueUnsuccessfulResponseHandler()); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Put, "https://test-unsuccessful-handler"); // set the right content switch (type) { case ContentType.String: request.Content = new StringContent(content); break; case ContentType.Stream: { var stream = new MemoryStream(); var buffer = Encoding.UTF8.GetBytes(content); stream.Write(buffer, 0, buffer.Length); stream.Position = 0; request.Content = new StreamContent(stream); } break; case ContentType.ByteArray: request.Content = new ByteArrayContent(Encoding.UTF8.GetBytes(content)); break; } HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); Assert.That(contentHandler.Calls, Is.EqualTo(ContentMessageHandler.NumFails)); Assert.That(contentHandler.ReadContent, Is.EqualTo(content)); } }
public void NumTries_Setter() { var configurableHanlder = new ConfigurableMessageHandler(new HttpClientHandler()); // valid values configurableHanlder.NumTries = 5; configurableHanlder.NumTries = 1; configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowedNumTries; // test invalid values try { configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowedNumTries + 1; Assert.Fail(); } catch (ArgumentOutOfRangeException ex) { Assert.True(ex.Message.Contains("Parameter name: NumRetries")); } try { configurableHanlder.NumTries = 0; Assert.Fail(); } catch (ArgumentOutOfRangeException ex) { Assert.True(ex.Message.Contains("Parameter name: NumRetries")); } try { configurableHanlder.NumTries = -2; Assert.Fail(); } catch (ArgumentOutOfRangeException ex) { Assert.True(ex.Message.Contains("Parameter name: NumRetries")); } }
/// <summary> /// Tests the retry mechanism. In case the abnormal response is handled, there should be retries, but otherwise /// there should not be any retry. /// </summary> /// <param name="numTries"></param> /// <param name="handle"></param> private void SubtestSendAsyncNumTries(int numTries, bool handle = true) { var handler = new UnsuccessfulResponseMessageHandler { ResponseStatusCode = HttpStatusCode.ServiceUnavailable }; var configurableHanlder = new ConfigurableMessageHandler(handler) { NumTries = numTries }; if (handle) { var unsuccessfulHandler = new UnsuccessfulResponseMessageHandler.ServiceUnavailableResponseHandler(); configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfulHandler); } using (var client = new HttpClient(configurableHanlder)) { client.GetAsync("http://num-retres"); Assert.That(handler.Calls, Is.EqualTo(handle ? numTries : 1)); } }
/// <summary> Tests that execute interceptor is called. </summary> private void SubtestSendAsyncExecuteInterceptor(HttpStatusCode code) { var handler = new InterceptorMessageHandler(); handler.InjectedResponseMessage = new HttpResponseMessage() { StatusCode = code }; var configurableHanlder = new ConfigurableMessageHandler(handler); var interceptor = new InterceptorMessageHandler.Interceptor(); configurableHanlder.ExecuteInterceptors.Add(interceptor); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-execute-interceptor"); HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(interceptor.Calls, Is.EqualTo(1)); Assert.That(handler.Calls, Is.EqualTo(1)); } }
public void SendAsync_ExecuteInterceptor_AbnormalResponse_UnsuccessfulResponseHandler() { var handler = new InterceptorMessageHandler(); handler.InjectedResponseMessage = new HttpResponseMessage() { StatusCode = HttpStatusCode.ServiceUnavailable }; var configurableHanlder = new ConfigurableMessageHandler(handler); var interceptor = new InterceptorMessageHandler.Interceptor(); configurableHanlder.ExecuteInterceptors.Add(interceptor); configurableHanlder.UnsuccessfulResponseHandlers.Add(new TrueUnsuccessfulResponseHandler()); using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-execute-interceptor"); HttpResponseMessage response = client.SendAsync(request).Result; Assert.That(interceptor.Calls, Is.EqualTo(configurableHanlder.NumTries)); Assert.That(handler.Calls, Is.EqualTo(configurableHanlder.NumTries)); } }
public void SendAsync_UserAgent() { var apiVersion = string.Format("google-api-dotnet-client/{0} (gzip)", Utilities.GetLibraryVersion()); const string applicationName = "NO NAME"; var handler = new MockMessageHandler(); var configurableHanlder = new ConfigurableMessageHandler(handler); using (var client = new HttpClient(configurableHanlder)) { // without application name var request = new HttpRequestMessage(HttpMethod.Get, "https://test-user-agent"); HttpResponseMessage response = client.SendAsync(request).Result; var userAgent = string.Join(" ", request.Headers.GetValues("User-Agent").ToArray()); Assert.That(userAgent, Is.EqualTo(apiVersion)); // with application name configurableHanlder.ApplicationName = applicationName; request = new HttpRequestMessage(HttpMethod.Get, "https://test-user-agent"); response = client.SendAsync(request).Result; userAgent = string.Join(" ", request.Headers.GetValues("User-Agent").ToArray()); Assert.That(userAgent, Is.EqualTo(applicationName + " " + apiVersion)); } }
/// <summary> /// Subtest that back-off handler works as expected when a successful or abnormal response is returned. /// For testing the back-off handler in case of a canceled request, set the <code>cancelRequestNum</code> /// parameter to the index of the request you want to cancel. /// </summary> private void SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode statusCode, BackOffHandler.Initializer initializer, int cancelRequestNum = 0) { var handler = new UnsuccessfulResponseMessageHandler { ResponseStatusCode = statusCode }; CancellationToken cancellationToken = CancellationToken.None; bool cancel = cancelRequestNum > 0; if (cancel) { CancellationTokenSource tcs = new CancellationTokenSource(); handler.CancellationTokenSource = tcs; handler.CancelRequestNum = cancelRequestNum; cancellationToken = tcs.Token; } var configurableHanlder = new ConfigurableMessageHandler(handler); var boHandler = new MockBackOffHandler(initializer); configurableHanlder.UnsuccessfulResponseHandlers.Add(boHandler); int boHandleCount = 0; if (initializer.HandleUnsuccessfulResponseFunc != null && initializer.HandleUnsuccessfulResponseFunc(new HttpResponseMessage { StatusCode = statusCode })) { boHandleCount = Math.Min((int)Math.Floor(Math.Log(boHandler.MaxTimeSpan.TotalSeconds, 2)) + 1, configurableHanlder.NumTries - 1); boHandleCount = boHandleCount >= 0 ? boHandleCount : 0; if (cancel) { boHandleCount = Math.Min(boHandleCount, cancelRequestNum); } } using (var client = new HttpClient(configurableHanlder)) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler"); try { HttpResponseMessage response = client.SendAsync(request, cancellationToken).Result; Assert.False(cancel); } catch (AggregateException ae) { // a canceled request should throw an exception Assert.IsInstanceOf <TaskCanceledException>(ae.InnerException); Assert.True(cancel); } Assert.That(boHandler.Waits.Count, Is.EqualTo(boHandleCount)); // check the exponential behavior - wait 1, 2, 4, 8, ... seconds. for (int i = 0; i < boHandler.Waits.Count; ++i) { Assert.That(boHandler.Waits[i].TotalSeconds, Is.EqualTo((int)Math.Pow(2, i))); } // if the request was canceled the number of calls to the message handler is equal to the number of // calls to back-off handler Assert.That(handler.Calls, Is.EqualTo(boHandleCount + (cancel ? 0 : 1))); } }
/// <summary> /// Constructor to use when you want to keep the REST support library HTTP handling /// code (for error handling etc), creating a ConfigurableMessageHandler that delegates /// to <paramref name="handler"/>. /// </summary> public FakeHttpClientFactory(HttpMessageHandler handler) { _handler = new ConfigurableMessageHandler(handler); }
public FakeHttpClientFactory(ConfigurableMessageHandler handler) { _handler = handler; }