1313using System . Net . WebSockets ;
1414using System . Security . Authentication ;
1515using System . Text . Json ;
16- using System . Threading ;
1716using System . Threading . Tasks ;
1817
1918namespace OpenAI . Proxy
@@ -66,8 +65,7 @@ async Task HandleRequest(HttpContext httpContext, string endpoint)
6665 {
6766 if ( httpContext . WebSockets . IsWebSocketRequest )
6867 {
69- await ProcessWebSocketRequest ( httpContext , endpoint ) . ConfigureAwait ( false ) ;
70- return ;
68+ throw new InvalidOperationException ( "Websockets not supported" ) ;
7169 }
7270
7371 await authenticationFilter . ValidateAuthenticationAsync ( httpContext . Request . Headers ) . ConfigureAwait ( false ) ;
@@ -87,9 +85,7 @@ async Task HandleRequest(HttpContext httpContext, string endpoint)
8785
8886 var uri = new Uri ( string . Format (
8987 client . Settings . BaseRequestUrlFormat ,
90- QueryHelpers . AddQueryString ( endpoint , modifiedQuery )
91- ) ) ;
92-
88+ QueryHelpers . AddQueryString ( endpoint , modifiedQuery ) ) ) ;
9389 using var request = new HttpRequestMessage ( method , uri ) ;
9490 request . Content = new StreamContent ( httpContext . Request . Body ) ;
9591
@@ -129,16 +125,18 @@ async Task HandleRequest(HttpContext httpContext, string endpoint)
129125 }
130126 catch ( AuthenticationException authenticationException )
131127 {
128+ Console . WriteLine ( $ "{ nameof ( AuthenticationException ) } : { authenticationException . Message } ") ;
132129 httpContext . Response . StatusCode = StatusCodes . Status401Unauthorized ;
133130 await httpContext . Response . WriteAsync ( authenticationException . Message ) . ConfigureAwait ( false ) ;
134131 }
135- catch ( WebSocketException )
132+ catch ( WebSocketException webEx )
136133 {
137- // ignore
134+ Console . WriteLine ( $ " { nameof ( WebSocketException ) } [ { webEx . WebSocketErrorCode } ] { webEx . Message } " ) ;
138135 throw ;
139136 }
140137 catch ( Exception e )
141138 {
139+ Console . WriteLine ( $ "{ nameof ( Exception ) } : { e . Message } ") ;
142140 if ( httpContext . Response . HasStarted ) { throw ; }
143141 httpContext . Response . StatusCode = StatusCodes . Status500InternalServerError ;
144142 var response = JsonSerializer . Serialize ( new { error = new { e . Message , e . StackTrace } } ) ;
@@ -152,88 +150,6 @@ static async Task WriteServerStreamEventsAsync(HttpContext httpContext, Stream c
152150 await responseStream . FlushAsync ( httpContext . RequestAborted ) . ConfigureAwait ( false ) ;
153151 }
154152 }
155-
156- async Task ProcessWebSocketRequest ( HttpContext httpContext , string endpoint )
157- {
158- using var clientWebsocket = await httpContext . WebSockets . AcceptWebSocketAsync ( ) . ConfigureAwait ( false ) ;
159-
160- try
161- {
162- await authenticationFilter . ValidateAuthenticationAsync ( httpContext . Request . Headers ) . ConfigureAwait ( false ) ;
163- }
164- catch ( AuthenticationException authenticationException )
165- {
166- var message = JsonSerializer . Serialize ( new
167- {
168- type = "error" ,
169- error = new
170- {
171- type = "invalid_request_error" ,
172- code = "invalid_session_token" ,
173- message = authenticationException . Message
174- }
175- } ) ;
176- await clientWebsocket . SendAsync ( System . Text . Encoding . UTF8 . GetBytes ( message ) , WebSocketMessageType . Text , true , httpContext . RequestAborted ) . ConfigureAwait ( false ) ;
177- await clientWebsocket . CloseAsync ( WebSocketCloseStatus . PolicyViolation , authenticationException . Message , httpContext . RequestAborted ) . ConfigureAwait ( false ) ;
178- return ;
179- }
180-
181- if ( endpoint . EndsWith ( "echo" ) )
182- {
183- await EchoAsync ( clientWebsocket , httpContext . RequestAborted ) ;
184- return ;
185- }
186-
187- using var hostWebsocket = new ClientWebSocket ( ) ;
188-
189- foreach ( var header in client . WebsocketHeaders )
190- {
191- hostWebsocket . Options . SetRequestHeader ( header . Key , header . Value ) ;
192- }
193-
194- var uri = new Uri ( string . Format (
195- client . Settings . BaseWebSocketUrlFormat ,
196- $ "{ endpoint } { httpContext . Request . QueryString } "
197- ) ) ;
198- await hostWebsocket . ConnectAsync ( uri , httpContext . RequestAborted ) . ConfigureAwait ( false ) ;
199- var receive = ProxyWebSocketMessages ( clientWebsocket , hostWebsocket , httpContext . RequestAborted ) ;
200- var send = ProxyWebSocketMessages ( hostWebsocket , clientWebsocket , httpContext . RequestAborted ) ;
201- await Task . WhenAll ( receive , send ) . ConfigureAwait ( false ) ;
202- return ;
203-
204- async Task ProxyWebSocketMessages ( WebSocket fromSocket , WebSocket toSocket , CancellationToken cancellationToken )
205- {
206- var buffer = new byte [ 1024 * 4 ] ;
207- var memoryBuffer = buffer . AsMemory ( ) ;
208-
209- while ( fromSocket . State == WebSocketState . Open && ! cancellationToken . IsCancellationRequested )
210- {
211- var result = await fromSocket . ReceiveAsync ( memoryBuffer , cancellationToken ) . ConfigureAwait ( false ) ;
212-
213- if ( fromSocket . CloseStatus . HasValue || result . MessageType == WebSocketMessageType . Close )
214- {
215- await toSocket . CloseOutputAsync ( fromSocket . CloseStatus ?? WebSocketCloseStatus . NormalClosure , fromSocket . CloseStatusDescription ?? "Closing" , cancellationToken ) . ConfigureAwait ( false ) ;
216- break ;
217- }
218-
219- await toSocket . SendAsync ( memoryBuffer [ ..result . Count ] , result . MessageType , result . EndOfMessage , cancellationToken ) . ConfigureAwait ( false ) ;
220- }
221- }
222- }
223-
224- static async Task EchoAsync ( WebSocket webSocket , CancellationToken cancellationToken )
225- {
226- var buffer = new byte [ 1024 * 4 ] ;
227- var receiveResult = await webSocket . ReceiveAsync ( new ArraySegment < byte > ( buffer ) , cancellationToken ) ;
228-
229- while ( ! receiveResult . CloseStatus . HasValue )
230- {
231- await webSocket . SendAsync ( new ArraySegment < byte > ( buffer , 0 , receiveResult . Count ) , receiveResult . MessageType , receiveResult . EndOfMessage , cancellationToken ) ;
232- receiveResult = await webSocket . ReceiveAsync ( new ArraySegment < byte > ( buffer ) , cancellationToken ) ;
233- }
234-
235- await webSocket . CloseAsync ( receiveResult . CloseStatus . Value , receiveResult . CloseStatusDescription , cancellationToken ) ;
236- }
237153 }
238154 }
239155}
0 commit comments