예제 #1
0
        protected ConnectionCloseEventArgs GetConnectionCloseEventArgsFromPayload(byte[] payload)
        {
            if (payload.Length >= 2)
            {
                using (MemoryStream stream = new MemoryStream(payload))
                {
                    ushort code = BinaryReaderWriter.ReadUShortExactly(stream, false);

                    try
                    {
                        WebSocketCloseCode closeCode = (WebSocketCloseCode)code;

                        if (payload.Length > 2)
                        {
                            string reason = Encoding.UTF8.GetString(payload, 2, payload.Length - 2);
                            return(new ConnectionCloseEventArgs(closeCode, reason));
                        }
                        else
                        {
                            return(new ConnectionCloseEventArgs(closeCode, null));
                        }
                    }
                    catch (InvalidCastException)
                    {
                        _logger.Warning(this.GetType(), "Close code {0} not recognised", code);
                        return(new ConnectionCloseEventArgs(WebSocketCloseCode.Normal, null));
                    }
                }
            }

            return(new ConnectionCloseEventArgs(WebSocketCloseCode.Normal, null));
        }
예제 #2
0
        public static void Recieve(int port)
        {
            try
            {
                string webRoot    = string.Empty;
                string baseFolder = AppDomain.CurrentDomain.BaseDirectory;
                _logger.Warning(typeof(MainWindow), "Webroot folder {0} not found. Using application base directory: {1}", webRoot, baseFolder);
                webRoot = baseFolder;


                // used to decide what to do with incoming connections
                var serviceFactory = new ServiceFactory(webRoot, _logger);

                using (var server = new WebServer(serviceFactory, _logger))
                {
                    server.Listen(port);

                    Thread.Sleep(100000);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
예제 #3
0
        private static void Main(string[] args)
        {
            _logger = new WebSocketLogger();

            try
            {
                int    port    = 2120;
                string webRoot = Settings.Default.WebRoot;
                if (!Directory.Exists(webRoot))
                {
                    string baseFolder = AppDomain.CurrentDomain.BaseDirectory;
                    _logger.Warning(typeof(Program), "Webroot folder {0} not found. Using application base directory: {1}", webRoot, baseFolder);
                    webRoot = baseFolder;
                }

                // used to decide what to do with incoming connections
                ServiceFactory serviceFactory = new ServiceFactory(webRoot, _logger);

                using (WebServer server = new WebServer(serviceFactory, _logger))
                {
                    server.Listen(port);

                    //Thread clientThread = new Thread(new ParameterizedThreadStart(TestClient));
                    //clientThread.IsBackground = true;

                    //clientThread.Start("ws://localhost:2120/chat");
                    Console.ReadKey();
                }
            }
            catch (Exception ex)
            {
                _logger.Error(typeof(Program), ex);
                Console.ReadKey();
            }
        }
예제 #4
0
        public void Respond()
        {
            HttpHelper.WriteHttpHeader("HTTP/1.1 400 Bad Request", _stream);

            // limit what we log. Headers can be up to 16K in size
            string header = _header.Length > 255 ? _header.Substring(0, 255) + "..." : _header;

            _logger.Warning(this.GetType(), "Bad request: '{0}'", header);
        }
예제 #5
0
        public void Respond()
        {
            HttpHelper.WriteHttpHeader("HTTP/1.1 400 Bad Request", _stream);

            // limit what we log. Headers can be up to 16K in size
            int    length = 1024 * 16; // 16KB buffer more than enough for http header
            string header = _header.Length > length?_header.Substring(0, length) + "..." : _header;

            _logger.Warning("", this.GetType(), "Bad request: '{0}'", header);
        }
예제 #6
0
        //Check if the classes we have available is of type
        public bool SendAllWebsockets(string sCommand, ArrayList aParameters)
        {
            //Webserver running?
            if (_isDisposed)
            {
                return(false);
            }

            try
            {
                _logger.Debug(this.GetType(), "openConnections lock in SendAllWebsockets");

                // record the connection so we can close it if something goes wrong
                lock (_openConnections)
                {
                    //_openConnections.Add(service);
                    for (int i = 0; i < _openConnections.Count(); i++)
                    {
                        IService oService = (IService)_openConnections[i];
                        Type     tType    = oService.GetType();
                        if (tType.IsSubclassOf(typeof(WebSocketBase)))
                        {
                            IServiceWebsocket oServiceWS = (IServiceWebsocket)_openConnections[i];
                            oServiceWS.SendCommand(sCommand, aParameters);
                        }
                        //else
                        //    _logger.Error(typeof(WebServer), "Not websocket... This error message should not happend");
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                // do nothing. This will be thrown if the Listener has been stopped
                _logger.Warning(this.GetType(), "Object is already disposed in SensAllWebsocket...");
            }
            catch (Exception ex)
            {
                _logger.Error(this.GetType(), ex);
            }

            return(true);
        }
예제 #7
0
 public ServiceFactory(string webRoot, IWebSocketLogger logger)
 {
     _logger  = logger;
     _webRoot = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
     if (!Directory.Exists(_webRoot))
     {
         _logger.Warning(this.GetType(), "Web root not found: {0}", _webRoot);
     }
     else
     {
         _logger.Information(this.GetType(), "Web root: {0}", _webRoot);
     }
 }
예제 #8
0
 public ServiceFactory(string webRoot, IWebSocketLogger logger, String Identification_Alias, WebServer server, BusinessObject My_CommObject)
 {
     _Identification_Alias = Identification_Alias;
     _logger        = logger;
     _webRoot       = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
     _server        = server;
     _My_CommObject = My_CommObject;
     if (!Directory.Exists(_webRoot))
     {
         _logger.Warning("", this.GetType(), "Web root not found: {0}", _webRoot);
     }
     else
     {
         _logger.Information("", this.GetType(), "Web root: {0}", _webRoot);
     }
 }
예제 #9
0
        public MOTR_WebserverFactoryInitalWizard(string webRoot, MOTR_Users users, MOTR_Admin _admin, IWebSocketLogger logger)
        {
            _logger  = logger;
            _webRoot = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
            m_Users  = users;
            m_Admin  = _admin;

            if (!Directory.Exists(_webRoot))
            {
                _logger.Warning(this.GetType(), "InitalWizard: Web root not found: {0}", _webRoot);
            }
            else
            {
                _logger.Information(this.GetType(), "InitalWizard: Web root: {0}", _webRoot);
            }
        }
예제 #10
0
        private static void Main(string[] args)
        {
            _logger = new WebSocketLogger();

            try
            {
                int    port    = Settings.Default.Port;
                string webRoot = Settings.Default.WebRoot;
                if (!Directory.Exists(webRoot))
                {
                    string baseFolder = AppDomain.CurrentDomain.BaseDirectory;
                    _logger.Warning(typeof(Program), "Webroot folder {0} not found. Using application base directory: {1}", webRoot, baseFolder);
                    webRoot = baseFolder;
                }

                // used to decide what to do with incoming connections
                ServiceFactory serviceFactory = new ServiceFactory(webRoot, _logger);

                using (WebServer server = new WebServer(serviceFactory, _logger))
                {
                    if (port == 443)
                    {
                        X509Certificate2 cert = GetCertificate();
                        server.Listen(port, cert);
                    }
                    else
                    {
                        server.Listen(port);
                    }

                    Thread clientThread = new Thread(new ParameterizedThreadStart(TestClient));
                    clientThread.IsBackground = false;

                    // to enable ssl change the port to 443 in the settings file and use the wss schema below
                    // clientThread.Start("wss://localhost/chat");

                    clientThread.Start("ws://localhost/chat");
                    Console.ReadKey();
                }
            }
            catch (Exception ex)
            {
                _logger.Error(typeof(Program), ex);
                Console.ReadKey();
            }
        }
예제 #11
0
        private void WaitForServerCloseMessage()
        {
            // as per the websocket spec, the server must close the connection, not the client.
            // The client is free to close the connection after a timeout period if the server fails to do so
            _conectionCloseWait.WaitOne(TimeSpan.FromSeconds(10));

            // this will only happen if the server has failed to reply with a close response
            if (_isOpen)
            {
                _logger.Warning("", this.GetType(), "Server failed to respond with a close response. Closing the connection from the client side.");

                // wait for data to be sent before we close the stream and client
                _tcpClient.Client.Shutdown(SocketShutdown.Both);
                _stream.Close();
                _tcpClient.Close();
            }

            _logger.Information("", this.GetType(), "Client: Connection closed");
        }
예제 #12
0
        public MOTR_WebserverFactory(string webRoot, MOTR_Sessions sessions, MOTR_Users users, MOTR_Dirs dirs, MOTR_Queue queue, MOTR_Admin _admin, MOTR_Downloads _downloads, IWebSocketLogger logger, MOTR_Webserver _webserver)
        {
            _logger     = logger;
            _webRoot    = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
            m_Sessions  = sessions;
            m_Users     = users;
            m_Dirs      = dirs;
            m_Queue     = queue;
            m_WebServer = _webserver;
            m_Admin     = _admin;
            m_Downloads = _downloads;

            if (!Directory.Exists(_webRoot))
            {
                _logger.Warning(this.GetType(), "Web root not found: {0}", _webRoot);
            }
            else
            {
                _logger.Debug(this.GetType(), "Web root: " + _webRoot);
            }
        }
예제 #13
0
        public void HandleEventSendMobileDownload(object sender, MobileDownloadEventArgs args)
        {
            _logger.Debug(typeof(MOTR_Webserver), "Mobile download!");
            for (int i = 0; i < aWebservers.Count; i++)
            {
                //If we found a connection with websocket, we will return now
                if (aWebservers[i].server.MobileDownload(args.MobileID, args.UserID))
                {
                    return;
                }
            }

            //If reached here we don't have a active connection, trigger a push message
            if (args.PushID.Length == 0)
            {
                _logger.Warning(typeof(MOTR_Webserver), "Mobile " + args.MobileID.ToString() + " does not have pushid registered, unable to download");
                return;
            }
            MOTR_PushMobile m_MobilePush = new MOTR_PushMobile();

            m_MobilePush.SendPush(args.PushID);
        }
예제 #14
0
 public void RespondMimeTypeFailure(string file)
 {
     HttpHelper.WriteHttpHeader("415 Unsupported Media Type", _stream);
     _logger.Warning("", this.GetType(), "File extension not found MimeTypes.config: {0}", file);
 }
예제 #15
0
/*
 *      private LoginReturn LoginValid(string sHeader)
 *      {
 *          //Hent ut info fra svaret
 *          int iLength = GetContentLength(sHeader);
 *          int nEndPos = sHeader.IndexOf("\r\n\r\n");
 *          if (nEndPos+4 > (sHeader.Length - iLength))
 *          {
 *              Console.WriteLine("No userdata ffs: " + sHeader);
 *              return LoginReturn.NO_CONTENT;
 *          }
 *          string sPostData = sHeader.Substring(sHeader.Length - iLength);
 *          _logger.Information(typeof(MOTR_WebserverFactory), "Header in POST: " + sHeader);
 *          _logger.Information(typeof(MOTR_WebserverFactory), "PostData: " + sPostData);
 *
 *          //Data needs to be at least u=x&p=x
 *          if (sPostData.Length < 7)
 *              return LoginReturn.NOT_LOGGED_IN;
 *
 *          //Split the chars
 *          char[] delimiterChars = { '=', '&'};
 *          string[] verbs= sPostData.Split(delimiterChars);
 *
 *          //Fill username and password
 *          string sUsername="";
 *          string sPassword="";
 *          for(int i=0;i<verbs.Count();i++)
 *          {
 *              //Find username
 *              if (verbs[i].ToUpper() == "U")
 *                  if(verbs.Count() > i+1)
 *                      sUsername = verbs[i + 1];
 *              if (verbs[i].ToUpper() == "P")
 *                  if (verbs.Count() > i + 1)
 *                      sPassword = verbs[i + 1];
 *          }
 *
 *          //Console.WriteLine("Username: "******"Password: "******"/directory")
                {
                    MOTR_DirectoryWebsocket pWS = new MOTR_DirectoryWebsocket(connectionDetails.Stream, connectionDetails.TcpClient, connectionDetails.Header, _logger, m_Sessions, m_Dirs, m_Queue, m_Users, m_Downloads);
                    pWS.OnQueueUpdate += m_WebServer.HandleEvent;
                    return(pWS);
                }
                if (connectionDetails.Path == "/admin")
                {
                    MOTR_AdminWebsocket pWS = new MOTR_AdminWebsocket(connectionDetails.Stream, connectionDetails.TcpClient, connectionDetails.Header, _logger, m_Sessions, m_Dirs, m_Users, m_Admin);
                    pWS.OnRestartWebserver += this.OnRestartWebserver;
                    return(pWS);
                }
                break;

            case ConnectionType.Http:
                // this path actually refers to the reletive location of some html file or image
                string extension = connectionDetails.Path;
                //_logger.Information(this.GetType(), "Header: {0}", connectionDetails.Header);
                //_logger.Information(this.GetType(), "Path: {0}", connectionDetails.Path);
                if (extension.Length > 4)
                {
                    extension = extension.Substring(extension.Length - 4);
                    extension = extension.ToUpper();

                    string sIP = connectionDetails.TcpClient.Client.RemoteEndPoint.ToString();
                    //_logger.Information(this.GetType(), "IP adress: {0}", sIP);
                }

                //Special extension for our file
                if (extension == "MOTR" || extension == "LOAD")
                {
                    //_logger.Information(this.GetType(), "Handling MOTR or LOAD: " + extension);

                    //Sjekk at brukeren er logget inn (SessionID = gullgutten), TempID er for å sette gullgutten ;)
                    string sSessionID = GetCookie(connectionDetails.Header, "SessionID");
                    if (sSessionID.Length > 0)
                    {
                        if (!m_Sessions.SessionLoggedIn(sSessionID, "[WEBBASEDAUTH, NOT USER]"))
                        {
                            return(new HttpRedirectService(connectionDetails.Stream, "/", connectionDetails.Path, "[DELETE]", _logger));
                        }
                        else if (GetCookie(connectionDetails.Header, "TempID").Length > 0)
                        {
                            return(new HttpRedirectService(connectionDetails.Stream, connectionDetails.Path, connectionDetails.Path, sSessionID, _logger));
                        }
                    }
                    else     //Just forward when we don't have any session
                    {
                        string sTempID = GetCookie(connectionDetails.Header, "TempID");
                        if (sTempID.Length == 0)
                        {
                            return(new HttpRedirectService(connectionDetails.Stream, "/", connectionDetails.Path, "", _logger));
                        }
                        else
                        {
                            //Get the session, if it is real, set the session to login
                            sSessionID = m_Sessions.GetSessionByTempID(sTempID);
                            if (sSessionID.Length == 0)
                            {
                                return(new HttpRedirectService(connectionDetails.Stream, "/", connectionDetails.Path, "", _logger));
                            }
                            else
                            {
                                return(new HttpRedirectService(connectionDetails.Stream, connectionDetails.Path, connectionDetails.Path, sSessionID, _logger));
                            }
                        }
                    }

                    //Sjekk om det er utlogging som skal foregå
                    bool bRemoveCookies = false;
                    if (connectionDetails.Path.ToUpper().Contains("LOGOFF.MOTR"))
                    {
                        //Slett sesjonen fra listen, la parseren håndtere resten
                        m_Sessions.RemoveSession(sSessionID);
                        bRemoveCookies = true;
                    }

                    //Her skal vi parse fila før vi sender avgårde html'n...
                    if (extension == "MOTR")     //Ignore if we are going to remove cookies, normally logging out
                    {
                        MOTR_Parser m_Parser = new MOTR_Parser(_logger, sSessionID, m_Sessions);
                        return(new HttpTextService(connectionDetails.Stream, m_Parser.ParseFile(_webRoot + connectionDetails.Path), _logger, bRemoveCookies));
                    }
                    else     //Handling "DOWN.LOAD"
                    {
                        string[] aTemp = connectionDetails.Path.Split('/');
                        if (aTemp.Count() > 0)
                        {
                            string nID   = aTemp[1];
                            string sPath = m_Sessions.GetTemporaryVariable(sSessionID, "DrivePosition");
                            string sFile = m_Sessions.GetPathByID(sSessionID, Convert.ToInt32(nID));

                            string sOneHour    = DateTime.Now.AddHours(1).ToString();
                            string sDownloadID = m_Downloads.AddDownload(sSessionID, sPath + sFile, false, sOneHour);

                            return(new HttpRedirectService(connectionDetails.Stream, "/MOTR-download/" + sDownloadID + "/" + sFile, "", "", _logger));
                        }
                        else
                        {
                            return(new HttpTextService(connectionDetails.Stream, "Did not provide correct nID for file", _logger));
                        }
                    }
                }

                //Here we handle the tag "/motr-download/" to ensure we download the file binary
                if (connectionDetails.Path.Contains("/MOTR-download/"))
                {
                    //Check if we have a session (This blocks several clients, temp disabled)
                    //string sSessionID = GetCookie(connectionDetails.Header, "SessionID");
                    //if(sSessionID.Length == 0)
                    //    return new HttpTextService(connectionDetails.Stream, "Session is no longer valid, unable to download", _logger);

                    string[] aDownloads  = connectionDetails.Path.Split('/');
                    string   sDownloadID = "";
                    if (aDownloads.Count() > 2)
                    {
                        sDownloadID = aDownloads[2];
                    }
                    if (sDownloadID.Length > 0)
                    {
                        //Get the filename
                        //string sFileName = connectionDetails.Path.Substring(connectionDetails.Path.LastIndexOf('/') + 1);
                        string sFileName = m_Downloads.GetDownload(sDownloadID);

                        //No filename, no love...
                        if (sFileName.Length == 0)
                        {
                            _logger.Warning(typeof(MOTR_WebserverFactory), "Download is no longer valid...");
                            return(new BadRequestService(connectionDetails.Stream, connectionDetails.Header, _logger));
                        }

                        sFileName = Uri.UnescapeDataString(sFileName);



                        if (connectionDetails != null)
                        {
                            if (connectionDetails.Header != null)
                            {
                                _logger.Debug(typeof(MOTR_WebserverFactory), "MOTR-download: " + WebUtility.HtmlDecode(connectionDetails.Header));
                            }
                        }

                        //This is where the file actually is
                        //string sBasePath = m_Sessions.GetTemporaryVariable(sSessionID, "DrivePosition");
                        //return new HttpBinaryService(connectionDetails.Stream, sBasePath + sFileName, _logger);
                        return(new HttpBinaryService(connectionDetails.Stream, sFileName, _webRoot, connectionDetails.Header, _logger));
                    }
                }                                                   //END: /MOTR-download
                else if (connectionDetails.Path.Contains("/kodi/")) //Kodi directory is special
                {
                    extension = extension.ToUpper();
                    if (extension == ".ZIP")
                    {
                        return(new HttpBinaryService(connectionDetails.Stream, _webRoot + connectionDetails.Path, _webRoot, connectionDetails.Header, _logger));
                    }
                }
                else if (connectionDetails.Path.Contains("/MovieInfo/"))     //Kodi directory is special
                {
                    int    nSlashPos  = connectionDetails.Path.LastIndexOf('/');
                    string sImageName = connectionDetails.Path.Substring(nSlashPos, connectionDetails.Path.Length - (nSlashPos));
                    sImageName = sImageName.Substring(1, sImageName.Length - 1);
                    sImageName = sImageName.Replace("..", "");
                    sImageName = sImageName.Replace("%", "");
                    string movieInfoPath = MOTR_Settings.GetGlobalApplicationPath("MovieImages");
                    return(new HttpBinaryService(connectionDetails.Stream, movieInfoPath + sImageName, _webRoot, connectionDetails.Header, _logger));
                }    //Redirect to front page on initalsetup

                if (connectionDetails.Path.Contains("/initalsetup/"))
                {
                    return(new HttpRedirectService(connectionDetails.Stream, "/", connectionDetails.Path, "", _logger));
                }

                //Everything else is served here (but limited to the mimelist...)
                return(new HttpService(connectionDetails.Stream, connectionDetails.Path, _webRoot, _logger));


            case ConnectionType.Head:
                //Only handle MOTR-download on head requests
                //_logger.Information(typeof(MOTR_WebserverFactory), "HEAD: " + connectionDetails.Header);
                if (connectionDetails.Path.Contains("/MOTR-download/"))
                {
                    string[] aDownloads  = connectionDetails.Path.Split('/');
                    string   sDownloadID = "";
                    if (aDownloads.Count() > 2)
                    {
                        sDownloadID = aDownloads[2];
                    }
                    if (sDownloadID.Length > 0)
                    {
                        string sFileName = m_Downloads.GetDownload(sDownloadID, true);
                        return(new HttpBinaryService(connectionDetails.Stream, sFileName, _webRoot, connectionDetails.Header, _logger, true));    //True is head only!
                    }
                }
                else if (connectionDetails.Path.Contains("/kodi/"))                                                                                                //Kodi directory is special
                {
                    return(new HttpBinaryService(connectionDetails.Stream, _webRoot + connectionDetails.Path, _webRoot, connectionDetails.Header, _logger, true)); //True is head only!
                }
                else if (connectionDetails.Path.Contains("/MovieInfo/"))                                                                                           //Kodi directory is special
                {
                    int    nSlashPos  = connectionDetails.Path.LastIndexOf('/');
                    string sImageName = connectionDetails.Path.Substring(nSlashPos, connectionDetails.Path.Length - (nSlashPos));
                    sImageName = sImageName.Substring(1, sImageName.Length - 1);
                    sImageName = sImageName.Replace("..", "");
                    sImageName = sImageName.Replace("%", "");
                    string movieInfoPath = MOTR_Settings.GetGlobalApplicationPath("MovieImages");
                    return(new HttpBinaryService(connectionDetails.Stream, movieInfoPath + sImageName, _webRoot, connectionDetails.Header, _logger, true)); //True is head only!
                }                                                                                                                                           //Redirect to front page on initalsetup

                _logger.Warning(typeof(MOTR_WebserverFactory), "Head requested, not supported for all paths: " + connectionDetails.Header);
                return(new BadRequestService(connectionDetails.Stream, connectionDetails.Header, _logger));
                //return new HttpTextService(connectionDetails.Stream, "HEAD is not supported", _logger);
            }

            return(new BadRequestService(connectionDetails.Stream, connectionDetails.Header, _logger));
        }