Пример #1
0
        /// <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);
        }
Пример #2
0
 void CloseConnection()
 {
     // close connection
     RequestContext?.Close();
     RequestContext = null;
 }
Пример #3
0
        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;
                }
            }
        }