public async Task Test_SafeNext_WrapsPipelineException() { var callMock = new Mock <IUntypedCall>(); callMock.SetupGet(x => x.Jsonrpc) .Returns(JsonRpcConstants.Version); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken(false)); var nextMock = new Mock <RequestDelegate>(); nextMock.Setup(x => x(It.IsAny <HttpContext>())) .Throws <DivideByZeroException>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, nextMock.Object); requestHandlerMock.Setup(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); var result = await requestHandlerMock.Object.SafeNext(callMock.Object, handlingContext, false); result.Should().BeOfType <JsonServerResponseWrapper>(); errorFactoryMock.Verify(x => x.Exception(It.IsAny <DivideByZeroException>())); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())); requestHandlerMock.Verify(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); }
public async Task Test_Write_ChecksMemoryStream() { var ms = new MemoryStream(); var resposneMock = new Mock <HttpResponse>(); resposneMock.SetupGet(x => x.Body) .Returns(ms); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(resposneMock.Object); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken()); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = true }; var sourceResponse = Mock.Of <Stream>(); var sourceMock = new Mock <HttpResponse>(); sourceMock.SetupGet(x => x.StatusCode) .Returns(200); sourceMock.SetupGet(x => x.Body) .Returns(sourceResponse); var wrapper = new RawServerResponseWrapper(sourceMock.Object); Func <Task> action = async() => await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); await action.Should().ThrowAsync <JsonRpcInternalException>(); }
public async Task Test_Write_CopiesHeaders() { var responseHeaders = new HeaderDictionary() { { "a", "b" } }; var responseMock = new Mock <HttpResponse>(); responseMock.SetupGet(x => x.Headers) .Returns(responseHeaders); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(responseMock.Object); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = false }; var notification = new UntypedNotification(); var value = new JObject(); var headers = new HeaderDictionary { { "header", "value" } }; var wrapper = new JsonServerResponseWrapper(value, notification, headers); await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); responseMock.VerifyGet(x => x.Headers); responseHeaders.Should().HaveCount(2); responseHeaders.Should().ContainKey("header"); }
public async Task Test_Write_WritesBody() { var ms = new MemoryStream(); var resposneMock = new Mock <HttpResponse>(); resposneMock.SetupGet(x => x.Body) .Returns(ms); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(resposneMock.Object); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken()); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = true }; var sourceResponse = new MemoryStream(new byte[1]); var sourceMock = new Mock <HttpResponse>(); sourceMock.SetupGet(x => x.StatusCode) .Returns(200); sourceMock.SetupGet(x => x.Body) .Returns(sourceResponse); var wrapper = new RawServerResponseWrapper(sourceMock.Object); await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); ms.Length.Should().BePositive(); }
public async Task Test_SafeNext_ReadsResponse() { var callMock = new Mock <IUntypedCall>(); callMock.SetupGet(x => x.Jsonrpc) .Returns(JsonRpcConstants.Version); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken(false)); var nextMock = new Mock <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, nextMock.Object); responseReaderMock.Setup(x => x.GetResponse(It.IsAny <HttpContext>(), It.IsAny <IUntypedCall>(), It.IsAny <bool>(), It.IsAny <CancellationToken>())) .ReturnsAsync(Mock.Of <IServerResponseWrapper>()); requestHandlerMock.Setup(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); var result = await requestHandlerMock.Object.SafeNext(callMock.Object, handlingContext, false); nextMock.Verify(x => x(It.IsAny <HttpContext>())); result.Should().BeAssignableTo <IServerResponseWrapper>(); responseReaderMock.Verify(x => x.GetResponse(It.IsAny <HttpContext>(), It.IsAny <IUntypedCall>(), It.IsAny <bool>(), It.IsAny <CancellationToken>())); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())); requestHandlerMock.Verify(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); }
public async Task Test_Write_ChecksCancellationToken() { var ms = new MemoryStream(); var responseMock = new Mock <HttpResponse>(); responseMock.SetupGet(x => x.Body) .Returns(ms); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(responseMock.Object); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken(true)); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = true }; var notification = new UntypedNotification(); var value = new JObject(); var wrapper = new JsonServerResponseWrapper(value, notification, null); Func <Task> action = async() => await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); await action.Should().ThrowAsync <TaskCanceledException>(); }
protected internal virtual async Task HandleException(HandlingContext context, Exception e) { context.WriteResponse = true; log.LogTrace($"{nameof(HandleException)}: set writeResponse [{context.WriteResponse}]"); var response = errorFactory.ConvertExceptionToResponse(e, headerJsonRpcSerializer); var wrapper = GetResponseWrapper(response); await wrapper.Write(context, headerJsonRpcSerializer); }
public async Task Test_HandleBatchSequential_ReturnsEmptyOnEmptyBatch() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var result = await requestHandlerMock.Object.HandleBatchSequential(batch, handlingContext); result.Should().BeEmpty(); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatch_ThrowsOnEmpty() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); Func <Task> action = async() => await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); await action.Should().ThrowAsync <JsonRpcInternalException>(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); }
public async Task Test_HandleRequestWrapper_HandlesSingle() { var request = Mock.Of <SingleRequestWrapper>(); var expected = Mock.Of <IServerResponseWrapper>(); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleSingle(It.IsAny <SingleRequestWrapper>(), It.IsAny <HandlingContext>())) .ReturnsAsync(expected); var result = await requestHandlerMock.Object.HandleRequestWrapper(request, handlingContext); result.Should().Be(expected); requestHandlerMock.Verify(x => x.HandleRequestWrapper(It.IsAny <IRequestWrapper>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleSingle(It.IsAny <SingleRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleRequestWrapper_HandlesBad() { var request = Mock.Of <BadRequestWrapper>(); var expected = new JsonServerResponseWrapper(JValue.CreateString("test"), Mock.Of <IUntypedCall>(), Mock.Of <IHeaderDictionary>()); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleBad(It.IsAny <BadRequestWrapper>(), It.IsAny <HandlingContext>())) .Returns(expected); var result = await requestHandlerMock.Object.HandleRequestWrapper(request, handlingContext); result.Should().Be(expected); requestHandlerMock.Verify(x => x.HandleRequestWrapper(It.IsAny <IRequestWrapper>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleBad(It.IsAny <BadRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleException_WritesFlagAndResponse() { var responseMock = new Mock <IServerResponseWrapper>(); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var exception = new DivideByZeroException(); requestHandlerMock.Setup(x => x.GetResponseWrapper(It.IsAny <JToken>())) .Returns(responseMock.Object); await requestHandlerMock.Object.HandleException(handlingContext, exception); handlingContext.WriteResponse.Should().BeTrue(); responseMock.Verify(x => x.Write(It.IsAny <HandlingContext>(), It.IsAny <HeaderJsonRpcSerializer>())); errorFactoryMock.Verify(x => x.Exception(It.IsAny <DivideByZeroException>())); requestHandlerMock.Verify(x => x.HandleException(It.IsAny <HandlingContext>(), It.IsAny <Exception>())); }
public async Task Test_SafeNext_ChecksCancellation() { var call = Mock.Of <IUntypedCall>(); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken(true)); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next); var result = await requestHandlerMock.Object.SafeNext(call, handlingContext, false); result.Should().BeOfType <JsonServerResponseWrapper>(); errorFactoryMock.Verify(x => x.Exception(It.IsAny <OperationCanceledException>())); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())); }
public async Task Test_HandleRequestWrapper_HandlesNull() { var responseMock = new Mock <IServerResponseWrapper>(); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.GetResponseWrapper(It.IsAny <JToken>())) .Returns(responseMock.Object); var result = await requestHandlerMock.Object.HandleRequestWrapper(null, handlingContext); result.Should().Be(responseMock.Object); handlingContext.WriteResponse.Should().BeTrue(); errorFactoryMock.Verify(x => x.Exception(It.IsAny <ArgumentOutOfRangeException>())); requestHandlerMock.Verify(x => x.GetResponseWrapper(It.IsAny <JToken>())); requestHandlerMock.Verify(x => x.HandleRequestWrapper(It.IsAny <IRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatch_ThrowsOnUnknown() { var request = new UntypedRequest(); var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { request } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); Func <Task> action = async() => await requestHandlerMock.Object.HandleBatch(batch, (BatchHandling)(-1), handlingContext); await action.Should().ThrowAsync <ArgumentOutOfRangeException>(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), It.IsAny <BatchHandling>(), It.IsAny <HandlingContext>())); }
public async Task Test_GetResponseSafeInBatch_WrapsUnknown() { var callMock = new Mock <IUntypedCall>(); callMock.SetupGet(x => x.Jsonrpc) .Returns(JsonRpcConstants.Version); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), false)) .ReturnsAsync(Mock.Of <IServerResponseWrapper>()); await requestHandlerMock.Object.GetResponseSafeInBatch(callMock.Object, handlingContext); errorFactoryMock.Verify(x => x.Exception(It.IsAny <ArgumentOutOfRangeException>())); requestHandlerMock.Verify(x => x.GetResponseSafeInBatch(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), false)); }
public void Test_HandleBad_WritesFlagAndWrapsError() { var bad = new BadRequestWrapper { Exception = new DivideByZeroException() }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.GetError(It.IsAny <DivideByZeroException>())) .Returns(new Error <object>()); var result = requestHandlerMock.Object.HandleBad(bad, handlingContext); handlingContext.WriteResponse.Should().BeTrue(); result.Should().NotBeNull(); requestHandlerMock.Verify(x => x.GetError(It.IsAny <DivideByZeroException>())); requestHandlerMock.Verify(x => x.HandleBad(It.IsAny <BadRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_GetResponseSafeInBatch_ReturnsValue() { var callMock = new Mock <IUntypedCall>(); callMock.SetupGet(x => x.Jsonrpc) .Returns(JsonRpcConstants.Version); var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var jToken = JValue.CreateString("test"); requestHandlerMock.Setup(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), false)) .ReturnsAsync(new JsonServerResponseWrapper(jToken, callMock.Object, Mock.Of <IHeaderDictionary>())); var result = await requestHandlerMock.Object.GetResponseSafeInBatch(callMock.Object, handlingContext); Assert.AreEqual(jToken, result); requestHandlerMock.Verify(x => x.GetResponseSafeInBatch(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), false)); }
public virtual async Task HandleRequest(HttpContext httpContext, IRequestWrapper requestWrapper, Encoding requestEncoding, RequestDelegate next) { var context = new HandlingContext(httpContext, requestEncoding, next); try { log.LogTrace($"RequestWrapper is {requestWrapper?.GetType().Name}, encoding is {requestEncoding.EncodingName}"); var responseWrapper = await HandleRequestWrapper(requestWrapper, context); await responseWrapper.Write(context, headerJsonRpcSerializer); } catch (Exception e) { // paranoid safeguard against unexpected errors log.LogWarning(e, $"{nameof(HandleRequest)} failed, write error response"); await HandleException(context, e); } }
public async Task Test_HandleSingle_NoFlagWhenNotificationAndCallsNext() { var single = new SingleRequestWrapper { Call = new UntypedNotification() { Jsonrpc = JsonRpcConstants.Version } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())) .ReturnsAsync(Mock.Of <IServerResponseWrapper>()); await requestHandlerMock.Object.HandleSingle(single, handlingContext); handlingContext.WriteResponse.Should().BeFalse(); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())); requestHandlerMock.Verify(x => x.HandleSingle(It.IsAny <SingleRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatch_WritesFlagWhenHaveRequests() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { new UntypedRequest() } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())) .ReturnsAsync(new JArray()); await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); handlingContext.WriteResponse.Should().BeTrue(); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }
public async Task Test_HandleBatchSequential_ReturnsEmptyOnNotification() { var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { new UntypedNotification() } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); var jValue = JValue.CreateString("test"); requestHandlerMock.Setup(x => x.GetResponseSafeInBatch(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>())) .ReturnsAsync(jValue); var result = await requestHandlerMock.Object.HandleBatchSequential(batch, handlingContext); result.Should().BeEmpty(); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.GetResponseSafeInBatch(It.IsAny <UntypedNotification>(), It.IsAny <HandlingContext>())); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var ctx = new HandlingContext { Request = request, HandleAsync = base.SendAsync, ResponsSource = new TaskCompletionSource <HttpResponseMessage>(cancellationToken), CancellationToken = cancellationToken }; try { await _dispather.AcceptThenDispatchAsync(ctx); } catch (Exception ex) { _logger.LogError(ex, ex.Message); ctx.ResponsSource.SetException(ex); } return(await ctx.ResponsSource.Task); }
public async Task Test_Write_SetsResponseProperties() { var responseMock = new Mock <HttpResponse>(); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(responseMock.Object); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = false }; var notification = new UntypedNotification(); var value = new JObject(); var wrapper = new JsonServerResponseWrapper(value, notification, null); await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); responseMock.VerifySet(x => x.StatusCode = 200); responseMock.VerifySet(x => x.ContentLength = null); responseMock.VerifySet(x => x.ContentType = It.IsAny <string>()); }
public async Task Test_SafeNext_WrapsErrorResponseException() { var callMock = new Mock <IUntypedCall>(); callMock.SetupGet(x => x.Jsonrpc) .Returns(JsonRpcConstants.Version); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken(false)); var nextMock = new Mock <RequestDelegate>(); var errorData = new object(); var exception = new JsonRpcErrorResponseException(new Error <object> { Code = 42, Data = errorData, Message = "test" }); nextMock.Setup(x => x(It.IsAny <HttpContext>())) .Throws(exception); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, nextMock.Object); requestHandlerMock.Setup(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); var result = await requestHandlerMock.Object.SafeNext(callMock.Object, handlingContext, false); result.Should().BeOfType <JsonServerResponseWrapper>(); var response = (result as JsonServerResponseWrapper).Value; response["error"].Should().NotBeNull(); response["error"]["code"].Value <int>().Should().Be(42); response["error"]["message"].Value <string>().Should().Be("test"); response["error"]["data"].Should().NotBeNull(); errorFactoryMock.Verify(x => x.Exception(It.IsAny <Exception>()), Times.Never); requestHandlerMock.Verify(x => x.SafeNext(It.IsAny <IUntypedCall>(), It.IsAny <HandlingContext>(), It.IsAny <bool>())); requestHandlerMock.Verify(x => x.PropagateItemsInternal(It.IsAny <HttpContext>(), It.IsAny <HttpContext>(), It.IsAny <object>())); }
public async Task Test_Write_SetsResponseErrorCodeOnError() { var items = new Dictionary <object, object>(); var ms = new MemoryStream(); var responseMock = new Mock <HttpResponse>(); responseMock.SetupGet(x => x.Body) .Returns(ms); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(responseMock.Object); httpContextMock.SetupGet(x => x.RequestAborted) .Returns(new CancellationToken()); httpContextMock.SetupGet(x => x.Items) .Returns(items); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = true }; var notification = new UntypedNotification(); var value = new JObject() { { "error", new JObject() { { "code", new JValue(1) } } } }; var wrapper = new JsonServerResponseWrapper(value, notification, null); await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); var result = httpContextMock.Object.Items[JsonRpcConstants.ResponseErrorCodeItemKey] as string; result.Should().Be("1"); }
public async Task Test_Write_SetsResponseProperties() { var resposneMock = new Mock <HttpResponse>(); var httpContextMock = new Mock <HttpContext>(); httpContextMock.SetupGet(x => x.Response) .Returns(resposneMock.Object); var next = Mock.Of <RequestDelegate>(); var handlingContext = new HandlingContext(httpContextMock.Object, Encoding.UTF8, next) { WriteResponse = false }; var sourceMock = new Mock <HttpResponse>(); sourceMock.SetupGet(x => x.StatusCode) .Returns(201); var wrapper = new RawServerResponseWrapper(sourceMock.Object); await wrapper.Write(handlingContext, new HeaderJsonRpcSerializer()); resposneMock.VerifySet(x => x.StatusCode = 201); resposneMock.VerifySet(x => x.ContentLength = null); }
public async Task Test_HandleBatch_CallsSequential() { var request = new UntypedRequest(); var value = new JArray(); var batch = new BatchRequestWrapper { Batch = new List <IUntypedCall>() { request } }; var handlingContext = new HandlingContext(Mock.Of <HttpContext>(), Mock.Of <Encoding>(), Mock.Of <RequestDelegate>()); requestHandlerMock.Setup(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())) .ReturnsAsync(value); var result = await requestHandlerMock.Object.HandleBatch(batch, BatchHandling.Sequential, handlingContext); result.Should().BeOfType <JsonServerResponseWrapper>(); Assert.AreEqual(value, (result as JsonServerResponseWrapper).Value); requestHandlerMock.Verify(x => x.HandleBatch(It.IsAny <BatchRequestWrapper>(), BatchHandling.Sequential, It.IsAny <HandlingContext>())); requestHandlerMock.Verify(x => x.HandleBatchSequential(It.IsAny <BatchRequestWrapper>(), It.IsAny <HandlingContext>())); }
/// <returns>是否尝试了“下一个”上游服务端</returns> private async Task <bool> NextPeerAsync( HandlingContext handlingContext, UpstreamPeer peer, HttpResponseMessage response, Uri originUri, bool isTimeout = false) { if (peer == null) { return(false); } if (handlingContext.IsSingle) { return(false); } handlingContext.Start = handlingContext.Start ?? DateTime.Now; if (NextWhen.Never == (peer.NextWhen & NextWhen.Never)) { return(false); } var request = handlingContext.Request; if (request.Method != HttpMethod.Get && NextWhen.GetOnly == (peer.NextWhen & NextWhen.GetOnly)) { return(false); } handlingContext.Tries = handlingContext.Tries ?? (peer.NextTries == 0 ? int.MaxValue : peer.NextTries); if (handlingContext.Tries == 0) { return(false); } var when = NextWhen.None; if (isTimeout) { when |= NextWhen.Timeout; } else if (response == null) { when |= NextWhen.Error; } else { if (response.IsSuccessStatusCode) { return(false); } switch (response.StatusCode) { case HttpStatusCode.InternalServerError: when |= NextWhen.Http500; break; case HttpStatusCode.BadGateway: when |= NextWhen.Http502; break; case HttpStatusCode.ServiceUnavailable: when |= NextWhen.Http503; break; case HttpStatusCode.RequestTimeout: case HttpStatusCode.GatewayTimeout: when |= NextWhen.Timeout; break; case HttpStatusCode.Forbidden: when |= NextWhen.Http403; break; case HttpStatusCode.NotFound: when |= NextWhen.Http404; break; default: return(false); } } #if NETSTANDARD2_0 if (request.Method == HttpMethod.Post || request.Method.Method == "PATCH") #elif NETSTANDARD2_1 if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Patch) #endif { when |= NextWhen.NonIdemponent; } if (when != (when & peer.NextWhen)) { return(false); } if (DateTime.Now - handlingContext.Start >= peer.NextTimeout) { return(false); } handlingContext.Request = request.Clone(originUri); //保持上下文重试 var next = await _dispatcher.AcceptThenDispatchAsync(handlingContext); handlingContext.Tries--; return(next); }
public void Handle( HandlingContext handlingContext, UpstreamPeer peer) { //负载均衡完成选择之后,由线程池线程完成接下来的http请求处理 Task.Run(async() => { var request = handlingContext.Request; var tcs = handlingContext.ResponsSource; var originalUri = request.RequestUri; //string originalScheme = current.Scheme; var response = default(HttpResponseMessage); try { var instance = peer?.Instance; var uri = instance?.Uri; if (uri != null) { request.RequestUri = new Uri(uri, originalUri.PathAndQuery); lock (peer) { peer.Connections++; } } var ct = handlingContext.CancellationToken; response = await handlingContext.HandleAsync(request, ct); if (!await NextPeerAsync(handlingContext, peer, response, originalUri)) { tcs.TrySetResult(response); } } catch (TaskCanceledException ex) { tcs.SetException(ex); _logger.LogWarning(ex, "Ensure that this cancelation is not caused by timeout, or you may lost the chance to try another upstream peer."); return; } catch (TimeoutException ex) { if (!await NextPeerAsync(handlingContext, peer, response, originalUri, true)) { tcs.SetException(ex); } } catch (HttpRequestException ex) { if (!await NextPeerAsync(handlingContext, peer, response, originalUri)) { tcs.TrySetException(ex); } } catch (Exception ex) { _logger.LogError(ex, ex.Message); tcs.SetException(ex); } finally { FreePeer(handlingContext, peer, response); } }); }