private void OnUserLogout(User user) { UserHandler handler = UserLogout; if (handler != null) { try { handler (this, new UserArgs (user)); } catch (Exception e) { Console.Error.WriteLine ("Exception in UserLogout event handler: " + e); } } }
public UserArgs(User user) { this.user = user; }
internal bool OnHandleRequest(Socket client, string username, string path, NameValueCollection query, int range) { int session = 0; if (query["session-id"] != null) { session = Int32.Parse (query["session-id"]); } if (!sessions.ContainsKey (session) && path != "/server-info" && path != "/content-codes" && path != "/login") { ws.WriteResponse (client, HttpStatusCode.Forbidden, "invalid session id"); return true; } if (session != 0) { sessions[session].LastActionTime = DateTime.Now; } int clientRev = 0; if (query["revision-number"] != null) { clientRev = Int32.Parse (query["revision-number"]); } int delta = 0; if (query["delta"] != null) { delta = Int32.Parse (query["delta"]); } if (path == "/server-info") { ws.WriteResponse (client, GetServerInfoNode ()); } else if (path == "/content-codes") { ws.WriteResponse (client, ContentCodeBag.Default.ToNode ()); } else if (path == "/login") { ExpireSessions (); if (maxUsers > 0 && sessions.Count + 1 > maxUsers) { ws.WriteResponse (client, HttpStatusCode.ServiceUnavailable, "too many users"); return true; } session = random.Next (); User user = new User (DateTime.Now, (client.RemoteEndPoint as IPEndPoint).Address, username); lock (sessions) { sessions[session] = user; } ws.WriteResponse (client, GetLoginNode (session)); OnUserLogin (user); } else if (path == "/logout") { User user = sessions[session]; lock (sessions) { sessions.Remove (session); } ws.WriteResponse (client, HttpStatusCode.OK, new byte[0]); OnUserLogout (user); return false; } else if (path == "/databases") { ws.WriteResponse (client, GetDatabasesNode ()); } else if (dbItemsRegex.IsMatch (path)) { int dbid = Int32.Parse (dbItemsRegex.Match (path).Groups[1].Value); Database curdb = revmgr.GetDatabase (clientRev, dbid); if (curdb == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid database id"); return true; } ArrayList deletedIds = new ArrayList (); if (delta > 0) { Database olddb = revmgr.GetDatabase (clientRev - delta, dbid); if (olddb != null) { foreach (Track track in olddb.Tracks) { if (curdb.LookupTrackById (track.Id) == null) deletedIds.Add (track.Id); } } } ContentNode node = curdb.ToTracksNode (query["meta"].Split (','), (int[]) deletedIds.ToArray (typeof (int))); ws.WriteResponse (client, node); } else if (dbTrackRegex.IsMatch (path)) { Match match = dbTrackRegex.Match (path); int dbid = Int32.Parse (match.Groups[1].Value); int trackid = Int32.Parse (match.Groups[2].Value); Database db = revmgr.GetDatabase (clientRev, dbid); if (db == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid database id"); return true; } Track track = db.LookupTrackById (trackid); if (track == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid track id"); return true; } try { try { if (TrackRequested != null) TrackRequested (this, new TrackRequestedArgs (username, (client.RemoteEndPoint as IPEndPoint).Address, db, track)); } catch {} if (track.FileName != null) { ws.WriteResponseFile (client, track.FileName, range); } else if (db.Client != null) { long trackLength = 0; Stream trackStream = db.StreamTrack (track, out trackLength); try { ws.WriteResponseStream (client, trackStream, trackLength); } catch (IOException) { } } else { ws.WriteResponse (client, HttpStatusCode.InternalServerError, "no file"); } } finally { client.Close (); } } else if (dbContainersRegex.IsMatch (path)) { int dbid = Int32.Parse (dbContainersRegex.Match (path).Groups[1].Value); Database db = revmgr.GetDatabase (clientRev, dbid); if (db == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid database id"); return true; } ws.WriteResponse (client, db.ToPlaylistsNode ()); } else if (dbContainerItemsRegex.IsMatch (path)) { Match match = dbContainerItemsRegex.Match (path); int dbid = Int32.Parse (match.Groups[1].Value); int plid = Int32.Parse (match.Groups[2].Value); Database curdb = revmgr.GetDatabase (clientRev, dbid); if (curdb == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid database id"); return true; } Playlist curpl = curdb.LookupPlaylistById (plid); if (curdb == null) { ws.WriteResponse (client, HttpStatusCode.BadRequest, "invalid playlist id"); return true; } ArrayList deletedIds = new ArrayList (); if (delta > 0) { Database olddb = revmgr.GetDatabase (clientRev - delta, dbid); if (olddb != null) { Playlist oldpl = olddb.LookupPlaylistById (plid); if (oldpl != null) { IList<Track> oldplTracks = oldpl.Tracks; for (int i = 0; i < oldplTracks.Count; i++) { int id = oldpl.GetContainerId (i); if (curpl.LookupIndexByContainerId (id) < 0) { deletedIds.Add (id); } } } } } ws.WriteResponse (client, curpl.ToTracksNode ((int[]) deletedIds.ToArray (typeof (int)))); } else if (path == "/update") { int retrev; lock (revmgr) { // if they have the current revision, wait for a change if (clientRev == revmgr.Current) { Monitor.Wait (revmgr); } retrev = revmgr.Current; } if (!running) { ws.WriteResponse (client, HttpStatusCode.NotFound, "server has been stopped"); } else { ws.WriteResponse (client, GetUpdateNode (retrev)); } } else { ws.WriteResponse (client, HttpStatusCode.Forbidden, "GO AWAY"); } return true; }