Пример #1
0
        public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
        {
            string pageLower = p.requestedPage.ToLower();

            if (pageLower.StartsWith("api/"))
            {
                string cmd = p.requestedPage.Substring("api/".Length);
                switch (cmd)
                {
                case "getBandwidthRecords":
                {
                    JSAPI.APIResponse response;
                    long lastTime = p.GetLongParam("time");
                    if (lastTime == 0)
                    {
                        response = new JSAPI.BandwidthRecordsResponse(routerReader.GetAllRecordsFromAllDevices());
                    }
                    else
                    {
                        response = new JSAPI.BandwidthRecordsResponse(routerReader.GetNewRecordsFromAllDevices(lastTime));
                    }
                    p.CompressResponseIfCompatible();
                    p.writeSuccess("application/json");
                    p.outputStream.Write(JsonConvert.SerializeObject(response));
                }
                break;
                }
            }
        }
Пример #2
0
        public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
        {
            string pageLower = p.requestedPage.ToLower();

            if (pageLower.StartsWith("api/"))
            {
                string cmd = p.requestedPage.Substring("api/".Length);
                switch (cmd)
                {
                case "uploadUsageRecord1":
                case "uploadUsageRecord2":
                {
                    // If this needs extended in the future, just make a new "case" with an incremented number.
                    string allUploaded = inputData.ReadToEnd();
                    if (allUploaded.Length < 33)
                    {
                        return;
                    }
                    string md5 = allUploaded.Substring(allUploaded.Length - 32).ToLower();
                    allUploaded = allUploaded.Remove(allUploaded.Length - 32);
                    string md5Verify = Hash.GetMD5Hex(allUploaded);
                    if (md5 != md5Verify)
                    {
                        p.writeFailure("400 Bad Request");
                        return;
                    }
                    UsageRecordUpload.v2.Upload_Record record = JsonConvert.DeserializeObject <UsageRecordUpload.v2.Upload_Record>(allUploaded);
                    DB.Agent.AddUsageRecord(record);
                    p.writeSuccess("text/plain", 0);
                }
                break;

                case "getUsageRecords":
                {
                    JSAPI.APIResponse response;
                    int detailsForId = p.GetIntParam("detailsForId", -1);
                    if (detailsForId > -1)
                    {
                        UsageRecord record = Agent.GetUsageRecord(detailsForId);
                        if (record == null)
                        {
                            response = new JSAPI.APIResponse("Could not find record \"" + detailsForId + "\"");
                        }
                        else
                        {
                            List <Camera>  cameras = Agent.GetCameras(record.ID);
                            List <GpuInfo> gpus    = Agent.GetGpus(record.ID);
                            response = new JSAPI.DetailedRecordResponse(record, cameras, gpus);
                            if (IsAdmin(p))
                            {
                                JSAPI.DetailedRecordResponse response2 = (JSAPI.DetailedRecordResponse)response;
                                response2.secret = response2.usage.Secret;
                            }
                        }
                    }
                    else
                    {
                        response = new JSAPI.AllUsageRecordsResponse(Agent.GetAllUsageRecords_TimestampDesc());
                        if (IsAdmin(p))
                        {
                            JSAPI.AllUsageRecordsResponse response2 = (JSAPI.AllUsageRecordsResponse)response;
                            response2.secrets = response2.records.Select(r => new UsageRecord_Secret_Map()
                                {
                                    ID = r.ID, Secret = r.Secret
                                });
                        }
                    }
                    byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(response));
                    p.CompressResponseIfCompatible();
                    List <KeyValuePair <string, string> > additionalHeaders = new List <KeyValuePair <string, string> >();
                    additionalHeaders.Add(new KeyValuePair <string, string>("Cache-Control", "no-cache, no-store"));
                    p.writeSuccess("application/json", additionalHeaders: additionalHeaders);
                    p.outputStream.Flush();
                    p.tcpStream.Write(data, 0, data.Length);
                    p.tcpStream.Flush();
                }
                break;

                case "deleteRecord":
                {
                    JSAPI.APIResponse response;
                    if (!IsAdmin(p))
                    {
                        response = new JSAPI.APIResponse("Unauthorized");
                    }
                    else
                    {
                        int id = p.GetIntParam("id", -1);
                        if (id < 0)
                        {
                            response = new JSAPI.APIResponse("Invalid ID");
                        }
                        else
                        {
                            bool success = Agent.DeleteUsageRecord(id);
                            if (success)
                            {
                                response = new JSAPI.APIResponse();
                            }
                            else
                            {
                                response = new JSAPI.APIResponse("Failed to delete record");
                            }
                        }
                    }
                    byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(response));
                    p.writeSuccess("application/json", data.Length);
                    p.outputStream.Flush();
                    p.tcpStream.Write(data, 0, data.Length);
                    p.tcpStream.Flush();
                }
                break;
                }
            }
        }
Пример #3
0
        public override void handleGETRequest(HttpProcessor p)
        {
            try
            {
                string requestedPage = Uri.UnescapeDataString(p.request_url.AbsolutePath.TrimStart('/'));

                if (requestedPage == "admin")
                {
                    p.writeRedirect("admin/main");
                    return;
                }

                if (requestedPage == "login")
                {
                    LogOutUser(p, null);
                    return;
                }

                Session s = sm.GetSession(p.requestCookies.GetValue("cps"), p.requestCookies.GetValue("auth"), p.GetParam("rawauth"));
                if (s.sid != null && s.sid.Length == 16)
                {
                    p.responseCookies.Add("cps", s.sid, TimeSpan.FromMinutes(s.sessionLengthMinutes));
                }

                if (requestedPage == "logout")
                {
                    LogOutUser(p, s);
                    return;
                }


                if (requestedPage.StartsWith("admin/"))
                {
                    string adminPage = requestedPage == "admin" ? "" : requestedPage.Substring("admin/".Length);
                    if (string.IsNullOrWhiteSpace(adminPage))
                    {
                        adminPage = "main";
                    }
                    int idxQueryStringStart = adminPage.IndexOf('?');
                    if (idxQueryStringStart == -1)
                    {
                        idxQueryStringStart = adminPage.Length;
                    }
                    adminPage = adminPage.Substring(0, idxQueryStringStart);
                    Pages.Admin.AdminPage.HandleRequest(adminPage, p, s);
                    return;
                }
                else if (requestedPage.StartsWith("image/"))
                {
                    requestedPage = requestedPage.Substring("image/".Length);
                    #region image/
                    if (requestedPage.EndsWith(".jpg") || requestedPage.EndsWith(".jpeg") || requestedPage.EndsWith(".png") || requestedPage.EndsWith(".webp"))
                    {
                        int    extensionLength = requestedPage[requestedPage.Length - 4] == '.' ? 4 : 5;
                        string format          = requestedPage.Substring(requestedPage.Length - (extensionLength - 1));
                        string cameraId        = requestedPage.Substring(0, requestedPage.Length - extensionLength);
                        cameraId = cameraId.ToLower();

                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            LogOutUser(p, s);
                            return;
                        }
                        int          wait        = p.GetIntParam("wait", 5000);
                        IPCameraBase cam         = cm.GetCamera(cameraId);
                        byte[]       latestImage = cm.GetLatestImage(cameraId, wait);
                        int          patience    = p.GetIntParam("patience");
                        if (patience > 0)
                        {
                            if (patience > 5000)
                            {
                                patience = 5000;
                            }

                            int timeLeft = patience;
                            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
                            timer.Start();
                            while (s.DuplicateImageSendCheck(cameraId, latestImage) && cam != null && timeLeft > 0)
                            {
                                // The latest image was already sent to the user in a previous image request.
                                // Wait for up to 5 seconds as desired by the user to get a "new" image.
                                cam.newFrameWaitHandle.WaitOne(Math.Max(50, timeLeft));                                  // This EventWaitHandle nonsense isn't perfect, so this should prevent excessively long delays in the event of a timing error.
                                latestImage = cm.GetLatestImage(cameraId);
                                timeLeft    = patience - (int)timer.ElapsedMilliseconds;
                            }
                        }
                        if (latestImage.Length == 0)
                        {
                            p.writeFailure("502 Bad Gateway");
                            return;
                        }
                        ImageFormat imgFormat = ImageFormat.Jpeg;
                        latestImage = ImageConverter.HandleRequestedConversionIfAny(latestImage, p, ref imgFormat, format);
                        p.tcpClient.SendBufferSize = latestImage.Length + 256;
                        p.writeSuccess(Util.GetMime(imgFormat), latestImage.Length);
                        p.outputStream.Flush();
                        p.tcpStream.Write(latestImage, 0, latestImage.Length);
                    }
                    else if (requestedPage.EndsWith(".mjpg"))
                    {
                        string cameraId = requestedPage.Substring(0, requestedPage.Length - 5);
                        cameraId = cameraId.ToLower();
                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            LogOutUser(p, s);
                            return;
                        }
                        if (cm.GetLatestImage(cameraId).Length == 0)
                        {
                            return;
                        }
                        // Increasing the send buffer size here does not help streaming fluidity.
                        p.writeSuccess("multipart/x-mixed-replace;boundary=ipcamera");
                        byte[] newImage;
                        byte[] lastImage = null;
                        while (!this.stopRequested)
                        {
                            try
                            {
                                newImage = cm.GetLatestImage(cameraId);
                                while (newImage == lastImage)
                                {
                                    Thread.Sleep(1);
                                    newImage = cm.GetLatestImage(cameraId);
                                    if (this.stopRequested)
                                    {
                                        return;
                                    }
                                }
                                lastImage = newImage;

                                ImageFormat imgFormat = ImageFormat.Jpeg;
                                byte[]      sendImage = ImageConverter.HandleRequestedConversionIfAny(newImage, p, ref imgFormat);

                                p.outputStream.WriteLine("--ipcamera");
                                p.outputStream.WriteLine("Content-Type: " + Util.GetMime(imgFormat));
                                p.outputStream.WriteLine("Content-Length: " + sendImage.Length);
                                p.outputStream.WriteLine();
                                p.outputStream.Flush();
                                p.tcpStream.Write(sendImage, 0, sendImage.Length);
                                p.tcpStream.Flush();
                                p.outputStream.WriteLine();
                            }
                            catch (Exception ex)
                            {
                                if (!p.isOrdinaryDisconnectException(ex))
                                {
                                    Logger.Debug(ex);
                                }
                                break;
                            }
                        }
                    }
                    else if (requestedPage.EndsWith(".ogg"))
                    {
                        string cameraId = requestedPage.Substring(0, requestedPage.Length - 4);
                        cameraId = cameraId.ToLower();
                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            LogOutUser(p, s);
                            return;
                        }
                        IPCameraBase _cam = cm.GetCamera(cameraId);
                        if (_cam is Html5VideoCamera)
                        {
                            Html5VideoCamera         cam            = (Html5VideoCamera)_cam;
                            ConcurrentQueue <byte[]> myDataListener = new ConcurrentQueue <byte[]>();
                            try
                            {
                                cam.RegisterStreamListener(myDataListener);
                                p.writeSuccess("application/octet-stream");
                                p.outputStream.Flush();
                                byte[] outputBuffer;
                                int    chunkCount = 0;
                                while (!this.stopRequested)
                                {
                                    try
                                    {
                                        chunkCount = myDataListener.Count;
                                        if (chunkCount > 100)
                                        {
                                            return;                                             // This connection is falling too far behind.  End it.
                                        }
                                        else if (chunkCount > 0)
                                        {
                                            Console.Write(chunkCount + " ");
                                            if (myDataListener.TryDequeue(out outputBuffer))
                                            {
                                                p.tcpStream.Write(outputBuffer, 0, outputBuffer.Length);
                                                p.tcpStream.Flush();
                                            }
                                        }
                                        else
                                        {
                                            Thread.Sleep(1);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        if (!p.isOrdinaryDisconnectException(ex))
                                        {
                                            Logger.Debug(ex);
                                        }
                                        break;
                                    }
                                }
                            }
                            finally
                            {
                                cam.UnregisterStreamListener(myDataListener);
                            }
                        }
                        else
                        {
                            p.writeFailure("501 Not Implemented");
                        }
                    }
                    else if (requestedPage.EndsWith(".cam"))
                    {
                        string cameraId = requestedPage.Substring(0, requestedPage.Length - 4);
                        cameraId = cameraId.ToLower();
                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            LogOutUser(p, s);
                            return;
                        }
                        IPCameraBase cam = cm.GetCamera(cameraId);
                        if (cam != null && cam.cameraSpec.ptzType == MJpegCameraProxy.Configuration.PtzType.Dahua || cam.cameraSpec.ptzType == MJpegCameraProxy.Configuration.PtzType.Hikvision)
                        {
                            p.writeRedirect("../Camera.html?cam=" + cameraId);
                            return;
                        }

                        string userAgent = p.GetHeaderValue("User-Agent", "");
                        bool   isMobile  = userAgent.Contains("iPad") || userAgent.Contains("iPhone") || userAgent.Contains("Android") || userAgent.Contains("BlackBerry");

                        bool   isLanConnection = p == null ? false : p.IsLanConnection;
                        int    defaultRefresh  = isLanConnection && !isMobile ? -1 : 250;
                        string html            = CamPage.GetHtml(cameraId, !isMobile, p.GetIntParam("refresh", defaultRefresh), p.GetBoolParam("override") ? -1 : 600000, p);
                        if (string.IsNullOrEmpty(html) || html == "NO")
                        {
                            p.writeFailure();
                            return;
                        }
                        HttpCompressionBody response = new HttpCompressionBody(Encoding.UTF8.GetBytes(html), ".html", p.GetHeaderValue("accept-encoding"));
                        p.writeSuccess(contentLength: response.body.Length, additionalHeaders: response.additionalHeaders);
                        p.outputStream.Flush();
                        p.tcpStream.Write(response.body, 0, response.body.Length);
                    }
                    else if (requestedPage == "PTZPRESETIMG")
                    {
                        string cameraId = p.GetParam("id");
                        cameraId = cameraId.ToLower();
                        IPCameraBase cam = cm.GetCamera(cameraId);
                        if (cam != null)
                        {
                            int index = p.GetIntParam("index", -1);
                            if (index > -1)
                            {
                                if (cam.cameraSpec.ptz_proxy)
                                {
                                    string auth = (!string.IsNullOrEmpty(cam.cameraSpec.ptz_username) && !string.IsNullOrEmpty(cam.cameraSpec.ptz_password)) ? "rawauth=" + HttpUtility.UrlEncode(cam.cameraSpec.ptz_username) + ":" + HttpUtility.UrlEncode(cam.cameraSpec.ptz_password) + "&" : "";
                                    byte[] data = SimpleProxy.GetData("http://" + cam.cameraSpec.ptz_hostName + "/PTZPRESETIMG?" + auth + "id=" + HttpUtility.UrlEncode(cam.cameraSpec.ptz_proxy_cameraId) + "&index=" + index);
                                    if (data.Length > 0)
                                    {
                                        p.writeSuccess("image/jpg", data.Length);
                                        p.outputStream.Flush();
                                        p.tcpStream.Write(data, 0, data.Length);
                                        return;
                                    }
                                }
                                else
                                {
                                    string fileName      = CameraProxyGlobals.ThumbsDirectoryBase + cameraId + index + ".jpg";
                                    int    minPermission = cm.GetCameraMinPermission(cameraId);
                                    if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission) || minPermission == 101)
                                    {
                                    }
                                    else
                                    {
                                        if (File.Exists(fileName))
                                        {
                                            byte[] bytes = File.ReadAllBytes(fileName);
                                            p.writeSuccess("image/jpg", bytes.Length);
                                            p.outputStream.Flush();
                                            p.tcpStream.Write(bytes, 0, bytes.Length);
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                        {                         // Failed to get image thumbnail
                            byte[] bytes = File.ReadAllBytes(CameraProxyGlobals.WWWPublicDirectoryBase + "Images/qmark.png");
                            p.writeSuccess("image/png", bytes.Length);
                            p.outputStream.Flush();
                            p.tcpStream.Write(bytes, 0, bytes.Length);
                            return;
                        }
                    }
                    else if (requestedPage.EndsWith(".wanscamstream"))
                    {
                        string       cameraId = requestedPage.Substring(0, requestedPage.Length - ".wanscamstream".Length);
                        IPCameraBase cam      = cm.GetCamera(cameraId);
                        if (cam == null)
                        {
                            return;
                        }
                        if (!cam.cameraSpec.wanscamCompatibilityMode)
                        {
                            return;
                        }
                        if (p.RemoteIPAddressStr != "127.0.0.1")
                        {
                            return;
                        }
                        Uri    url  = new Uri(cam.cameraSpec.imageryUrl);
                        string host = url.Host;
                        int    port = url.Port;
                        string path = url.PathAndQuery;
                        //string path = "/livestream.cgi?user=admin&pwd=nooilwell&streamid=0&audio=0&filename=";
                        //string path = "/videostream.cgi?user=admin&pwd=nooilwell&resolution=8";
                        int total = 0;
                        try
                        {
                            //Console.WriteLine("opening");
                            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            socket.Connect(host, port);
                            byte[] buffer = new byte[4096];
                            socket.Send(UTF8Encoding.UTF8.GetBytes("GET " + path + " HTTP/1.1\r\nHost: " + host + ":" + port + "\r\nConnection: close\r\n\r\n"));
                            //Console.WriteLine("open");
                            int read = socket.Receive(buffer);
                            p.writeSuccess("video/raw");
                            p.outputStream.Flush();
                            while (read > 0 && socket.Connected && p.tcpClient.Connected)
                            {
                                p.tcpStream.Write(buffer, 0, read);
                                total += read;
                                //Console.WriteLine(read);
                                read = socket.Receive(buffer);
                            }
                            //Console.WriteLine("close");
                        }
                        catch (Exception ex)
                        {
                            if (!p.isOrdinaryDisconnectException(ex))
                            {
                                Logger.Debug(ex);
                            }
                        }
                    }
                    #endregion
                }
                else if (requestedPage.StartsWith("control/"))
                {
                    requestedPage = requestedPage.Substring("control/".Length);
                    #region control/
                    if (requestedPage == "keepalive")
                    {
                        string cameraId = p.GetParam("id");
                        cameraId = cameraId.ToLower();
                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            p.writeFailure("403 Forbidden");
                            return;
                        }
                        cm.GetRTSPUrl(cameraId, p);
                        p.writeSuccess("text/plain");
                        p.outputStream.Write("1");
                    }

                    else if (requestedPage == "PTZ")
                    {
                        string cameraId = p.GetParam("id");
                        cameraId = cameraId.ToLower();
                        int minPermission = cm.GetCameraMinPermission(cameraId);
                        if (minPermission == 101)
                        {
                            p.writeFailure();
                            return;
                        }
                        if ((s == null && minPermission > 0) || (s != null && s.permission < minPermission))
                        {
                            LogOutUser(p, s);
                            return;
                        }
                        PTZ.RunCommand(cameraId, p.GetParam("cmd"));
                        p.writeSuccess("text/plain");
                    }
                    #endregion
                }
                else if (requestedPage.StartsWith(".well-known/acme-challenge/"))
                {
                    string token = requestedPage.Substring(".well-known/acme-challenge/".Length);
                    string response;
                    if (letsEncryptChallenges.TryGetValue(token, out response))
                    {
                        p.writeSuccess("text/plain");
                        p.outputStream.Flush();
                        byte[] buf = Encoding.ASCII.GetBytes(response);
                        p.tcpStream.Write(buf, 0, buf.Length);
                    }
                    else
                    {
                        p.writeFailure();
                    }
                }
                else
                {
                    #region www
                    int permissionRequired;
                    if (!Util.TryGetValue(requestedPage.ToLower(), MJpegWrapper.cfg.GetWwwFilesList(), out permissionRequired))
                    {
                        permissionRequired = -1;
                    }


                    string wwwDirectory = permissionRequired == -1 ? CameraProxyGlobals.WWWPublicDirectoryBase : CameraProxyGlobals.WWWDirectoryBase;

                    if (permissionRequired < 0)
                    {
                        permissionRequired = 0;
                    }
                    else if (permissionRequired > 100)
                    {
                        permissionRequired = 100;
                    }

                    if (permissionRequired > s.permission)
                    {
                        LogOutUser(p, s);
                        return;
                    }

                    DirectoryInfo WWWDirectory     = new DirectoryInfo(wwwDirectory);
                    string        wwwDirectoryBase = WWWDirectory.FullName.Replace('\\', '/').TrimEnd('/') + '/';
                    FileInfo      fi             = new FileInfo(wwwDirectoryBase + requestedPage);
                    string        targetFilePath = fi.FullName.Replace('\\', '/');
                    if (!targetFilePath.StartsWith(wwwDirectoryBase) || targetFilePath.Contains("../"))
                    {
                        p.writeFailure("400 Bad Request");
                        return;
                    }
                    if (!fi.Exists)
                    {
                        p.writeFailure();
                        return;
                    }

                    // && (fi.Extension == ".html" || fi.Extension == ".htm")
                    if (fi.Name.ToLower() == "camera.html" && fi.Length < 256000)
                    {
                        string   html = File.ReadAllText(fi.FullName);
                        CamPage2 cp   = new CamPage2(html, p);
                        html = cp.Html;
                        html = html.Replace("%ALLCAMS%", string.Join(",", MJpegServer.cm.GenerateAllCameraIdList()));
                        html = html.Replace("%ALLCAMS_IDS_NAMES_JS_ARRAY%", MJpegServer.cm.GenerateAllCameraIdNameList(s == null ? 0 : s.permission));
                        try
                        {
                            html = html.Replace("%REMOTEIP%", p.RemoteIPAddressStr);
                        }
                        catch (Exception ex)
                        {
                            Logger.Debug(ex);
                        }
                        HttpCompressionBody response = new HttpCompressionBody(Encoding.UTF8.GetBytes(html), ".html", p.GetHeaderValue("accept-encoding"));
                        p.writeSuccess(Mime.GetMimeType(fi.Extension), response.body.Length, additionalHeaders: response.additionalHeaders);
                        p.outputStream.Flush();
                        p.tcpStream.Write(response.body, 0, response.body.Length);
                    }
                    else if ((fi.Extension == ".html" || fi.Extension == ".htm") && fi.Length < 256000)
                    {
                        string html = File.ReadAllText(fi.FullName);
                        html = html.Replace("%ALLCAMS%", string.Join(",", MJpegServer.cm.GenerateAllCameraIdList()));
                        html = html.Replace("%ALLCAMS_IDS_NAMES_JS_ARRAY%", MJpegServer.cm.GenerateAllCameraIdNameList(s == null ? 0 : s.permission));
                        try
                        {
                            html = html.Replace("%REMOTEIP%", p.RemoteIPAddressStr);
                        }
                        catch (Exception ex)
                        {
                            Logger.Debug(ex);
                        }
                        HttpCompressionBody response = new HttpCompressionBody(Encoding.UTF8.GetBytes(html), ".html", p.GetHeaderValue("accept-encoding"));
                        p.writeSuccess(Mime.GetMimeType(fi.Extension), response.body.Length, additionalHeaders: response.additionalHeaders);
                        p.outputStream.Flush();
                        p.tcpStream.Write(response.body, 0, response.body.Length);
                    }
                    else
                    {
                        if (fi.Length < 1000000)
                        {
                            HttpCompressionBody response = new HttpCompressionBody(File.ReadAllBytes(fi.FullName), fi.Extension, p.GetHeaderValue("accept-encoding"));
                            p.writeSuccess(Mime.GetMimeType(fi.Extension), response.body.Length, additionalHeaders: response.additionalHeaders);
                            p.outputStream.Flush();
                            p.tcpStream.Write(response.body, 0, response.body.Length);
                        }
                        else
                        {
                            if (HttpCompressionHelper.FileTypeShouldBeCompressed(fi.Extension))
                            {
                                p.CompressResponseIfCompatible();
                            }
                            List <KeyValuePair <string, string> > additionalHeaders = new List <KeyValuePair <string, string> >();
                            additionalHeaders.Add(new KeyValuePair <string, string>("Cache-Control", "max-age=3600, public"));
                            p.writeSuccess(Mime.GetMimeType(fi.Extension), additionalHeaders: additionalHeaders);
                            p.outputStream.Flush();
                            using (FileStream fs = fi.OpenRead())
                            {
                                fs.CopyTo(p.tcpStream);
                            }
                            p.tcpStream.Flush();
                        }
                    }
                    #endregion
                }
            }
            catch (Exception ex)
            {
                if (!p.isOrdinaryDisconnectException(ex))
                {
                    Logger.Debug(ex);
                }
            }
        }
Пример #4
0
        public override void handleGETRequest(HttpProcessor p)
        {
            string pageLower = p.requestedPage.ToLower();

            if (pageLower.StartsWith("api/"))
            {
                p.writeFailure("405 Method Not Allowed");
            }
            else if (p.requestedPage == "")
            {
                p.writeRedirect("default.html");
            }
            else if (p.requestedPage == "TEST")
            {
                StringBuilder sb = new StringBuilder();
                p.writeSuccess("text/plain");
                p.outputStream.Write(string.Join(", ", Process.GetProcessesByName("svchost").Select(i => ProcessHelper.GetUserWhichOwnsProcess(i.Id))));
            }
            else
            {
                string wwwPath = Globals.ApplicationDirectoryBase + "www/";
#if DEBUG
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    wwwPath = Globals.ApplicationDirectoryBase + "../../www/";
                }
#endif
                DirectoryInfo WWWDirectory     = new DirectoryInfo(wwwPath);
                string        wwwDirectoryBase = WWWDirectory.FullName.Replace('\\', '/').TrimEnd('/') + '/';
                FileInfo      fi             = new FileInfo(wwwDirectoryBase + p.requestedPage);
                string        targetFilePath = fi.FullName.Replace('\\', '/');
                if (!targetFilePath.StartsWith(wwwDirectoryBase) || targetFilePath.Contains("../"))
                {
                    p.writeFailure("400 Bad Request");
                    return;
                }
                if (!fi.Exists)
                {
                    return;
                }
                if ((fi.Extension == ".html" || fi.Extension == ".htm") && fi.Length < 256000)
                {
                    string html = File.ReadAllText(fi.FullName);
                    html = html.Replace("%%VERSION%%", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
                    html = html.Replace("%%RND%%", rnd.ToString());

                    byte[] data = Encoding.UTF8.GetBytes(html);
                    if (!p.GetBoolParam("nocompress"))
                    {
                        p.CompressResponseIfCompatible();
                    }
                    p.writeSuccess(Mime.GetMimeType(fi.Extension));
                    p.outputStream.Flush();
                    p.tcpStream.Write(data, 0, data.Length);
                    p.tcpStream.Flush();
                }
                else
                {
                    string mime = Mime.GetMimeType(fi.Extension);
                    if (pageLower.StartsWith(".well-known/acme-challenge/"))
                    {
                        mime = "text/plain";
                    }
                    if (fi.LastWriteTimeUtc.ToString("R") == p.GetHeaderValue("if-modified-since"))
                    {
                        p.writeSuccess(mime, -1, "304 Not Modified");
                        return;
                    }
                    if (!p.GetBoolParam("nocompress"))
                    {
                        p.CompressResponseIfCompatible();
                    }
                    p.writeSuccess(mime, additionalHeaders: GetCacheLastModifiedHeaders(TimeSpan.FromHours(1), fi.LastWriteTimeUtc));
                    p.outputStream.Flush();
                    using (FileStream fs = fi.OpenRead())
                    {
                        fs.CopyTo(p.tcpStream);
                    }
                    p.tcpStream.Flush();
                }
            }
        }
Пример #5
0
        public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
        {
            string pageLower = p.requestedPage.ToLower();

            if (pageLower.StartsWith("api/"))
            {
                JSAPI.APIResponse apiResponse = null;
                string            cmd         = p.requestedPage.Substring("api/".Length);
                if (cmd.StartsWith("PerformanceCounterCategoryDetails/"))
                {
                    string name = Uri.UnescapeDataString(cmd.Substring("PerformanceCounterCategoryDetails/".Length));
                    try
                    {
                        PerformanceCounterCategory cat = new PerformanceCounterCategory(name);
                        apiResponse = new CategoryDetailsResponse(cat);
                    }
                    catch (Exception ex)
                    {
                        apiResponse = new APIResponse(ex.ToString());
                    }
                }
                else
                {
                    switch (cmd)
                    {
                    case "getCounterRecords":
                    {
                        JSAPI.PerfDataRecordsResponse response = new JSAPI.PerfDataRecordsResponse();
                        response.machineName = Environment.MachineName;
                        lock (managersLock)
                        {
                            response.collections = new List <PerfMonValueCollection>(managers.Length);

                            long time = p.GetLongParam("time");
                            for (int i = 0; i < managers.Length; i++)
                            {
                                response.collections.Add(new PerfMonValueCollection(managers[i], time));
                            }
                        }
                        apiResponse = response;
                    }
                    break;

                    case "getPerformanceCounterCategories":
                    {
                        PerformanceCounterCategory[] categories = PerformanceCounterCategory.GetCategories();
                        PerfDataCategoriesResponse   response   = new PerfDataCategoriesResponse();
                        response.categories = new List <PerfDataCategory>();
                        foreach (PerformanceCounterCategory c in categories)
                        {
                            try
                            {
                                response.categories.Add(new PerfDataCategory(c));
                            }
                            catch { }
                        }
                        response.categories.Sort(new Comparison <PerfDataCategory>((a, b) => string.Compare(a.name, b.name)));
                        apiResponse = response;
                    }
                    break;
                    }
                }
                if (!p.GetBoolParam("nocompress"))
                {
                    p.CompressResponseIfCompatible();
                }
                p.writeSuccess("application/json");
                if (apiResponse == null)
                {
                    apiResponse = new JSAPI.APIResponse("Response was null, so this response was generated instead.");
                }
                p.outputStream.Write(JsonConvert.SerializeObject(apiResponse));
            }
        }
Пример #6
0
        public static void HandleRequest(HttpProcessor p, string jsonStr)
        {
            object response = null;

            try
            {
                dynamic requestObj = JsonConvert.DeserializeObject(jsonStr);
                string  cmd        = Try.Get(() => (string)requestObj.cmd);
                switch (cmd)
                {
                case "log_get":
                {
                    int  nextLine = (int)requestObj.nextLine;
                    long logId    = (long)requestObj.logId;
                    if (logId == -1)
                    {
                        logId = ServiceWrapper.logReader.readerId;
                    }
                    else if (logId != ServiceWrapper.logReader.readerId)
                    {
                        response = new ResultLogGet("REFRESH", -1, ServiceWrapper.logReader.readerId, null);
                        break;
                    }
                    List <string> lines = ServiceWrapper.logReader.GetLogUpdate(logId, ref nextLine);
                    response = new ResultLogGet("OK", nextLine, ServiceWrapper.logReader.readerId, lines);
                    break;
                }

                    #region Hotkeys
                case "hotkey_reorder":
                case "hotkey_names":
                case "hotkey_list":
                case "hotkey_new":
                case "hotkey_get":
                case "hotkey_update":
                case "hotkey_delete":
                {
                    response = NamedItemAPI(requestObj, ServiceWrapper.config.hotkeys);
                    break;
                }

                case "beginHotkeyBind":
                {
                    int    hotkeyId = requestObj.hotkeyId;
                    string bindId   = ServiceWrapper.hotkeyManager.BeginHotkeyBind(hotkeyId);
                    if (bindId == null)
                    {
                        response = new ResultFailWithReason("hotkey not found");
                    }
                    else if (bindId == "")
                    {
                        response = new ResultFailWithReason("another bind is already in progress");
                    }
                    else
                    {
                        response = new ResultWithData(bindId);
                    }
                    break;
                }

                case "endHotkeyBind":
                {
                    int    hotkeyId = requestObj.hotkeyId;
                    Hotkey hotkey   = ServiceWrapper.config.hotkeys.Get(hotkeyId);
                    if (hotkey == null)
                    {
                        response = new ResultFailWithReason("hotkey not found");
                        break;
                    }
                    string bindId = requestObj.bindId;
                    if (string.IsNullOrWhiteSpace(bindId))
                    {
                        response = new ResultFailWithReason("invalid bindId");
                        break;
                    }
                    while (bindId == ServiceWrapper.hotkeyManager.GetCurrentBindId())
                    {
                        Thread.Sleep(100);
                    }
                    response = new ResultWithData(hotkey);
                    break;
                }

                case "cancelHotkeyBind":
                {
                    string bindId = requestObj.bindId;
                    if (string.IsNullOrWhiteSpace(bindId))
                    {
                        response = new ResultFailWithReason("invalid bindId");
                        break;
                    }
                    ServiceWrapper.hotkeyManager.CancelHotkeyBind(bindId);
                    response = new ResultSuccess();
                    break;
                }

                case "unbindHotkey":
                {
                    string bindId = requestObj.bindId;
                    if (string.IsNullOrWhiteSpace(bindId))
                    {
                        response = new ResultFailWithReason("invalid bindId");
                        break;
                    }
                    Hotkey hotkey = ServiceWrapper.hotkeyManager.UnbindHotkey(bindId);
                    if (hotkey != null)
                    {
                        response = new ResultWithData(hotkey);
                    }
                    else
                    {
                        response = new ResultFailWithReason("Unable to unbind hotkey. Please try again.");
                    }
                    break;
                }

                case "executeHotkey":
                {
                    int    hotkeyId = requestObj.hotkeyId;
                    string error    = ServiceWrapper.hotkeyManager.ExecuteHotkeyById(hotkeyId);
                    if (error == null)
                    {
                        response = new ResultSuccess();
                    }
                    else
                    {
                        response = new ResultFailWithReason("Hotkey manual execution failed: " + error);
                    }
                    break;
                }

                    #endregion
                    #region BroadLink
                case "broadlink_reorder":
                case "broadlink_names":
                case "broadlink_list":
                case "broadlink_new":
                case "broadlink_get":
                case "broadlink_update":
                case "broadlink_delete":
                {
                    response = NamedItemAPI(requestObj, ServiceWrapper.config.broadLinks);
                    break;
                }

                case "broadlink_command_short_names":
                {
                    response = new ResultWithData(IRBlasters.IRCommands.GetIRCommandShortNames());
                    break;
                }

                    #endregion
                    #region BroadLink Commands
                case "broadlinkcmd_reorder":
                case "broadlinkcmd_names":
                case "broadlinkcmd_list":
                case "broadlinkcmd_new":
                case "broadlinkcmd_get":
                case "broadlinkcmd_update":
                case "broadlinkcmd_delete":
                {
                    response = NamedItemAPI(requestObj, BroadLinkCommands.commands, (Action)(() =>
                        {
                            BroadLinkCommands.Save(ServiceWrapper.BroadLinkCommandsFile);
                        }));
                    break;
                }

                case "broadlinkcmd_reload_commands":
                {
                    BroadLinkCommands.Load(ServiceWrapper.BroadLinkCommandsFile);
                    response = new ResultSuccess();
                    break;
                }

                case "beginBroadlinkCommandLearn":
                {
                    int    controllerId = requestObj.controllerId;
                    int    commandId    = requestObj.commandId;
                    string lessonId     = BroadLinkCommands.BeginLearning(controllerId, commandId);
                    if (lessonId == null)
                    {
                        response = new ResultFailWithReason("hotkey not found");
                    }
                    else if (lessonId == "")
                    {
                        response = new ResultFailWithReason("another bind is already in progress");
                    }
                    else
                    {
                        response = new ResultWithData(lessonId);
                    }
                    break;
                }

                case "endBroadlinkCommandLearn":
                {
                    int          controllerId = requestObj.controllerId;
                    int          commandId    = requestObj.commandId;
                    BroadLinkCmd command      = BroadLinkCommands.commands.Get(commandId);
                    if (command == null)
                    {
                        response = new ResultFailWithReason("command not found");
                        break;
                    }
                    string lessonId = requestObj.lessonId;
                    if (string.IsNullOrWhiteSpace(lessonId))
                    {
                        response = new ResultFailWithReason("invalid lessonId");
                        break;
                    }
                    BroadLinkCommands.AwaitLearningResult(controllerId, lessonId);
                    response = new ResultWithData(command);
                    break;
                }

                case "cancelBroadlinkCommandLearn":
                {
                    int    controllerId = requestObj.controllerId;
                    string lessonId     = requestObj.lessonId;
                    if (string.IsNullOrWhiteSpace(lessonId))
                    {
                        response = new ResultFailWithReason("invalid lessonId");
                        break;
                    }
                    BroadLinkCommands.CancelLearning(controllerId, lessonId);
                    response = new ResultSuccess();
                    break;
                }

                case "unlearnBroadlinkCommand":
                {
                    int    controllerId = requestObj.controllerId;
                    string lessonId     = requestObj.lessonId;
                    if (string.IsNullOrWhiteSpace(lessonId))
                    {
                        response = new ResultFailWithReason("invalid lessonId");
                        break;
                    }
                    BroadLinkCmd command = BroadLinkCommands.UnlearnCommandCodes(controllerId, lessonId);
                    if (command != null)
                    {
                        response = new ResultWithData(command);
                    }
                    else
                    {
                        response = new ResultFailWithReason("Unable to unbind command. Please try again.");
                    }
                    break;
                }

                    #endregion
                    #region iTach
                case "itach_reorder":
                case "itach_names":
                case "itach_list":
                case "itach_new":
                case "itach_get":
                case "itach_update":
                case "itach_delete":
                {
                    response = NamedItemAPI(requestObj, ServiceWrapper.config.iTachs);
                    break;
                }

                case "ir_command_short_names":
                {
                    response = new ResultWithData(IRBlasters.IRCommands.GetIRCommandShortNames());
                    break;
                }

                case "itach_reload_commands":
                {
                    iTachCommands.Load(ServiceWrapper.iTachCommandsFile);
                    response = new ResultSuccess();
                    break;
                }

                    #endregion
                    #region Vera
                case "vera_reorder":
                case "vera_names":
                case "vera_list":
                case "vera_new":
                case "vera_get":
                case "vera_update":
                case "vera_delete":
                {
                    response = NamedItemAPI(requestObj, ServiceWrapper.config.veras);
                    break;
                }

                case "vera_command_list":
                {
                    List <object> list = new List <object>();
                    Parallel.ForEach(ServiceWrapper.config.veras.List(), vera =>
                        {
                            ConcurrentDictionary <int, string> map = vera.GetDeviceIdToDisplayNameMap();
                            if (map != null)
                            {
                                int[] DeviceIds = map.Keys.ToArray();
                                string[] Names  = DeviceIds.Select(id => map[id]).ToArray();
                                lock (list)
                                {
                                    list.Add(new { Id = vera.id, Name = vera.name, DeviceIds = DeviceIds, Names = Names });
                                }
                            }
                        });
                    response = new ResultWithData(list);
                    break;
                }

                case "vera_reload_commands":
                {
                    int success = 0;
                    int failure = 0;
                    Parallel.ForEach(ServiceWrapper.config.veras.List(), vera =>
                        {
                            if (vera.LoadDisplayNames(true))
                            {
                                Interlocked.Increment(ref success);
                            }
                            else
                            {
                                Interlocked.Increment(ref failure);
                            }
                        });
                    response = new ResultWithData("Vera Command Loading complete. Successful loads: " + success + ". Failed loads: " + failure);
                    break;
                }

                    #endregion
                    #region HomeAssistant
                case "hass_reorder":
                case "hass_names":
                case "hass_list":
                case "hass_new":
                case "hass_get":
                case "hass_update":
                case "hass_delete":
                {
                    response = NamedItemAPI(requestObj, ServiceWrapper.config.homeAssistantServers);
                    break;
                }

                case "hass_entities":
                {
                    List <object> list = new List <object>();
                    Parallel.ForEach(ServiceWrapper.config.homeAssistantServers.List(), hass =>
                        {
                            List <object> listFromOneServer = hass.GetCommandList();
                            list.AddRange(listFromOneServer);
                        });
                    response = new ResultWithData(list);
                    break;
                }

                case "hass_load":
                {
                    int success = 0;
                    int failure = 0;
                    Parallel.ForEach(ServiceWrapper.config.homeAssistantServers.List(), hass =>
                        {
                            if (hass.Load())
                            {
                                Interlocked.Increment(ref success);
                            }
                            else
                            {
                                Interlocked.Increment(ref failure);
                            }
                        });
                    response = new ResultWithData("HomeAssistant Entity Loading complete. Successful loads: " + success + ". Failed loads: " + failure);
                    break;
                }

                    #endregion
                default:
                    response = new ResultFail()
                    {
                        error = "command \"" + cmd + "\" not supported"
                    };
                    break;
                }
            }
            catch (Exception ex)
            {
                Logger.Debug(ex);
                response = new ResultFail()
                {
                    error = "An unexpected error occurred. " + ex.ToString()
                };
            }
            finally
            {
                if (response == null)
                {
                    response = new ResultFail()
                    {
                        error = "Application Error: A response was not generated, so this response was generated as a fallback."
                    }
                }
                ;
                p.CompressResponseIfCompatible();
                p.writeSuccess(jsonType);
                p.outputStream.Write(JsonConvert.SerializeObject(response));
            }
        }