/// <summary> /// Process incoming data from the WebSocket /// </summary> /// <param name="webSocket">Remote WebSocket</param> /// <param name="endpointConnection">Local UNIX socket connection</param> /// <param name="sessionId">Session ID</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Asynchronous task</returns> private async Task ReadFromWebSocket(WebSocket webSocket, HttpEndpointConnection endpointConnection, int sessionId, CancellationToken cancellationToken) { int bufferSize = _configuration.GetValue("WebSocketBufferSize", 8192); byte[] rxBuffer = new byte[bufferSize]; do { // Read data from the WebSocket WebSocketReceiveResult result = await webSocket.ReceiveAsync(rxBuffer, cancellationToken); if (result.MessageType == WebSocketMessageType.Close) { // Remote end is closing this connection return; } if (result.MessageType == WebSocketMessageType.Binary) { // Terminate the connection if binary content is received await CloseConnection(webSocket, WebSocketCloseStatus.InvalidMessageType, "Only text commands are supported"); break; } // Forward it to the UNIX socket connection ReceivedHttpRequest receivedHttpRequest = new ReceivedHttpRequest { Body = Encoding.UTF8.GetString(rxBuffer, 0, result.Count), SessionId = sessionId }; await endpointConnection.SendHttpRequest(receivedHttpRequest, cancellationToken); }while (!cancellationToken.IsCancellationRequested); }
/// <summary> /// Process a RESTful HTTP request /// </summary> /// <param name="context">HTTP context</param> /// <param name="endpointConnection">Endpoint connection</param> /// <param name="sessionId">Session ID</param> /// <returns>Asynchronous task</returns> private async Task ProcessRestRequst(HttpContext context, HttpEndpointConnection endpointConnection, int sessionId) { // Deal with RESTful HTTP requests. Read the full HTTP request body first string body; using (StreamReader reader = new StreamReader(context.Request.Body)) { body = await reader.ReadToEndAsync(); } // Prepare the HTTP request notification ReceivedHttpRequest receivedHttpRequest = new ReceivedHttpRequest { Body = body, ContentType = context.Request.ContentType, SessionId = sessionId }; foreach (var item in context.Request.Headers) { receivedHttpRequest.Headers.Add(item.Key, item.Value.ToString()); } foreach (var item in context.Request.Query) { receivedHttpRequest.Queries.Add(item.Key, item.Value.ToString()); } // Send it to the third-party application and get a response type await endpointConnection.SendHttpRequest(receivedHttpRequest); SendHttpResponse httpResponse = await endpointConnection.GetHttpResponse(); // Send the response to the HTTP client context.Response.StatusCode = httpResponse.StatusCode; if (httpResponse.ResponseType == HttpResponseType.File) { context.Response.ContentType = "application/octet-stream"; using FileStream fs = new FileStream(httpResponse.Response, FileMode.Open, FileAccess.Read); await fs.CopyToAsync(context.Response.Body); } else { switch (httpResponse.ResponseType) { case HttpResponseType.StatusCode: context.Response.ContentType = null; break; case HttpResponseType.PlainText: context.Response.ContentType = "text/plain;charset=utf-8"; break; case HttpResponseType.JSON: context.Response.ContentType = "application/json"; break; } await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(httpResponse.Response)); } }
/// <summary> /// Process a RESTful HTTP request /// </summary> /// <param name="context">HTTP context</param> /// <param name="endpoint">HTTP endpoint descriptor</param> /// <param name="endpointConnection">Endpoint connection</param> /// <param name="sessionId">Session ID</param> /// <returns>Asynchronous task</returns> private async Task ProcessRestRequst(HttpContext context, HttpEndpoint endpoint, HttpEndpointConnection endpointConnection, int sessionId) { string body; if (endpoint.IsUploadRequest) { // Write to a temporary file string filename = Path.GetTempFileName(); using (FileStream fileStream = new(filename, FileMode.Create, FileAccess.Write, FileShare.Read)) { await context.Request.Body.CopyToAsync(fileStream); } // Adjust the file permissions if possible endpointConnection.GetPeerCredentials(out _, out int uid, out int gid); if (uid != 0 && gid != 0) { LinuxApi.Commands.Chown(filename, uid, gid); } body = filename; } else { // Read the body content using StreamReader reader = new(context.Request.Body); body = await reader.ReadToEndAsync(); } // Prepare the HTTP request notification ReceivedHttpRequest receivedHttpRequest = new() { Body = body, ContentType = context.Request.ContentType, SessionId = sessionId }; foreach (var item in context.Request.Headers) { receivedHttpRequest.Headers.Add(item.Key, item.Value.ToString()); } foreach (var item in context.Request.Query) { receivedHttpRequest.Queries.Add(item.Key, item.Value.ToString()); } // Send it to the third-party application and get a response type await endpointConnection.SendHttpRequest(receivedHttpRequest); SendHttpResponse httpResponse = await endpointConnection.GetHttpResponse(); // Send the response to the HTTP client context.Response.StatusCode = httpResponse.StatusCode; if (httpResponse.ResponseType == HttpResponseType.File) { context.Response.ContentType = "application/octet-stream"; using FileStream fs = new(httpResponse.Response, FileMode.Open, FileAccess.Read); await fs.CopyToAsync(context.Response.Body); } else { switch (httpResponse.ResponseType) { case HttpResponseType.StatusCode: context.Response.ContentType = null; break; case HttpResponseType.PlainText: context.Response.ContentType = "text/plain;charset=utf-8"; break; case HttpResponseType.JSON: context.Response.ContentType = "application/json"; break; } await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(httpResponse.Response)); } } }