Browse Source

Fix tye's proxy for websockets (#1481)

* Fix tye's proxy for websockets
- We need to add the middleware

* Added a websocket proxy test
pull/1494/head
David Fowler 4 years ago
committed by GitHub
parent
commit
041aedcbc9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Microsoft.Tye.Hosting/HttpProxyService.cs
  2. 33
      test/E2ETest/TyeRunTests.cs
  3. 29
      test/E2ETest/testassets/projects/apps-with-ingress/ApplicationA/Startup.cs

2
src/Microsoft.Tye.Hosting/HttpProxyService.cs

@ -113,6 +113,8 @@ namespace Microsoft.Tye.Hosting
builder.Configure(app => builder.Configure(app =>
{ {
app.UseWebSockets();
app.UseRouting(); app.UseRouting();
app.UseEndpoints(endpointBuilder => app.UseEndpoints(endpointBuilder =>

33
test/E2ETest/TyeRunTests.cs

@ -11,10 +11,14 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net.WebSockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Primitives;
using Microsoft.Tye; using Microsoft.Tye;
using Microsoft.Tye.Hosting; using Microsoft.Tye.Hosting;
using Microsoft.Tye.Hosting.Model; using Microsoft.Tye.Hosting.Model;
@ -669,6 +673,7 @@ services:
}; };
var client = new HttpClient(new RetryHandler(handler)); var client = new HttpClient(new RetryHandler(handler));
var wsClient = new ClientWebSocket();
await RunHostingApplication(application, new HostOptions(), async (app, uri) => await RunHostingApplication(application, new HostOptions(), async (app, uri) =>
{ {
@ -702,6 +707,34 @@ services:
// checking preservePath behavior // checking preservePath behavior
var responsePreservePath = await client.GetAsync(ingressUri + "/C/test"); var responsePreservePath = await client.GetAsync(ingressUri + "/C/test");
Assert.Contains("Hit path /C/test", await responsePreservePath.Content.ReadAsStringAsync()); Assert.Contains("Hit path /C/test", await responsePreservePath.Content.ReadAsStringAsync());
string GetWebSocketUri(string uri)
{
if (uri.StartsWith("http"))
{
return "ws" + uri.Substring(4);
}
else if (uri.StartsWith("https"))
{
return "wss" + uri.Substring(5);
}
throw new NotSupportedException();
}
// Check the websocket endpoint
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var wsUri = GetWebSocketUri(ingressUri);
await wsClient.ConnectAsync(new Uri(wsUri + "/A/ws"), cts.Token);
var data = Encoding.UTF8.GetBytes("Hello World");
await wsClient.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cts.Token);
var receiveBuffer = new byte[4096];
var result = await wsClient.ReceiveAsync(receiveBuffer.AsMemory(), cts.Token);
Assert.True(result.EndOfMessage);
Assert.Equal(WebSocketMessageType.Text, result.MessageType);
Assert.Equal(data.Length, result.Count);
Assert.Equal(data, receiveBuffer.AsMemory(0, result.Count).ToArray());
await wsClient.CloseAsync(WebSocketCloseStatus.NormalClosure, "", cts.Token);
}); });
} }

29
test/E2ETest/testassets/projects/apps-with-ingress/ApplicationA/Startup.cs

@ -1,6 +1,8 @@
using System; using System;
using System.IO; using System.IO;
using System.Net.WebSockets;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -25,6 +27,8 @@ namespace ApplicationA
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
} }
app.UseWebSockets();
app.UseRouting(); app.UseRouting();
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
@ -53,6 +57,31 @@ namespace ApplicationA
query query
})); }));
}); });
endpoints.MapGet("/ws", async context =>
{
if (!context.WebSockets.IsWebSocketRequest)
{
context.Response.StatusCode = 400;
}
else
{
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await Echo(ws);
}
});
async Task Echo(WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
var result = await webSocket.ReceiveAsync(buffer.AsMemory(), default);
while (result.MessageType != WebSocketMessageType.Close)
{
await webSocket.SendAsync(buffer.AsMemory(..result.Count), result.MessageType, result.EndOfMessage, default);
result = await webSocket.ReceiveAsync(buffer.AsMemory(), default);
}
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", default);
}
}); });
} }
} }

Loading…
Cancel
Save