Example #1
0
        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;

            _responseData1 = Encoding.UTF8.GetBytes("{\"connectionId\":\"123\",\"availableTransports\":[]}");
            _responseData2 = Encoding.UTF8.GetBytes("{\"url\": \"http://foo.com/chat\"}");
            _responseData3 = Encoding.UTF8.GetBytes("{\"url\": \"http://foo.com/chat\", \"accessToken\": \"token\"}");
            _responseData4 = Encoding.UTF8.GetBytes("{\"connectionId\":\"123\",\"availableTransports\":[{\"transport\":\"test\",\"transferFormats\":[]}]}");

            var writer = new MemoryBufferWriter();

            NegotiateProtocol.WriteResponse(_negotiateResponse, writer);
            _responseData5 = writer.ToArray();
        }
    private static void WriteNegotiatePayload(IBufferWriter <byte> writer, string?connectionId, string?connectionToken, HttpContext context, HttpConnectionDispatcherOptions options,
                                              int clientProtocolVersion, string?error)
    {
        var response = new NegotiationResponse();

        if (!string.IsNullOrEmpty(error))
        {
            response.Error = error;
            NegotiateProtocol.WriteResponse(response, writer);
            return;
        }

        response.Version             = clientProtocolVersion;
        response.ConnectionId        = connectionId;
        response.ConnectionToken     = connectionToken;
        response.AvailableTransports = new List <AvailableTransport>();

        if ((options.Transports & HttpTransportType.WebSockets) != 0 && ServerHasWebSockets(context.Features))
        {
            response.AvailableTransports.Add(_webSocketAvailableTransport);
        }

        if ((options.Transports & HttpTransportType.ServerSentEvents) != 0)
        {
            response.AvailableTransports.Add(_serverSentEventsAvailableTransport);
        }

        if ((options.Transports & HttpTransportType.LongPolling) != 0)
        {
            response.AvailableTransports.Add(_longPollingAvailableTransport);
        }

        NegotiateProtocol.WriteResponse(response, writer);
    }
Example #3
0
        public void ParsingNegotiateResponseMessageThrowsForInvalid(string payload, string expectedMessage)
        {
            var responseData = Encoding.UTF8.GetBytes(payload);

            var exception = Assert.Throws <InvalidDataException>(() => NegotiateProtocol.ParseResponse(responseData));

            Assert.Equal(expectedMessage, exception.InnerException.Message);
        }
Example #4
0
        public void WriteNegotiateResponseWithNullAvailableTransports()
        {
            using (MemoryBufferWriter writer = new MemoryBufferWriter())
            {
                NegotiateProtocol.WriteResponse(new NegotiationResponse(), writer);

                string json = Encoding.UTF8.GetString(writer.ToArray());

                Assert.Equal("{\"negotiateVersion\":0,\"availableTransports\":[]}", json);
            }
        }
Example #5
0
        public void ParsingNegotiateResponseMessageSuccessForValid(string json, string connectionId, string[] availableTransports)
        {
            var responseData = Encoding.UTF8.GetBytes(json);
            var ms           = new MemoryStream(responseData);
            var response     = NegotiateProtocol.ParseResponse(ms);

            Assert.Equal(connectionId, response.ConnectionId);
            Assert.Equal(availableTransports.Length, response.AvailableTransports.Count);

            var responseTransports = response.AvailableTransports.Select(t => t.Transport).ToList();

            Assert.Equal(availableTransports, responseTransports);
        }
Example #6
0
        public Task WriteResponse_MemoryBufferWriter()
        {
            var writer = new MemoryBufferWriter();

            try
            {
                NegotiateProtocol.WriteResponse(_negotiateResponse, writer);
                return(writer.CopyToAsync(_stream));
            }
            finally
            {
                writer.Reset();
            }
        }
Example #7
0
        public void WriteNegotiateResponseWithNullTransferFormats()
        {
            using (MemoryBufferWriter writer = new MemoryBufferWriter())
            {
                NegotiateProtocol.WriteResponse(new NegotiationResponse
                {
                    AvailableTransports = new List <AvailableTransport>
                    {
                        new AvailableTransport()
                    }
                }, writer);

                string json = Encoding.UTF8.GetString(writer.ToArray());

                Assert.Equal("{\"negotiateVersion\":0,\"availableTransports\":[{\"transport\":null,\"transferFormats\":[]}]}", json);
            }
        }
Example #8
0
        public void ParsingNegotiateResponseMessageSuccessForValid(string json, string connectionId, string[] availableTransports, string url, string accessToken)
        {
            var responseData = Encoding.UTF8.GetBytes(json);
            var response     = NegotiateProtocol.ParseResponse(responseData);

            Assert.Equal(connectionId, response.ConnectionId);
            Assert.Equal(availableTransports?.Length, response.AvailableTransports?.Count);
            Assert.Equal(url, response.Url);
            Assert.Equal(accessToken, response.AccessToken);

            if (response.AvailableTransports != null)
            {
                var responseTransports = response.AvailableTransports.Select(t => t.Transport).ToList();

                Assert.Equal(availableTransports, responseTransports);
            }
        }
Example #9
0
        public void ParsingAspNetSignalRResponseThrowsError()
        {
            var payload = "{\"Url\":\"/signalr\"," +
                          "\"ConnectionToken\":\"X97dw3uxW4NPPggQsYVcNcyQcuz4w2\"," +
                          "\"ConnectionId\":\"05265228-1e2c-46c5-82a1-6a5bcc3f0143\"," +
                          "\"KeepAliveTimeout\":10.0," +
                          "\"DisconnectTimeout\":5.0," +
                          "\"TryWebSockets\":true," +
                          "\"ProtocolVersion\":\"1.5\"," +
                          "\"TransportConnectTimeout\":30.0," +
                          "\"LongPollDelay\":0.0}";

            var responseData = Encoding.UTF8.GetBytes(payload);

            var exception = Assert.Throws <InvalidDataException>(() => NegotiateProtocol.ParseResponse(responseData));

            Assert.Equal("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.", exception.InnerException.Message);
        }
Example #10
0
        private async Task <NegotiationResponse> Negotiate(Uri url, HttpClient httpClient, ILogger logger)
        {
            try
            {
                // Get a connection ID from the server
                Log.EstablishingConnection(logger, url);
                var urlBuilder = new UriBuilder(url);
                if (!urlBuilder.Path.EndsWith("/"))
                {
                    urlBuilder.Path += "/";
                }
                urlBuilder.Path += "negotiate";

                using (var request = new HttpRequestMessage(HttpMethod.Post, urlBuilder.Uri))
                {
                    // Corefx changed the default version and High Sierra curlhandler tries to upgrade request
                    request.Version = new Version(1, 1);

                    // ResponseHeadersRead instructs SendAsync to return once headers are read
                    // rather than buffer the entire response. This gives a small perf boost.
                    // Note that it is important to dispose of the response when doing this to
                    // avoid leaving the connection open.
                    using (var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
                    {
                        response.EnsureSuccessStatusCode();
                        NegotiationResponse negotiateResponse;
                        using (var responseStream = await response.Content.ReadAsStreamAsync())
                        {
                            negotiateResponse = NegotiateProtocol.ParseResponse(responseStream);
                        }
                        Log.ConnectionEstablished(_logger, negotiateResponse.ConnectionId);
                        return(negotiateResponse);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorWithNegotiation(logger, url, ex);
                throw;
            }
        }
Example #11
0
        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();
            }
        }
        private async Task RedirectToService(HttpContext context, string hubName, IList <IAuthorizeData> authorizationData)
        {
            if (!await AuthorizeHelper.AuthorizeAsync(context, authorizationData))
            {
                return;
            }

            var negotiateResponse = _negotiateHandler.Process(context, hubName);

            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();
            }
        }
Example #13
0
        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();
            }
        }
Example #14
0
 public void ParsingNegotiateResponseMessageSuccessForValid5()
 => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData5));
Example #15
0
 public void ParsingNegotiateResponseMessageSuccessForValid5()
 => NegotiateProtocol.ParseResponse(_responseData5);