예제 #1
0
파일: AVPlayList.cs 프로젝트: Scannow/SWYH
        /// <summary>
        /// This method gets called when a new Request is received
        /// </summary>
        /// <param name="request"></param>
        /// <param name="WebSession"></param>
        protected void ReceiveSink(HTTPMessage request, HTTPSession WebSession)
        {
            HTTPMessage rsp = new HTTPMessage();
            UTF8Encoding U = new UTF8Encoding();

            if ((request.Directive == "HEAD") ||
                (request.Directive == "GET"))
            {
                if (request.DirectiveObj == "/item.m3u")
                {/*
					rsp.StatusCode = 200;
					rsp.StatusData = "OK";
					rsp.ContentType = "audio/mpegurl";
					rsp.StringBuffer = M3UString;
					*/

                    string r = request.GetTag("Range");
                    if (r == "")
                    {
                        rsp.StatusCode = 200;
                        rsp.StatusData = "OK";
                        rsp.ContentType = "audio/mpegurl";
                        rsp.StringBuffer = M3UString;
                    }
                    else
                    {
                        rsp.StatusCode = 206;
                        rsp.StatusData = "Partial Content";
                        rsp.ContentType = "audio/mpegurl";

                        DText rp0 = new DText();
                        rp0.ATTRMARK = "=";
                        rp0[0] = r;
                        DText rp = new DText();
                        rp.ATTRMARK = "-";
                        rp[0] = rp0[2].Trim();
                        if (rp[1] == "")
                        {
                            // LastBytes
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length)
                                {
                                    rsp.AddTag("Content-Range", "bytes 0-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString;
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + (M3UString.Length - int.Parse(rp[2])).ToString() + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(M3UString.Length - int.Parse(rp[2]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else if (rp[2] == "")
                        {
                            // Offset till end
                            try
                            {
                                rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }

                        }
                        else
                        {
                            // Range
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length + 1)
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + (M3UString.Length - 1).ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + rp[2] + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]), 1 + int.Parse(rp[2]) - int.Parse(rp[1]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        int i = request.DirectiveObj.LastIndexOf("/");
                        string tmp = request.DirectiveObj.Substring(1, i - 1);
                        bool hasRange = true;
                        if (tmp.IndexOf("/") != -1)
                        {
                            tmp = tmp.Substring(0, tmp.IndexOf("/"));
                        }

                        if (FileInfoTable.ContainsKey(tmp))
                        {
                            FileInfo f;
                            if (FileInfoTable[tmp].GetType() == typeof(string))
                            {
                                f = new FileInfo((string)FileInfoTable[tmp]);
                                FileInfoTable[tmp] = f;
                            }
                            else
                            {
                                f = (FileInfo)FileInfoTable[tmp];
                            }
                            ProtocolInfoString pis = ProtocolInfoString.CreateHttpGetProtocolInfoString(f);
                            rsp.StatusCode = 200;
                            rsp.StatusData = "OK";
                            rsp.ContentType = pis.MimeType;
                            if (request.Directive == "HEAD")
                            {
                                rsp.AddTag("Content-Length", f.Length.ToString());
                                rsp.OverrideContentLength = true;
                            }
                            else
                            {
                                HTTPSession.Range[] RNG = null;
                                if (request.GetTag("Range") != "")
                                {
                                    long x, y;
                                    ArrayList RList = new ArrayList();
                                    DText rp = new DText();
                                    rp.ATTRMARK = "=";
                                    rp.MULTMARK = ",";
                                    rp.SUBVMARK = "-";
                                    rp[0] = request.GetTag("Range");

                                    for (int I = 1; I <= rp.DCOUNT(2); ++I)
                                    {
                                        if (rp[2, I, 1] == "")
                                        {
                                            // Final Bytes
                                            y = long.Parse(rp[2, I, 2].Trim());
                                            x = f.Length - y;
                                            y = x + y;
                                        }
                                        else if (rp[2, I, 2] == "")
                                        {
                                            // Offset till end
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = f.Length - x;
                                        }
                                        else
                                        {
                                            // Full Range
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = long.Parse(rp[2, I, 2].Trim());
                                        }
                                        RList.Add(new HTTPSession.Range(x, 1 + y - x));
                                    }
                                    RNG = (HTTPSession.Range[])RList.ToArray(typeof(HTTPSession.Range));
                                }
                                else
                                {
                                    hasRange = false;
                                }

                                if (request.Version == "1.0")
                                {
                                    WebSession.OnStreamDone += new HTTPSession.StreamDoneHandler(DoneSink);
                                }
                                //								((HTTPMessage)(new UPnPDebugObject(WebSession)).GetField("Headers")).Version = "1.0";
                                if (hasRange)
                                {
                                    WebSession.SendStreamObject(f.OpenRead(), RNG, pis.MimeType);
                                }
                                else
                                {
                                    FileStream fs = f.OpenRead();
                                    long length = fs.Length;
                                    WebSession.SendStreamObject(fs, length, pis.MimeType);
                                }
                                return;
                            }
                        }
                        else
                        {
                            rsp.StatusCode = 404;
                            rsp.StatusData = "Not Found";
                        }
                    }
                    catch (Exception)
                    {
                        rsp.StatusCode = 404;
                        rsp.StatusData = "Not Found";
                    }
                }
                WebSession.Send(rsp);
                return;
            }

            rsp.StatusCode = 500;
            rsp.StatusData = "Not implemented";
            WebSession.Send(rsp);
        }
        /// <summary>
        /// This method gets called when a new Request is received
        /// </summary>
        /// <param name="request"></param>
        /// <param name="WebSession"></param>
        protected void ReceiveSink(HTTPMessage request, HTTPSession WebSession)
        {
            HTTPMessage  rsp = new HTTPMessage();
            UTF8Encoding U   = new UTF8Encoding();

            if ((request.Directive == "HEAD") ||
                (request.Directive == "GET"))
            {
                if (request.DirectiveObj == "/item.m3u")
                {/*
                  *                     rsp.StatusCode = 200;
                  *                     rsp.StatusData = "OK";
                  *                     rsp.ContentType = "audio/mpegurl";
                  *                     rsp.StringBuffer = M3UString;
                  */
                    string r = request.GetTag("Range");
                    if (r == "")
                    {
                        rsp.StatusCode   = 200;
                        rsp.StatusData   = "OK";
                        rsp.ContentType  = "audio/mpegurl";
                        rsp.StringBuffer = M3UString;
                    }
                    else
                    {
                        rsp.StatusCode  = 206;
                        rsp.StatusData  = "Partial Content";
                        rsp.ContentType = "audio/mpegurl";

                        DText rp0 = new DText();
                        rp0.ATTRMARK = "=";
                        rp0[0]       = r;
                        DText rp = new DText();
                        rp.ATTRMARK = "-";
                        rp[0]       = rp0[2].Trim();
                        if (rp[1] == "")
                        {
                            // LastBytes
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length)
                                {
                                    rsp.AddTag("Content-Range", "bytes 0-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString;
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + (M3UString.Length - int.Parse(rp[2])).ToString() + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(M3UString.Length - int.Parse(rp[2]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else if (rp[2] == "")
                        {
                            // Offset till end
                            try
                            {
                                rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else
                        {
                            // Range
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length + 1)
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + (M3UString.Length - 1).ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + rp[2] + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]), 1 + int.Parse(rp[2]) - int.Parse(rp[1]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        int    i        = request.DirectiveObj.LastIndexOf("/");
                        string tmp      = request.DirectiveObj.Substring(1, i - 1);
                        bool   hasRange = true;
                        if (tmp.IndexOf("/") != -1)
                        {
                            tmp = tmp.Substring(0, tmp.IndexOf("/"));
                        }

                        if (FileInfoTable.ContainsKey(tmp))
                        {
                            FileInfo f;
                            if (FileInfoTable[tmp].GetType() == typeof(string))
                            {
                                f = new FileInfo((string)FileInfoTable[tmp]);
                                FileInfoTable[tmp] = f;
                            }
                            else
                            {
                                f = (FileInfo)FileInfoTable[tmp];
                            }
                            ProtocolInfoString pis = ProtocolInfoString.CreateHttpGetProtocolInfoString(f);
                            rsp.StatusCode  = 200;
                            rsp.StatusData  = "OK";
                            rsp.ContentType = pis.MimeType;
                            if (request.Directive == "HEAD")
                            {
                                rsp.AddTag("Content-Length", f.Length.ToString());
                                rsp.OverrideContentLength = true;
                            }
                            else
                            {
                                HTTPSession.Range[] RNG = null;
                                if (request.GetTag("Range") != "")
                                {
                                    long      x, y;
                                    ArrayList RList = new ArrayList();
                                    DText     rp    = new DText();
                                    rp.ATTRMARK = "=";
                                    rp.MULTMARK = ",";
                                    rp.SUBVMARK = "-";
                                    rp[0]       = request.GetTag("Range");

                                    for (int I = 1; I <= rp.DCOUNT(2); ++I)
                                    {
                                        if (rp[2, I, 1] == "")
                                        {
                                            // Final Bytes
                                            y = long.Parse(rp[2, I, 2].Trim());
                                            x = f.Length - y;
                                            y = x + y;
                                        }
                                        else if (rp[2, I, 2] == "")
                                        {
                                            // Offset till end
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = f.Length - x;
                                        }
                                        else
                                        {
                                            // Full Range
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = long.Parse(rp[2, I, 2].Trim());
                                        }
                                        RList.Add(new HTTPSession.Range(x, 1 + y - x));
                                    }
                                    RNG = (HTTPSession.Range[])RList.ToArray(typeof(HTTPSession.Range));
                                }
                                else
                                {
                                    hasRange = false;
                                }

                                if (request.Version == "1.0")
                                {
                                    WebSession.OnStreamDone += new HTTPSession.StreamDoneHandler(DoneSink);
                                }
                                //								((HTTPMessage)(new UPnPDebugObject(WebSession)).GetField("Headers")).Version = "1.0";
                                if (hasRange)
                                {
                                    WebSession.SendStreamObject(f.OpenRead(), RNG, pis.MimeType);
                                }
                                else
                                {
                                    FileStream fs     = f.OpenRead();
                                    long       length = fs.Length;
                                    WebSession.SendStreamObject(fs, length, pis.MimeType);
                                }
                                return;
                            }
                        }
                        else
                        {
                            rsp.StatusCode = 404;
                            rsp.StatusData = "Not Found";
                        }
                    }
                    catch (Exception)
                    {
                        rsp.StatusCode = 404;
                        rsp.StatusData = "Not Found";
                    }
                }
                WebSession.Send(rsp);
                return;
            }

            rsp.StatusCode = 500;
            rsp.StatusData = "Not implemented";
            WebSession.Send(rsp);
        }
예제 #3
0
        private void SendStreamObject(HTTPSession webSession, HTTPMessage msg, string fileName)
        {
            Stream stream = null;

            try
            {
                if (!fileName.Contains("/"))
                {
                    fileName = HttpUtility.UrlDecode(fileName);
                }
                string str       = (fileName[0] == '1' ? fileName.Substring(2, fileName.LastIndexOf('/') - 2) : fileName.Substring(2));
                int    idx       = str.Length;
                string freeboxV5 = GetString(str, ref idx);
                string file      = str.Substring(0, idx);

                string mimeType      = null;
                long   contentLength = -1;
                bool   liveStream    = MimeType.IsLiveStream(file);
                string rangeStr      = (msg == null ? null : msg.GetTag("RANGE"));
                List <HTTPSession.Range> rangeSets = new List <HTTPSession.Range>();
                if (!String.IsNullOrEmpty(rangeStr))
                {
                    rangeStr = rangeStr.Trim().ToLower();
                }

                if (liveStream)
                {
                    Web.CreateWebRequest(rangeSets, rangeStr, file, ref stream, ref contentLength, ref mimeType);
                    if (!String.IsNullOrEmpty(mimeType) && mimeType.ToUpperInvariant() == "AUDIO/X-SCPLS")
                    {
                        file = new PLSPlaylist().GetMediaUrl(Web.GetStringAndCloseStream(stream, Encoding.UTF8));
                        Web.CreateWebRequest(rangeSets, rangeStr, file, ref stream, ref contentLength, ref mimeType);
                    }
                }
                else
                {
                    stream   = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
                    mimeType = MimeType.GetMimeTypeFromFileName(file);
                }

                if (stream == null)
                {
                    SendErrorMessage(webSession, null);
                    return;
                }

                bool canSeek = stream.CanSeek;
                if (canSeek)
                {
                    contentLength = stream.Length;
                }

                PreventSystemStandBy();
                if (msg != null && String.Compare(msg.Directive, "HEAD", true) == 0)
                {
                    HTTPMessage head = new HTTPMessage();
                    head.StatusCode  = 200;
                    head.StatusData  = "OK";
                    head.ContentType = mimeType;
                    if (contentLength >= 0)
                    {
                        head.OverrideContentLength = true;
                        if (String.IsNullOrEmpty(rangeStr))
                        {
                            head.AddTag("Content-Length", contentLength.ToString());
                            head.AddTag("Accept-Ranges", "bytes");
                        }
                        else
                        {
                            head.StatusCode = 206;
                            rangeSets.AddRange(rangeStr.Trim().ToLower(), contentLength);
                            if (rangeSets.Count == 1)
                            {
                                HTTPSession.Range range = rangeSets[0];
                                head.AddTag("Content-Range", "bytes " + range.Position.ToString() + "-" + ((long)(range.Position + range.Length - 1)).ToString() + "/" + contentLength.ToString());
                                head.AddTag("Content-Length", range.Length.ToString());
                            }
                        }
                    }
                    else
                    {
                        // Can't calculate length => can't do range
                        head.AddTag("Accept-Ranges", "none");
                    }

                    webSession.Send(head);
                }
                else
                {
                    if (canSeek && contentLength >= 0 && rangeSets.Count == 0)
                    {
                        rangeSets.AddRange(rangeStr, contentLength);
                    }

                    lock (webSession)
                    {
                        webSession.OnStreamDone += new HTTPSession.StreamDoneHandler(WebSession_OnStreamDone);
                        if (freeboxV5 == "1" && mimeType == "audio/mpeg")
                        {
                            webSession.StateObject = file;
                        }

                        bool image = (MimeType.GetMediaKind(mimeType) == MediaKind.Image);
                        if (freeboxV5 == "1")
                        {
                            if (!image)
                            {
                                webSession.BUFFER_SIZE = Settings.Default.V5BufferSize;
                            }
                        }
                        else
                        {
                            webSession.BUFFER_SIZE = Settings.Default.V6BufferSize;
                        }

                        if (rangeSets.Count > 0)
                        {
                            webSession.SendStreamObject(stream, rangeSets.ToArray(), mimeType);
                        }
                        else
                        {
                            if (canSeek)
                            {
                                stream.Seek(0, SeekOrigin.Begin);
                            }
                            if (contentLength >= 0)
                            {
                                webSession.SendStreamObject(stream, contentLength, mimeType, image);
                            }
                            else
                            {
                                webSession.SendStreamObject(stream, mimeType);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.WriteException(ex);
                SendErrorMessage(webSession, stream);
            }
        }