Ejemplo n.º 1
0
        /// <summary>
        /// Parses the Shoutcast specific headers.  This method is different because of how Shoutcast responds to an HttpWebRequest.  The headers need to be parsed, then removed from the initialBuffer.
        /// </summary>
        /// <param name="initialBuffer">Initial data buffer from the audio stream.</param>
        /// <returns>ShoutcastStreamInformation containing information about the audio stream.</returns>
        private ShoutcastStreamInformation ParseShoutcastHeaders(ref byte[] initialBuffer)
        {
            ShoutcastStreamInformation result = null;
            int byteCount = 0;
            Dictionary<string, string> responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            // We may have a REAL ICY stream
            MemoryStream stream = null;
            try
            {
                stream = new MemoryStream(initialBuffer, false);
                using (StreamReader reader = new StreamReader(stream, this.metadataEncoding, true))
                {
                    // This is to resolve CA2202.
                    stream = null;

                    // Read until we get a blank line.  This is SUCH a bad and unsafe way to parse "http" headers.
                    List<string> headerLines = new List<string>();
                    string line;
                    string responseHeader;
                    HttpStatusCode status = HttpStatusCode.NotFound;
                    string statusDescription = string.Empty;

                    // Get the ICY header
                    responseHeader = reader.ReadLine();
                    string[] headerParts = responseHeader.Split(' ');
                    if (headerParts.Length >= 2)
                    {
                        string s = headerParts[1];
                        status = (HttpStatusCode)int.Parse(s);
                        if (headerParts.Length >= 3)
                        {
                            string str3 = headerParts[2];
                            for (int i = 3; i < headerParts.Length; i++)
                            {
                                str3 = str3 + " " + headerParts[i];
                            }

                            statusDescription = str3;
                        }
                    }

                    if (status != HttpStatusCode.OK)
                    {
                        // Bail!
                        return result;
                    }

                    byteCount = responseHeader.Length + 2;
                    while (!string.IsNullOrEmpty((line = reader.ReadLine())))
                    {
                        headerLines.Add(line);
                    }

                    // We should be pointing right at the data now! :)
                    // Parse the headers
                    foreach (string headerLine in headerLines)
                    {
                        byteCount += this.metadataEncoding.GetByteCount(headerLine) + 2;
                        int colonIndex = headerLine.IndexOf(':');
                        string key = headerLine.Substring(0, colonIndex);
                        string value = headerLine.Substring(colonIndex + 1).Trim();

                        // We are going to not duplicate headers for now, as this requires order parsing, comma appending, etc.
                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
                        if (!responseHeaders.ContainsKey(key))
                        {
                            responseHeaders.Add(key, value);
                        }
                    }

                    // Add the last CRLF
                    byteCount += 2;
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                }
            }

            // Resize the initialBuffer to reflect the headers we've read.
            int newBufferLength = initialBuffer.Length - byteCount;
            byte[] tempBuffer = initialBuffer;
            initialBuffer = new byte[newBufferLength];
            Array.Copy(tempBuffer, byteCount, initialBuffer, 0, newBufferLength);

            result = new ShoutcastStreamInformation(responseHeaders);

            if (result.MetadataInterval == -1)
            {
                // TODO - Fix this!!!
                return null;
            }

            return result;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses the headers from the audio stream.
        /// </summary>
        /// <param name="httpWebResponse">HttpWebResponse from the server sending the audio stream.</param>
        /// <param name="initialBuffer">Initial data buffer from the audio stream.</param>
        /// <returns>ShoutcastStreamInformation containing information about the audio stream.</returns>
        private ShoutcastStreamInformation FindStreamInformation(HttpWebResponse httpWebResponse, ref byte[] initialBuffer)
        {
            if (httpWebResponse == null)
            {
                throw new ArgumentNullException("httpWebResponse");
            }

            if (initialBuffer == null)
            {
                throw new ArgumentNullException("initialBuffer");
            }

            ShoutcastStreamInformation result = null;

            // See if we are a Shoutcast stream.
            if (string.IsNullOrEmpty(httpWebResponse.Headers[HttpRequestHeader.ContentType]))
            {
                // We may have a REAL ICY stream
                result = this.ParseShoutcastHeaders(ref initialBuffer);
            }
            else
            {
                // We are a non-Shoutcast server stream, so we can assign the information here.
                result = new ShoutcastStreamInformation(httpWebResponse.Headers.ToDictionary());
            }

            return result;
        }