public override void handleGETRequest(HttpProcessor p) { try { if (p.requestedPage == "") { p.writeSuccess(); p.outputStream.WriteLine("<html>"); p.outputStream.WriteLine("<head>"); p.outputStream.WriteLine("<title>Geolocation Web Service</title>"); p.outputStream.WriteLine("</head>"); p.outputStream.WriteLine("<body>"); p.outputStream.WriteLine("<h1>Geolocation Web Service " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + "</h1>"); p.outputStream.WriteLine("<h2>Examples</h2>"); p.outputStream.WriteLine("<h3>HTML Page</h3>"); p.outputStream.WriteLine("<p><a href=\"whois/8.8.8.8\">whois/8.8.8.8</a></p>"); p.outputStream.WriteLine("<h3>HTML Embed</h3>"); p.outputStream.WriteLine("<p><a href=\"embed/8.8.8.8\">embed/8.8.8.8</a></p>"); p.outputStream.WriteLine("<h3>JSON Record</h3>"); p.outputStream.WriteLine("<p><a href=\"ip/8.8.8.8\">ip/8.8.8.8</a> (or <a href=\"ip/8.8.8.8.json\">ip/8.8.8.8.json</a>)</p>"); p.outputStream.WriteLine("<h3>Location on Map</h3>"); p.outputStream.WriteLine("<p><a href=\"map/0/8.8.8.8\">map/0/8.8.8.8</a> (or <a href=\"map/0/8.8.8.8.jpg\">map/0/8.8.8.8.jpg</a>)</p>"); p.outputStream.WriteLine("<p><a href=\"map/1/8.8.8.8.jpg\">map/1/8.8.8.8.jpg</a></p>"); p.outputStream.WriteLine("<p><a href=\"map/2/8.8.8.8.jpg\">map/2/8.8.8.8.jpg</a></p>"); p.outputStream.WriteLine("<p><a href=\"map/3/8.8.8.8.jpg\">map/3/8.8.8.8.jpg</a></p>"); p.outputStream.WriteLine("<p><a href=\"map/4/8.8.8.8.jpg\">map/4/8.8.8.8.jpg</a></p>"); p.outputStream.WriteLine("<p><a href=\"map/5/8.8.8.8.jpg\">map/5/8.8.8.8.jpg</a></p>"); p.outputStream.WriteLine("<h2>Licensing and Attribution</h2>"); p.outputStream.WriteLine("<p>Wherever data or maps from this service are used, it is required that you comply with the licensing and attribution requirements of the organizations listed below:</p>"); p.outputStream.WriteLine("<h3>IP2Location</h3>"); p.outputStream.WriteLine("<p>This site or product includes IP2Location LITE data available from <a href=\"http://www.ip2location.com\">http://www.ip2location.com</a>.</p>"); p.outputStream.WriteLine("<h3>OpenStreetMap</h3>"); p.outputStream.WriteLine("<p>Map data is <a href=\"https://www.openstreetmap.org/copyright\">© OpenStreetMap contributors and cartography is licensed as CC BY-SA.</a></p>"); p.outputStream.WriteLine("</body>"); p.outputStream.WriteLine("</html>"); } else if (p.requestedPage.StartsWith("whois/")) { string input = p.requestedPage.Substring("whois/".Length); if (input.EndsWith(".json", StringComparison.OrdinalIgnoreCase)) { input = input.Remove(input.Length - ".json".Length); } IPRecord record = Program.db.GetIPRecord(input); if (record == null) { p.writeFailure(); } else { p.writeSuccess(additionalHeaders: CoordsHeader(record)); p.outputStream.WriteLine("<html>"); p.outputStream.WriteLine("<head>"); p.outputStream.WriteLine("<title>Geolocation Web Service</title>"); p.outputStream.WriteLine("<style type=\"text/css\">"); p.outputStream.WriteLine("table { border-collapse: collapse; }"); p.outputStream.WriteLine("td { border: 1px solid black; padding: 2px 5px; }"); p.outputStream.WriteLine("</style>"); p.outputStream.WriteLine("</head>"); p.outputStream.WriteLine("<body>"); p.outputStream.WriteLine("<h1>Geolocation Information For " + input + "</h1>"); p.outputStream.WriteLine("<p>"); p.outputStream.WriteLine("<table>"); p.outputStream.WriteLine("<tbody>"); p.outputStream.WriteLine("<tr><td>Latitude</td><td>" + record.latitude + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Longitude</td><td>" + record.longitude + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Country</td><td>" + record.country_code + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Country Name</td><td>" + record.country_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Region</td><td>" + record.region_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>City</td><td>" + record.city_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Zip Code</td><td>" + record.zip_code + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Time Zone</td><td>" + record.time_zone + "</td></tr>"); p.outputStream.WriteLine("</tbody>"); p.outputStream.WriteLine("</table>"); p.outputStream.WriteLine("</p>"); p.outputStream.WriteLine("<p>"); p.outputStream.WriteLine("<img src=\"../map/1/" + input + ".jpg\" alt=\"map\"/>"); p.outputStream.WriteLine("</p>"); p.outputStream.WriteLine("<p>This site or product includes IP2Location LITE data available from <a href=\"http://www.ip2location.com\">http://www.ip2location.com</a>.</p>"); p.outputStream.WriteLine("<p>Map data is <a href=\"https://www.openstreetmap.org/copyright\">© OpenStreetMap contributors and cartography is licensed as CC BY-SA.</a></p>"); p.outputStream.WriteLine("</body>"); p.outputStream.WriteLine("</html>"); } } else if (p.requestedPage.StartsWith("embed/")) { string input = p.requestedPage.Substring("embed/".Length); IPRecord record = Program.db.GetIPRecord(input); if (record == null) { p.writeFailure(); } else { LocationMap map = LocationMapper.GetMap(record, 1, 256, 256); p.writeSuccess(additionalHeaders: CoordsHeader(record)); p.outputStream.WriteLine("<style type=\"text/css\">"); p.outputStream.WriteLine(".gwsembed { font-family: sans-serif; }"); p.outputStream.WriteLine(".gwsembed .heading { font-size: 1.3em; font-weight: bold; margin: 3px 0px 8px 0px }"); p.outputStream.WriteLine(".gwsembed .data { display: inline-block; vertical-align: top; margin-right: 5px; margin-bottom: 5px; font-family: consolas, monospace; }"); p.outputStream.WriteLine(".gwsembed .physical_address { white-space: pre-wrap; }"); p.outputStream.WriteLine(".gwsembed table { border-collapse: collapse; margin-top: 5px;}"); p.outputStream.WriteLine(".gwsembed td { border: 1px solid black; padding: 2px 5px; }"); p.outputStream.WriteLine(".gwsembed .img { width: 256px; height: 256px; display: inline-block; vertical-align: top; }"); p.outputStream.WriteLine(".gwsembed .body > div, .gwsembed .body > p { margin: 5px 0px; }"); p.outputStream.WriteLine("</style>"); p.outputStream.WriteLine("<div class=\"gwsembed\">"); if (!p.GetBoolParam("hideTitle")) { p.outputStream.WriteLine("<div class=\"heading\">Geolocation for " + input + "</div>"); } p.outputStream.WriteLine("<div class=\"body\">"); p.outputStream.WriteLine("<div class=\"info\">"); p.outputStream.WriteLine("<div class=\"data\">"); p.outputStream.Write("<div class=\"physical_address\">"); p.outputStream.WriteLine(record.city_name + ", " + record.region_name + " " + record.zip_code); p.outputStream.Write(record.country_code + " (" + record.country_name + ")"); p.outputStream.WriteLine("</div>"); // end physical_address p.outputStream.WriteLine("<table>"); p.outputStream.WriteLine("<tbody>"); p.outputStream.WriteLine("<tr><td>Latitude</td><td>" + record.latitude + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Longitude</td><td>" + record.longitude + "</td></tr>"); p.outputStream.WriteLine("<tr><td>City</td><td>" + record.city_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Region</td><td>" + record.region_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Country</td><td>" + record.country_code + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Country Name</td><td>" + record.country_name + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Zip Code</td><td>" + record.zip_code + "</td></tr>"); p.outputStream.WriteLine("<tr><td>Time Zone</td><td>" + record.time_zone + "</td></tr>"); p.outputStream.WriteLine("</tbody>"); p.outputStream.WriteLine("</table>"); p.outputStream.WriteLine("</div>"); // end data p.outputStream.WriteLine("<img src=\"" + map.ToDataUri() + "\" alt=\"map\"/>"); p.outputStream.WriteLine("</div>"); // end info p.outputStream.WriteLine("<p>This information includes IP2Location LITE data available from <a href=\"http://www.ip2location.com\">http://www.ip2location.com</a>.</p>"); p.outputStream.WriteLine("<p>Map data is <a href=\"https://www.openstreetmap.org/copyright\">© OpenStreetMap contributors and cartography is licensed as CC BY-SA.</a></p>"); p.outputStream.WriteLine("</div>"); // end body p.outputStream.WriteLine("</div>"); // end gwsembed } } else if (p.requestedPage.StartsWith("ip/")) { string input = p.requestedPage.Substring("ip/".Length); if (input.EndsWith(".json", StringComparison.OrdinalIgnoreCase)) { input = input.Remove(input.Length - ".json".Length); } IPRecord record = Program.db.GetIPRecord(input); if (record == null) { p.writeFailure(); } else { p.writeSuccess("application/json"); p.outputStream.Write(JsonConvert.SerializeObject(record)); } } else { string page = p.requestedPage; if (page.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) { page = page.Remove(page.Length - ".jpg".Length); } Match m = rxMapURL.Match(page); if (m.Success) // map/zoom/ip { int.TryParse(m.Groups[1].Value, out int zoomLevel); string input = m.Groups[2].Value; IPRecord record = Program.db.GetIPRecord(input); if (record == null) { p.writeFailure(); } else { LocationMap map = LocationMapper.GetMap(record, zoomLevel, 256, 256); p.writeSuccess(map.mimeType, map.imgData.Length, additionalHeaders: CoordsHeader(record)); p.outputStream.Flush(); p.tcpStream.Write(map.imgData, 0, map.imgData.Length); } } else { m = rxMapDebugURL.Match(page); if (m.Success) // mapdebug/zoom/lat/lon { int.TryParse(m.Groups[1].Value, out int zoomLevel); double.TryParse(m.Groups[2].Value, out double lat); double.TryParse(m.Groups[3].Value, out double lon); IPRecord record = new IPv4Record(); record.latitude = lat; record.longitude = lon; LocationMap map = LocationMapper.GetMap(record, zoomLevel, 256, 256); p.writeSuccess(map.mimeType, map.imgData.Length, additionalHeaders: CoordsHeader(record)); p.outputStream.Flush(); p.tcpStream.Write(map.imgData, 0, map.imgData.Length); } } } } catch (Exception ex) { p.writeFailure("500 Internal Server Error", ex.ToString()); } }
public string SaveItem(HttpProcessor p) { bool isNew = p.GetBoolParam("new"); string originalIdNotLowerCase = p.GetPostParam("itemid"); string originalId = originalIdNotLowerCase.ToLower(); string itemtype = p.GetPostParam("itemtype"); if (itemtype == "camera") { CameraSpec cs = new CameraSpec(); string result = cs.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { if (isNew) { cs.id = originalId; if (CameraIdIsUsed(cs.id)) { return("0A camera with this ID already exists."); } cameras.Add(cs); } else { if (originalId != cs.id && CameraIdIsUsed(cs.id)) { return("0A camera with this ID already exists."); } bool foundCamera = false; for (int i = 0; i < cameras.Count; i++) { if (cameras[i].id == originalId) { cs.order = cameras[i].order; foundCamera = true; MJpegServer.cm.KillCamera(originalId); cameras[i] = cs; break; } } if (!foundCamera) { cameras.Add(cs); } } MJpegServer.cm.CleanUpCameraOrder(); Save(CameraProxyGlobals.ConfigFilePath); } return(result); } else if (itemtype == "user") { Configuration.User u = new Configuration.User(); string result = u.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { if (isNew) { u.name = originalId; if (UserNameIsUsed(u.name)) { return("0A user with this name already exists."); } users.Add(u); } else { if (originalId != u.name && UserNameIsUsed(u.name)) { return("0A user with this name already exists."); } bool foundUser = false; for (int i = 0; i < users.Count; i++) { if (users[i].name == originalId) { foundUser = true; users[i] = u; break; } } if (!foundUser) { users.Add(u); } } Save(CameraProxyGlobals.ConfigFilePath); } return(result); } else if (itemtype == "ptzprofile") { PTZProfile f = new PTZProfile(); int version = p.GetPostIntParam("version", 1); if (version == 1) { f.spec = new PTZSpecV1(); } string result = f.spec.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { if (isNew) { f.name = originalIdNotLowerCase; if (ProfileNameIsUsed(f.name)) { return("0A PTZ Profile with this name already exists."); } f.Save(CameraProxyGlobals.PTZProfilesDirectoryBase + f.name + ".xml"); } else { if (originalId != f.name.ToLower() && ProfileNameIsUsed(f.name)) { return("0A PTZ Profile with this name already exists."); } File.Delete(CameraProxyGlobals.PTZProfilesDirectoryBase + originalId + ".xml"); f.Save(CameraProxyGlobals.PTZProfilesDirectoryBase + f.name + ".xml"); } } return(result); } return("0Invalid item type: " + itemtype); }
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.rawOutputStream.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.rawOutputStream.Write(sendImage, 0, sendImage.Length); p.rawOutputStream.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.rawOutputStream.Write(outputBuffer, 0, outputBuffer.Length); p.rawOutputStream.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; } p.writeSuccess("text/html"); p.outputStream.Write(html); } 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.rawOutputStream.Write(data, 0, data.Length); return; } } else { string fileName = Globals.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.rawOutputStream.Write(bytes, 0, bytes.Length); return; } } } } } { // Failed to get image thumbnail byte[] bytes = File.ReadAllBytes(Globals.WWWPublicDirectoryBase + "Images/qmark.png"); p.writeSuccess("image/png", bytes.Length); p.outputStream.Flush(); p.rawOutputStream.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.RemoteIPAddress != "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.rawOutputStream.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 { #region www int permissionRequired; if (!Util.TryGetValue(requestedPage.ToLower(), MJpegWrapper.cfg.GetWwwFilesList(), out permissionRequired)) { permissionRequired = -1; } string wwwDirectory = permissionRequired == -1 ? Globals.WWWPublicDirectoryBase : Globals.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) { p.writeSuccess(Mime.GetMimeType(fi.Extension)); 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.RemoteIPAddress); } catch (Exception ex) { Logger.Debug(ex); } p.outputStream.Write(html); p.outputStream.Flush(); } else if ((fi.Extension == ".html" || fi.Extension == ".htm") && fi.Length < 256000) { p.writeSuccess(Mime.GetMimeType(fi.Extension)); 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.RemoteIPAddress); } catch (Exception ex) { Logger.Debug(ex); } p.outputStream.Write(html); p.outputStream.Flush(); } else { 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.rawOutputStream); } p.rawOutputStream.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 override void handleGETRequest(HttpProcessor p) { try { string requestedPage = p.request_url.AbsolutePath.TrimStart('/'); string streamid = p.GetParam("streamid"); if (requestedPage == "about") { p.writeSuccess(); p.outputStream.Write("<div>UI2Service version " + UI2ServiceWrapper.Version + "</div>"); p.outputStream.Write("<div>Thread pool min threads: " + this.pool.MinThreads + "</div>"); p.outputStream.Write("<div>Thread pool max threads: " + this.pool.MaxThreads + "</div>"); p.outputStream.Write("<div>Thread pool live threads: " + this.pool.CurrentLiveThreads + "</div>"); p.outputStream.Write("<div>Thread pool busy threads: " + this.pool.CurrentBusyThreads + "</div>"); } else if (requestedPage == "jpegdiffversions") { p.writeSuccess("text/plain"); p.outputStream.Write(string.Join("|", JpegDiffVideoEncoder.Versions)); } else if (requestedPage.StartsWith("image/") && !string.IsNullOrEmpty(streamid) && streamid.Length < 256) { bool startNewStream = p.GetBoolParam("startNewStream"); int quality = p.GetIntParam("jdq", 80); int version = p.GetIntParam("jdv", 1); JpegDiffVideoEncoder encoder = dictStreamIdToEncoder.GetOrAdd(streamid, p_streamId => { startNewStream = false; return(new JpegDiffVideoEncoder()); }); byte[] jpegData = DownloadBytes(p, BlueIrisBaseURL + p.request_url.PathAndQuery.TrimStart('/')); if (jpegData == null || jpegData.Length == 0) { p.writeFailure("500"); return; } int outputSizeBytes = 0; byte[] retVal; if (startNewStream) { encoder = GetNewEncoder(streamid); } try { encoder.CompressionQuality = quality; retVal = encoder.EncodeFrame(jpegData, jpegData.Length, out outputSizeBytes, version); } catch (JpegDiffVideoException) { Console.WriteLine("Frame resized."); encoder = GetNewEncoder(streamid); try { encoder.CompressionQuality = quality; retVal = encoder.EncodeFrame(jpegData, jpegData.Length, out outputSizeBytes, version); } catch (Exception ex) { Console.WriteLine("Eaten EncodeFrame exception: " + ex.ToString()); // This happens sometimes when decoding the jpeg header. Not sure why. p.writeFailure("500"); return; } } catch (Exception ex) { Console.WriteLine("Eaten EncodeFrame exception: " + ex.ToString()); // This happens sometimes when decoding the jpeg header. Not sure why. p.writeFailure("500"); return; } p.writeSuccess("image/jpeg", outputSizeBytes); p.outputStream.Flush(); p.rawOutputStream.Write(retVal, 0, outputSizeBytes); } else { ProxyRequestTo(p, BlueIrisBaseURL + p.request_url.PathAndQuery.TrimStart('/')); } } catch (Exception ex) { if (!p.isOrdinaryDisconnectException(ex)) { Logger.Debug(ex); } } }
public override void handleGETRequest(HttpProcessor p) { if (!Program.settings.IpIsWhitelisted(p.RemoteIPAddressStr)) { p.writeFailure("403 Forbidden"); return; } string successMessage = "<div>" + p.requestedPage + " command successful</div>"; List <KeyValuePair <string, string> > additionalHeaders = new List <KeyValuePair <string, string> >(); additionalHeaders.Add(new KeyValuePair <string, string>("Access-Control-Allow-Origin", "*")); if (p.requestedPage == "on") { On(p); } else if (p.requestedPage == "off") { int idleTimeMs = p.GetIntParam("ifidle", 0); int delayMs = p.GetIntParam("delay", 0); Action setOff = () => { if (idleTimeMs <= 0 || LastInput.GetLastInputAgeMs() >= idleTimeMs) { Off(p.GetBoolParam("mute")); } }; if (delayMs > 0) { SetTimeout.OnBackground(setOff, delayMs); } else { setOff(); } } else if (p.requestedPage == "off_if_idle") { OffIfIdle(Program.settings.idleTimeMs, p.GetBoolParam("mute")); } else if (p.requestedPage == "standby") { currentMonitorStatus = "off"; SetMonitorInState(1); } else if (p.requestedPage == "status") { p.writeSuccess("text/plain", additionalHeaders: additionalHeaders); p.outputStream.Write(currentMonitorStatus); return; } else if (p.requestedPage == "idle") { p.writeSuccess("text/plain", additionalHeaders: additionalHeaders); p.outputStream.Write(LastInput.GetLastInputAgeMs()); return; } else if (p.requestedPage == "smarttoggle") { if (currentMonitorStatus == "on") { OffIfIdle(Program.settings.idleTimeMs, p.GetBoolParam("mute")); } else { On(p); } } else if (p.requestedPage == "cancel") { StopMonitorOffThread(); } else if (p.requestedPage == "getvolume") { int level = 0; try { level = (int)Math.Round(AudioManager.GetMasterVolume()); //level = Audio.GetVolume(); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain"); p.outputStream.Write(level); } else if (p.requestedPage == "setvolume") { int level = p.GetIntParam("level"); level = level.Clamp(0, 100); try { AudioManager.SetMasterVolume(level); //Audio.SetVolume(level); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain"); p.outputStream.Write(level); } else if (p.requestedPage == "mute") { try { AudioManager.SetMasterVolumeMute(true); //Audio.SetMute(true); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain"); p.outputStream.Write("muted"); } else if (p.requestedPage == "unmute") { try { AudioManager.SetMasterVolumeMute(false); //Audio.SetMute(false); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain"); p.outputStream.Write("unmuted"); } else if (p.requestedPage == "getmute") { bool muted = false; try { muted = AudioManager.GetMasterVolumeMute(); //muted = Audio.GetMute(); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain"); p.outputStream.Write(muted ? "muted" : "unmuted"); } else if (p.requestedPage == "mousemove") { int dx = p.GetIntParam("dx"); // x change int dy = p.GetIntParam("dy"); // y change int delay = p.GetIntParam("delay").Clamp(1, 200); // Approximate milliseconds between movements. int times = p.GetIntParam("times").Clamp(1, 5000 / delay); // Number of times to perform the change. Limited to about 5 seconds of movement. try { DragMouse(dx, dy, delay, times); } catch (Exception ex) { p.writeSuccess("text/plain; charset=utf-8", responseCode: "500 Internal Server Error"); p.outputStream.Write(ex.ToString()); return; } p.writeSuccess("text/plain; charset=utf-8"); p.outputStream.Write("move complete. moved " + dx + "," + dy + " " + times + " times with " + delay + " ms delay"); } else if (p.requestedPage == "AllowLocalOverride") { Program.settings.syncAllowLocalOverride = true; Program.settings.Save(); p.writeSuccess("text/plain; charset=utf-8"); p.outputStream.Write("✅ Allow local input to override synced state"); } else if (p.requestedPage == "DisallowLocalOverride") { Program.settings.syncAllowLocalOverride = false; Program.settings.Save(); p.writeSuccess("text/plain; charset=utf-8"); p.outputStream.Write("❌ Allow local input to override synced state"); } else { successMessage = ""; } if (p.responseWritten) { return; } p.writeSuccess(additionalHeaders: additionalHeaders); p.outputStream.Write("<html><head><title>Monitor Control Service</title></head>" + "<style type=\"text/css\">" + " table { border-collapse: collapse; }" + " th, td { border: 1px solid black; padding: 3px 5px; }" + "</style>" + "<body>" + "<p class=\"result\">" + successMessage + "</p>" + "<p class=\"syncStatus\">(Remote server \"" + Program.settings.syncAddress + "\") " + HttpUtility.HtmlEncode(MonitorControlService.syncedServerStatus) + "</p>" + "<table>" //+ "<thead>" //+ "<tr><th></th><th></th></tr>" //+ "</thead>" + "<tbody>" + BuildRow("on", "turn displays on") + BuildRow("on?offAfterSecs=15", "turn displays on, then after 15 seconds, off") + BuildRow("cancel", "cancel a scheduled monitor off command (see above)") + BuildRow("off", "turn displays off") + BuildRow("off?ifidle=3000", "turn displays off if idle for 3000ms") + BuildRow("off?delay=3000&ifidle=2900", "wait 3000ms, then turn displays off if idle for 2900ms") + BuildRow("off?delay=3000&ifidle=2900&mute=1", "wait 3000ms, then turn displays off if idle for 2900ms, and also mute until the computer is no longer idle") + BuildRow("off_if_idle", "turn displays off if idle for the configured idle time (" + Program.settings.idleTimeMs + " ms)") + BuildRow("off_if_idle?mute=1", "turn displays off if idle for the configured idle time (" + Program.settings.idleTimeMs + " ms). Also mute until the computer is no longer idle.") + BuildRow("standby", "change displays to standby state -- probably does nothing") + BuildRow("status", "return the current status (\"on\" or \"off\")") + BuildRow("idle", "return the time in milliseconds since the last user input") + BuildRow("smarttoggle", "if status is \"on\" then <b>off_if_idle</b>, else <b>on</b>. Also supports the <b>mute</b> boolean argument.") + BuildRow("getvolume", "returns default audio device volume from 0 to 100") + BuildRow("setvolume?level=10", "sets default audio device volume from 0 to 100") + BuildRow("mute", "mutes default audio device") + BuildRow("unmute", "unmutes default audio device") + BuildRow("getmute", "returns \"muted\" or \"unmuted\"") + BuildRow("mousemove?dx=2&dy=-2&delay=4×=5", "moves the mouse cursor up 2px and to the right 2px, 5 times, waiting 4ms between each movement. Max delay 200ms. Max 5 seconds movement per command.") + BuildRow("AllowLocalOverride", "Enables the setting \"Allow local input to override synced state\"") + BuildRow("DisallowLocalOverride", "Disables the setting \"Allow local input to override synced state\"") + "</tbody>" + "</table>" + "</body>" + "</html>"); }
public string SaveItem(HttpProcessor p) { bool isNew = p.GetBoolParam("new"); string originalIdNotLowerCase = p.GetPostParam("itemid"); string originalId = originalIdNotLowerCase.ToLower(); string itemtype = p.GetPostParam("itemtype"); if (itemtype == "camera") { CameraSpec cs = new CameraSpec(); string result = cs.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { if (isNew) { cs.id = originalId; if (CameraIdIsUsed(cs.id)) { return("0A camera with this ID already exists."); } cameras.Add(cs); } else { if (originalId != cs.id && CameraIdIsUsed(cs.id)) { return("0A camera with this ID already exists."); } bool foundCamera = false; for (int i = 0; i < cameras.Count; i++) { if (cameras[i].id == originalId) { cs.order = cameras[i].order; foundCamera = true; cameras[i] = cs; break; } } if (!foundCamera) { cameras.Add(cs); } } CleanUpCameraOrder(); Save(Globals.ConfigFilePath); } return(result); } else if (itemtype == "user") { Configuration.User u = new Configuration.User(); string result = u.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { if (isNew) { u.name = originalId; if (UserNameIsUsed(u.name)) { return("0A user with this name already exists."); } users.Add(u); } else { if (originalId != u.name && UserNameIsUsed(u.name)) { return("0A user with this name already exists."); } bool foundUser = false; for (int i = 0; i < users.Count; i++) { if (users[i].name == originalId) { foundUser = true; users[i] = u; break; } } if (!foundUser) { users.Add(u); } } Save(Globals.ConfigFilePath); } return(result); } else if (itemtype == "globaloptions") { Configuration.TimelapseGlobalOptions o = new TimelapseGlobalOptions(); string result = o.setFieldValues(p.RawPostParams); if (result.StartsWith("0")) { return(result); } lock (this) { this.options = o; Save(Globals.ConfigFilePath); } GlobalThrottledStream.ThrottlingManager.SetBytesPerSecond(0, o.uploadBytesPerSecond); GlobalThrottledStream.ThrottlingManager.SetBytesPerSecond(1, o.downloadBytesPerSecond); GlobalThrottledStream.ThrottlingManager.BurstIntervalMs = o.throttlingGranularity; return(result); } return("0Invalid item type: " + itemtype); }