예제 #1
0
파일: Server.cs 프로젝트: mono/daap-sharp
 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);
         }
     }
 }
예제 #2
0
파일: User.cs 프로젝트: mono/daap-sharp
 public UserArgs(User user)
 {
     this.user = user;
 }
예제 #3
0
파일: Server.cs 프로젝트: mono/daap-sharp
        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;
        }