diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index ea493936af..94b3b13f14 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -413,17 +413,17 @@
https://github.com/dotnet/extensions
cf044102f01a3402a680fa58cabea8a9ca53aa3d
-
+
https://github.com/dotnet/arcade
- 15f00efd583eab4372b2e9ca25bd80ace5b119ad
+ 1a55276ab9d16792cec595ba870df39a9d97d5ca
-
+
https://github.com/dotnet/arcade
- 15f00efd583eab4372b2e9ca25bd80ace5b119ad
+ 1a55276ab9d16792cec595ba870df39a9d97d5ca
-
+
https://github.com/dotnet/arcade
- 15f00efd583eab4372b2e9ca25bd80ace5b119ad
+ 1a55276ab9d16792cec595ba870df39a9d97d5ca
https://github.com/dotnet/extensions
@@ -434,4 +434,4 @@
d8180a5ecafb92adcfbfe8cf9199eb23be1a1ccf
-
+
\ No newline at end of file
diff --git a/eng/Versions.props b/eng/Versions.props
index e10323db1b..082dc20102 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -62,7 +62,7 @@
-->
- 1.0.0-beta.20113.5
+ 1.0.0-beta.20213.4
3.4.1-beta4-20127-10
@@ -271,4 +271,4 @@
https://dotnetcli.blob.core.windows.net/dotnet/
https://dotnetclimsrc.blob.core.windows.net/dotnet/
-
+
\ No newline at end of file
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index 94965a8fd2..acbb0c5b3f 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -210,7 +210,14 @@ function InstallDotNet {
local runtimeSourceFeedKey=''
if [[ -n "${7:-}" ]]; then
- decodedFeedKey=`echo $7 | base64 --decode`
+ # The 'base64' binary on alpine uses '-d' and doesn't support '--decode'
+ # '-d'. To work around this, do a simple detection and switch the parameter
+ # accordingly.
+ decodeArg="--decode"
+ if base64 --help 2>&1 | grep -q "BusyBox"; then
+ decodeArg="-d"
+ fi
+ decodedFeedKey=`echo $7 | base64 $decodeArg`
runtimeSourceFeedKey="--feed-credential $decodedFeedKey"
fi
diff --git a/global.json b/global.json
index 67ec79203b..974708a611 100644
--- a/global.json
+++ b/global.json
@@ -25,7 +25,7 @@
},
"msbuild-sdks": {
"Yarn.MSBuild": "1.15.2",
- "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20113.5",
- "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.20113.5"
+ "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20213.4",
+ "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.20213.4"
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs
index 0836ea8708..74b3de2e71 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs
@@ -66,6 +66,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
private static readonly Action _transportStarted =
LoggerMessage.Define(LogLevel.Debug, new EventId(18, "TransportStarted"), "Transport '{Transport}' started.");
+ private static readonly Action _serverSentEventsNotSupportedByBrowser =
+ LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");
+
public static void Starting(ILogger logger)
{
_starting(logger, null);
@@ -167,6 +170,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
{
_transportStarted(logger, transportType, null);
}
+
+ public static void ServerSentEventsNotSupportedByBrowser(ILogger logger)
+ {
+ _serverSentEventsNotSupportedByBrowser(logger, null);
+ }
}
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
index 4375d11285..4089360c01 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
@@ -37,6 +37,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
private bool _started;
private bool _disposed;
private bool _hasInherentKeepAlive;
+ private bool _isRunningInBrowser;
private readonly HttpClient _httpClient;
private readonly HttpConnectionOptions _httpConnectionOptions;
@@ -150,6 +151,14 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
_httpClient = CreateHttpClient();
}
+ _isRunningInBrowser = Utils.IsRunningInBrowser();
+
+
+ if (httpConnectionOptions.Transports == HttpTransportType.ServerSentEvents && _isRunningInBrowser)
+ {
+ throw new ArgumentException("ServerSentEvents can not be the only transport specified when running in the browser.", nameof(httpConnectionOptions));
+ }
+
_transportFactory = new DefaultTransportFactory(httpConnectionOptions.Transports, _loggerFactory, _httpClient, httpConnectionOptions, GetAccessTokenAsync);
_logScope = new ConnectionLogScope();
@@ -365,6 +374,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
continue;
}
+ if (transportType == HttpTransportType.ServerSentEvents && _isRunningInBrowser)
+ {
+ Log.ServerSentEventsNotSupportedByBrowser(_logger);
+ transportExceptions.Add(new TransportFailedException("ServerSentEvents", "The transport is not supported in the browser."));
+ continue;
+ }
+
try
{
if ((transportType & _httpConnectionOptions.Transports) == 0)
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
index f92f89a3a0..8071a054a3 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
{
@@ -41,5 +42,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
builder.Query = newQueryString;
return builder.Uri;
}
+
+ internal static bool IsRunningInBrowser()
+ {
+ return RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));
+ }
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
index 905a965841..8f201f6dbf 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
@@ -6,6 +6,7 @@ using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.WebSockets;
using System.Runtime.InteropServices;
+using System.Text.Encodings.Web;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
@@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
private readonly ILogger _logger;
private readonly TimeSpan _closeTimeout;
private volatile bool _aborted;
+ private bool _isRunningInBrowser;
private IDuplexPipe _transport;
@@ -87,6 +89,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
// Ignore the HttpConnectionOptions access token provider. We were given an updated delegate from the HttpConnection.
_accessTokenProvider = accessTokenProvider;
+
+ _isRunningInBrowser = Utils.IsRunningInBrowser();
}
public async Task StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken = default)
@@ -113,7 +117,17 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
var accessToken = await _accessTokenProvider();
if (!string.IsNullOrEmpty(accessToken))
{
- _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
+ // We can't use request headers in the browser, so instead append the token as a query string in that case
+ if (_isRunningInBrowser)
+ {
+ var accessTokenEncoded = UrlEncoder.Default.Encode(accessToken);
+ accessTokenEncoded = "access_token=" + accessTokenEncoded;
+ resolvedUrl = Utils.AppendQueryString(resolvedUrl, accessTokenEncoded);
+ }
+ else
+ {
+ _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
+ }
}
}