Exemplo n.º 1
0
        /// <summary>
        /// When the user does something on the PC Server music player like
        /// Pause or Play or change tracks then we need to release all waiting
        /// HTTP requests from DACP Clients that have been blocking.
        /// </summary>
        public static void ReleaseAllLatches()
        {
            Console.WriteLine("Releasing {0} CountDownLatches", latches.Count);
            foreach (CountDownLatch latch in latches)
            {
                latch.CountDown();
            }
            latches.Clear();

            // notify all connected clients to update their UI
            SessionBoundResponse.IncrementCtrlIntRevision();
        }
Exemplo n.º 2
0
        private void DispatchRequest(HttpListenerRequest request, HttpListenerResponse response, bool isCompressed)
        {
            DACPResponse dacpResponse = null;
            Stopwatch    stopWatch    = new Stopwatch();

            stopWatch.Start();
            // based on the URL, figure out what the client wanted and return it
            string url = request.RawUrl.ToLower();

            try {
                // first handle either login or security check
                if (url.StartsWith("/login"))
                {
                    dacpResponse = Login(request);
                    ReleaseAllLatches();
                }
                else if (url.StartsWith("/server-info"))
                {
                    ReleaseAllLatches();
                    dacpResponse = new ServerInfoResponse(request);
                }
                else if (url.Equals("/ctrl-int"))
                {
                    ReleaseAllLatches();
                    dacpResponse = new CtrlIntResponse(request);
                }
                else if (url.StartsWith("/databases?session-id="))
                {
                    dacpResponse = GetDatabaseInfo(request);
                }
                else if (url.StartsWith("/update"))
                {
                    stopWatch    = null;
                    dacpResponse = GetUpdate(request);
                }
                else if (url.StartsWith("/logout"))
                {
                    dacpResponse = new LogoutResponse(request);
                    Logout(request);
                }
                else if (url.StartsWith("/fp-setup"))
                {
                    dacpResponse = new FairPlayResponse(request);
                }
                else if (url.StartsWith("/refreshcache"))
                {
                    RefreshCache();
                }
                else if (url.StartsWith("/databases/"))
                {
                    if (url.Contains("daap.baseplaylist"))
                    {
                        dacpResponse = GetPlaylists(request);
                    }
                    else if (url.Contains("artwork"))
                    {
                        dacpResponse = GetArtworkResponse(request);
                    }
                    else if (url.Contains("browse/artists"))
                    {
                        dacpResponse = GetArtists(request);
                    }
                    else if (url.Contains("browse/genres"))
                    {
                        dacpResponse = GetGenres(request);
                    }
                    else if (url.Contains("browse/composers"))
                    {
                        dacpResponse = GetComposers(request);
                    }
                    else if (url.Contains("groups?") && url.Contains("type=music&group-type=albums"))
                    {
                        dacpResponse = GetAlbums(request);
                    }
                    else if (url.Contains("groups?") && url.Contains("type=music&group-type=artists"))
                    {
                        dacpResponse = GetArtists(request);
                    }
                    else if (url.Contains("items?") && url.Contains("query="))
                    {
                        dacpResponse = GetTracks(request);
                    }
                    else if (url.Contains("containers"))
                    {
                        if (url.Contains("action=add"))
                        {
                            dacpResponse = PlaylistAddTrack(request);
                        }
                        else if (url.Contains("action=remove"))
                        {
                            dacpResponse = PlaylistRemoveTrack(request);
                        }
                        else if (url.Contains("action=move"))
                        {
                            dacpResponse = PlaylistMoveTrack(request);
                        }
                        else if (url.Contains("action=rename"))
                        {
                            dacpResponse = PlaylistRename(request);
                            SessionBoundResponse.IncrementDatabaseRevision();
                        }
                        else if (url.Contains("action=refresh"))
                        {
                            dacpResponse = PlaylistRefresh(request);
                            SessionBoundResponse.IncrementDatabaseRevision();
                        }
                        else
                        {
                            dacpResponse = GetPlaylistTracks(request);
                        }
                    }
                    else if (url.Contains("edit?action=add"))
                    {
                        dacpResponse = PlaylistAdd(request);
                        SessionBoundResponse.IncrementDatabaseRevision();
                    }
                    else if (url.Contains("edit?action=remove"))
                    {
                        dacpResponse = PlaylistRemove(request);
                        SessionBoundResponse.IncrementDatabaseRevision();
                    }
                }
                else if (url.StartsWith("/ctrl-int/"))
                {
                    if (url.Contains("playstatusupdate"))
                    {
                        stopWatch    = null;
                        dacpResponse = GetCurrentPlayerStatus(request);
                    }
                    else if (url.Contains(ArtworkResponse.PROPERTY_NOW_PLAYING))
                    {
                        dacpResponse = GetArtworkResponse(request);
                    }
                    else if (url.Contains("cue?command=clear"))
                    {
                        if (PairingDatabase.RespectClearCueCommand)
                        {
                            ClearQueue = true;
                            ControlClearQueue(request);
                        }
                        else
                        {
                            ClearQueue = false;
                            Console.WriteLine("Clearing Playlist Cue disabled by RespectClearCueCommand in XML properties!");
                        }
                    }
                    else if (url.Contains("cue?command=play"))
                    {
                        // check for the clear flag
                        if (PairingDatabase.RespectClearCueCommand)
                        {
                            if (url.Contains("clear-first"))
                            {
                                ClearQueue = true;
                            }
                        }
                        QueueTracks(request, ClearQueue, true);
                    }
                    else if (url.Contains("cue?command=add"))
                    {
                        QueueTracks(request, false, false);
                    }
                    else if (url.Contains("playspec?"))
                    {
                        SetPlaylist(request);
                    }
                    else if (url.Contains("getproperty"))
                    {
                        dacpResponse = GetProperty(request);
                    }
                    else if (url.Contains("setproperty"))
                    {
                        dacpResponse = SetProperty(request);
                    }
                    else if (url.Contains("playpause"))
                    {
                        ControlPlayPause(request);
                    }
                    else if (url.Contains("pause"))
                    {
                        ControlPause(request);
                    }
                    else if (url.Contains("stop"))
                    {
                        ControlStop(request);
                    }
                    else if (url.Contains("nextitem"))
                    {
                        ControlNextItem(request);
                    }
                    else if (url.Contains("previtem"))
                    {
                        ControlPreviousItem(request);
                    }
                    else if (url.Contains("beginff"))
                    {
                        ControlFastForward(request);
                    }
                    else if (url.Contains("beginrew"))
                    {
                        ControlRewind(request);
                    }
                    else if (url.Contains("playresume"))
                    {
                        ControlPlayResume(request);
                    }
                    else if (url.Contains("items"))
                    {
                        dacpResponse = GetNowPlaying(request);
                    }
                    else if (url.Contains("getspeakers"))
                    {
                        dacpResponse = GetSpeakers(request);
                    }
                    else if (url.Contains("setspeakers"))
                    {
                        SetSpeakers(request);
                    }
                    else if (url.Contains("set-genius-seed"))
                    {
                        ControlGeniusSeed(request);
                    }
                    else
                    {
                        Console.WriteLine("Unknown URL type: {0}", request.RawUrl);
                    }
                }
                else
                {
                    Console.WriteLine("Unknown URL type: {0}", request.RawUrl);
                }

                // return a NO Content found if either null or is marker interface
                if ((dacpResponse == null) || (dacpResponse is INoContentResponse))
                {
                    response.StatusCode = DACPResponse.MSTT_NO_CONTENT;
                    return;
                }

                // return a 500 Internal Server Error
                if (dacpResponse is IErrorResponse)
                {
                    Console.WriteLine("500 Internal Server Error Response");
                    response.StatusCode = DACPResponse.MSTT_ERROR;
                    return;
                }

                // now output the DACPResponse as a binary byte message
                byte[] responseBytes = dacpResponse.GetBytes();
                if (isCompressed)
                {
                    response.AppendHeader("Content-Encoding", "gzip");
                    using (MemoryStream memoryStream = new MemoryStream(8092))  {
                        // Decide regular stream or gzip stream based on whether the response can be compressed or not
                        using (Stream writer = new GZipStream(memoryStream, CompressionMode.Compress))   {
                            writer.Write(responseBytes, 0, responseBytes.Length);
                        }
                        responseBytes = memoryStream.ToArray();
                    }
                }
                else
                {
                    response.AppendHeader("Content-Encoding", "utf-8");
                    response.ContentEncoding = Encoding.Unicode;
                }

                response.StatusCode = (int)HttpStatusCode.OK;
                response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
            } catch (Exception ex) {
                Console.WriteLine(this.GetApplicationName() + " Error: " + ex.Message, ex);
                response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
            } finally {
                if (stopWatch != null)
                {
                    // Get the elapsed time as a TimeSpan value.
                    TimeSpan ts = stopWatch.Elapsed;
                    if (ts.TotalMilliseconds > 2500)
                    {
                        Console.WriteLine("DACP Response Time Exceeded Threshold: {0,21} '{1}'", ts.TotalMilliseconds, url);
                    }
                    else
                    {
                        Console.WriteLine("DACP Response Time: {0,21}", ts.TotalMilliseconds);
                    }
                }
            }
        }