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; } } }
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; } } }
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); } } }
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(); } } }
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)); } }
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)); } }