/// <summary> /// Returns a raw stream which can be SSL encoded and the original /// Network stream so both are accessible. Use the raw stream /// for read/write and the Network Stream for checking data /// availability /// </summary> /// <param name="secure"></param> /// <returns></returns> WebRequestContext OpenConnection(bool secure = false) { WebRequestContext requestContext = new WebRequestContext(); try { requestContext.Connection = TcpServer.AcceptTcpClient(); requestContext.Connection.ReceiveTimeout = 3000; requestContext.Connection.SendTimeout = 3000; requestContext.NetworkStream = requestContext.Connection.GetStream(); if (secure) { requestContext.Stream = new SslStream(requestContext.NetworkStream); } else { requestContext.Stream = requestContext.NetworkStream; } } catch { return(null); } return(requestContext); }
void CloseConnection() { // close connection RequestContext?.Close(); RequestContext = null; }
public void RunServer() { TcpServer?.Stop(); try { TcpServer = new TcpListener(IPAddress.Parse(IpAddress), ServerPort); TcpServer.Start(); } catch (Exception ex) { var window = mmApp.Model?.Window; if (window != null) { window.Dispatcher.InvokeAsync(() => { mmApp.Model.Configuration.WebServer.IsRunning = false; window.ShowStatusError( $"Failed to start Web Server on `localhost:{ServerPort}`: {ex.Message}"); }); } return; } // enter to an infinite cycle to be able to handle every change in stream while (!Cancelled) { try { RequestContext = OpenConnection(); var capturedData = new List <byte>(); WaitForConnectionData(); if (!RequestContext.Connection.Connected) { continue; } if (RequestContext.Connection.Available == 0) { continue; } if (!ParseRequest()) { continue; } // Send CORS header so this can be accessed if (RequestContext.Verb == "OPTIONS") { WriteResponseInternal(null, "HTTP/1.1 200 OK\r\n" + "Access-Control-Allow-Origin: *\r\n" + "Access-Control-Allow-Methods: GET,POST,PUT,OPTIONS\r\n" + "Access-Control-Allow-Headers: *\r\n"); continue; // done here } else if (RequestContext.Verb == "POST" && (RequestContext.Path == "/markdownmonster" || RequestContext.Path.StartsWith("/markdownmonster/"))) { WebServerResult result = new WebServerResult(); try { var operation = JsonConvert.DeserializeObject(RequestContext.RequestContent, typeof(WebServerOperation)) as WebServerOperation; if (operation == null) { throw new ArgumentException("Invalid json request data: " + RequestContext.RequestContent); } try { result = OnMarkdownMonsterOperation?.Invoke(operation); } catch { mmApp.Model?.Window?.ShowStatusError("Web Server Client Request failed. Operation: " + operation.Operation); } } catch (Exception ex) { WriteErrorResponse("Markdown Monster Message Processing failed: " + ex.Message + "\r\n\r\n" + RequestContext.RequestContent); continue; } WriteResponse(result); } else if (RequestContext.Path.StartsWith("/ping")) { WriteDataResponse("OK"); } else { var result = new WebServerResult("Invalid URL access", 404); WriteResponse(result); } } catch (Exception ex) { WriteErrorResponse("An error occurred: " + ex.Message); } finally { // close connection CloseConnection(); RequestContext = null; } } }