/// <summary> /// Handle an Open Viewtop HTTP or Websocket request /// </summary> async public Task ProcessOpenViewtopRequestAsync(HttpContext context) { // Process web sockets to allow login and authentication var request = context.Request; if (request.Path == "/ovt/ws" && context.Request.IsWebSocketRequest) { PurgeInactiveSessions(); await ProcessOpenViewtopWebSocketsAsync(context.AcceptWebSocket("viewtop")); return; } if (request.Path == "/ovt/info") { // Do not send when IP address is on the public internet. TBD: Allow 172.17, etc. var ip = ((IPEndPoint)context.RemoteEndPoint).Address.ToString(); bool localIp = mLocalIpAddresses.FindIndex((a) => ip.StartsWith(a)) >= 0; var info = new Info(); info.Local = LocalComputerInfo; info.Remotes = localIp ? RemoteComputerInfo : new ComputerInfo[0]; await context.SendResponseAsync(JsonConvert.SerializeObject(info)); return; } // Requests with a valid SID (session id) get routed to the session long sid = request.Query["sid", 0]; if (sid != 0) { ViewtopSession session; lock (mLock) mSessions.TryGetValue(sid, out session); if (session == null) { throw new HttpException(400, "Unknown 'sid'"); } await session.ProcessOpenViewtopRequestAsync(context); return; } // *** Serve public static files *** // Convert path to Windows, strip leading "\", and choose "index" if no name is given string path = request.Path.Replace('/', Path.DirectorySeparatorChar); while (path.Length != 0 && path[0] == Path.DirectorySeparatorChar) { path = path.Substring(1); } if (path.Length == 0) { path = "index.html"; } string publicSubdirectory = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "www"); string hiddenFileName = Path.DirectorySeparatorChar + "."; // Never serve files outside of the public subdirectory, or that begin with a "." path = Path.Combine(publicSubdirectory, path); if (path.Contains("..") || path.Contains(hiddenFileName)) { throw new HttpException(400, "Invalid Request: File name is invalid", true); } if (request.Method != "GET") { throw new HttpException(405, "Invalid HTTP request: Only GET method is allowed for serving "); } if (mMimeTypes.TryGetValue(Path.GetExtension(path).ToLower(), out string contentType)) { context.Response.ContentType = contentType; } await context.SendFileAsync(path); }