-
Notifications
You must be signed in to change notification settings - Fork 9.8k
/
WebSocketAcceptAdapter.cs
92 lines (84 loc) · 3.48 KB
/
WebSocketAcceptAdapter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Owin
{
using AppFunc = Func<IDictionary<string, object>, Task>;
using WebSocketAccept =
Action
<
IDictionary<string, object>, // WebSocket Accept parameters
Func // WebSocketFunc callback
<
IDictionary<string, object>, // WebSocket environment
Task // Complete
>
>;
using WebSocketAcceptAlt =
Func
<
WebSocketAcceptContext, // WebSocket Accept parameters
Task<WebSocket>
>;
/// <summary>
/// This adapts the ASP.NET Core WebSocket Accept flow to match the OWIN WebSocket accept flow.
/// This enables OWIN based components to use WebSockets on ASP.NET Core servers.
/// </summary>
public class WebSocketAcceptAdapter
{
private IDictionary<string, object> _env;
private WebSocketAcceptAlt _accept;
private AppFunc _callback;
private IDictionary<string, object> _options;
public WebSocketAcceptAdapter(IDictionary<string, object> env, WebSocketAcceptAlt accept)
{
_env = env;
_accept = accept;
}
private void AcceptWebSocket(IDictionary<string, object> options, AppFunc callback)
{
_options = options;
_callback = callback;
_env[OwinConstants.ResponseStatusCode] = 101;
}
public static AppFunc AdaptWebSockets(AppFunc next)
{
return async environment =>
{
object accept;
if (environment.TryGetValue(OwinConstants.WebSocket.AcceptAlt, out accept) && accept is WebSocketAcceptAlt)
{
var adapter = new WebSocketAcceptAdapter(environment, (WebSocketAcceptAlt)accept);
environment[OwinConstants.WebSocket.Accept] = new WebSocketAccept(adapter.AcceptWebSocket);
await next(environment);
if ((int)environment[OwinConstants.ResponseStatusCode] == 101 && adapter._callback != null)
{
WebSocketAcceptContext acceptContext = null;
object obj;
if (adapter._options != null && adapter._options.TryGetValue(typeof(WebSocketAcceptContext).FullName, out obj))
{
acceptContext = obj as WebSocketAcceptContext;
}
else if (adapter._options != null)
{
acceptContext = new OwinWebSocketAcceptContext(adapter._options);
}
var webSocket = await adapter._accept(acceptContext);
var webSocketAdapter = new WebSocketAdapter(webSocket, (CancellationToken)environment[OwinConstants.CallCancelled]);
await adapter._callback(webSocketAdapter.Environment);
await webSocketAdapter.CleanupAsync();
}
}
else
{
await next(environment);
}
};
}
}
}