public Task<NegotiationResponse> Negotiate(IConnection connection, string connectionData) { Task<NegotiationResponse> response = _httpClient.GetNegotiationResponse(connection, connectionData); response.Then(negotiationResponse => _negotiationResponse = negotiationResponse); return response; }
public void GlobalSetup() { _negotiateResponse = new NegotiationResponse { ConnectionId = "d100338e-8c01-4281-92c2-9a967fdeebcb", AvailableTransports = new List <AvailableTransport> { new AvailableTransport { Transport = "WebSockets", TransferFormats = new List <string> { "Text", "Binary" } } } }; _stream = Stream.Null; }
private async Task RedirectToService(HttpContext context, string hubName, IList <IAuthorizeData> authorizationData) { if (!await AuthorizeHelper.AuthorizeAsync(context, authorizationData)) { return; } NegotiationResponse negotiateResponse = null; try { negotiateResponse = _negotiateHandler.Process(context, hubName); } catch (AzureSignalRAccessTokenTooLongException ex) { Log.NegotiateFailed(_logger, ex.Message); context.Response.StatusCode = 413; await HttpResponseWritingExtensions.WriteAsync(context.Response, ex.Message); return; } var writer = new MemoryBufferWriter(); try { context.Response.ContentType = "application/json"; NegotiateProtocol.WriteResponse(negotiateResponse, writer); // Write it out to the response with the right content length context.Response.ContentLength = writer.Length; await writer.CopyToAsync(context.Response.Body); } finally { writer.Reset(); } }
public async Task NegotiateInvokesGetNegotiationResponseOnTransportHelperAsync() { const string transportName = "fakeTransport"; var connection = new Connection("http://fake.url/"); var client = new DefaultHttpClient(); var negotiationResponse = new NegotiationResponse(); var mockTransportHelper = new Mock<TransportHelper>(); mockTransportHelper.Setup( h => h.GetNegotiationResponse(It.IsAny<IHttpClient>(), It.IsAny<IConnection>(), It.IsAny<string>())) .Returns(Task.FromResult(negotiationResponse)); var transport = new Mock<ClientTransportBase>(client, transportName, mockTransportHelper.Object, new TransportAbortHandler(client, transportName)) { CallBase = true }.Object; Assert.Same(negotiationResponse, await transport.Negotiate(connection, "test")); mockTransportHelper.Verify(m => m.GetNegotiationResponse(client, connection, "test"), Times.Once()); }
public static async Task RedirectToService(HttpContext context, string hubName, IList <IAuthorizeData> authorizationData) { var handler = context.RequestServices.GetRequiredService <NegotiateHandler>(); var loggerFactory = context.RequestServices.GetService <ILoggerFactory>(); var logger = loggerFactory.CreateLogger <ServiceRouteHelper>(); if (authorizationData != null && !await AuthorizeHelper.AuthorizeAsync(context, authorizationData)) { return; } NegotiationResponse negotiateResponse = null; try { negotiateResponse = handler.Process(context, hubName); if (context.Response.HasStarted) { // Inner handler already write to context.Response, no need to continue with error case return; } // Consider it as internal server error when we don't successfully get negotiate response if (negotiateResponse == null) { var message = "Unable to get the negotiate endpoint"; Log.NegotiateFailed(logger, message); context.Response.StatusCode = 500; await context.Response.WriteAsync(message); return; } } catch (AzureSignalRAccessTokenTooLongException ex) { Log.NegotiateFailed(logger, ex.Message); context.Response.StatusCode = 413; await context.Response.WriteAsync(ex.Message); return; } catch (AzureSignalRNotConnectedException e) { Log.NegotiateFailed(logger, e.Message); context.Response.StatusCode = 500; await context.Response.WriteAsync(e.Message); return; } var writer = new MemoryBufferWriter(); try { context.Response.ContentType = "application/json"; NegotiateProtocol.WriteResponse(negotiateResponse, writer); // Write it out to the response with the right content length context.Response.ContentLength = writer.Length; await writer.CopyToAsync(context.Response.Body); } finally { writer.Reset(); } }
public void WebSocketRemovedFromTransportList() { var tcs = new TaskCompletionSource<NegotiationResponse>(); var mre = new ManualResetEventSlim(); var transports = new List<IClientTransport>(); var webSocketTransport = new Mock<WebSocketTransport>(); webSocketTransport.Protected() .Setup("OnStart", ItExpr.IsAny<IConnection>(), ItExpr.IsAny<string>(), CancellationToken.None) .Callback(mre.Set); transports.Add(webSocketTransport.Object); transports.Add(new ServerSentEventsTransport()); transports.Add(new LongPollingTransport()); var negotiationResponse = new NegotiationResponse(); negotiationResponse.TryWebSockets = false; tcs.SetResult(negotiationResponse); var autoTransport = new Mock<AutoTransport>(It.IsAny<IHttpClient>(), transports); autoTransport.Setup(c => c.GetNegotiateResponse(It.IsAny<Connection>(), It.IsAny<string>())).Returns(tcs.Task); autoTransport.Object.Negotiate(new Connection("http://foo", string.Empty), string.Empty).Wait(); Assert.False(mre.IsSet); }
/// <summary> /// Writes the <paramref name="response"/> to the <paramref name="output"/>. /// </summary> /// <param name="response">The negotiation response generated in response to a negotiation request.</param> /// <param name="output">Where the <paramref name="response"/> is written to as Json.</param> public static void WriteResponse(NegotiationResponse response, IBufferWriter <byte> output) { var reusableWriter = ReusableUtf8JsonWriter.Get(output); try { var writer = reusableWriter.GetJsonWriter(); writer.WriteStartObject(); // If we already have an error its due to a protocol version incompatibility. // We can just write the error and complete the JSON object and return. if (!string.IsNullOrEmpty(response.Error)) { writer.WriteString(ErrorPropertyNameBytes, response.Error); writer.WriteEndObject(); writer.Flush(); Debug.Assert(writer.CurrentDepth == 0); return; } writer.WriteNumber(NegotiateVersionPropertyNameBytes, response.Version); if (!string.IsNullOrEmpty(response.Url)) { writer.WriteString(UrlPropertyNameBytes, response.Url); } if (!string.IsNullOrEmpty(response.AccessToken)) { writer.WriteString(AccessTokenPropertyNameBytes, response.AccessToken); } if (!string.IsNullOrEmpty(response.ConnectionId)) { writer.WriteString(ConnectionIdPropertyNameBytes, response.ConnectionId); } if (response.Version > 0 && !string.IsNullOrEmpty(response.ConnectionToken)) { writer.WriteString(ConnectionTokenPropertyNameBytes, response.ConnectionToken); } writer.WriteStartArray(AvailableTransportsPropertyNameBytes); if (response.AvailableTransports != null) { var transportCount = response.AvailableTransports.Count; for (var i = 0; i < transportCount; ++i) { var availableTransport = response.AvailableTransports[i]; writer.WriteStartObject(); if (availableTransport.Transport != null) { writer.WriteString(TransportPropertyNameBytes, availableTransport.Transport); } else { // Might be able to remove this after https://github.com/dotnet/corefx/issues/34632 is resolved writer.WriteNull(TransportPropertyNameBytes); } writer.WriteStartArray(TransferFormatsPropertyNameBytes); if (availableTransport.TransferFormats != null) { var formatCount = availableTransport.TransferFormats.Count; for (var j = 0; j < formatCount; ++j) { writer.WriteStringValue(availableTransport.TransferFormats[j]); } } writer.WriteEndArray(); writer.WriteEndObject(); } } writer.WriteEndArray(); writer.WriteEndObject(); writer.Flush(); Debug.Assert(writer.CurrentDepth == 0); } finally { ReusableUtf8JsonWriter.Return(reusableWriter); } }