Ejemplo n.º 1
0
        private void ThreadProc()
        {
            //start our wcf service
            ServiceHost host = new ServiceHost(typeof(ProxyService));

            host.AddServiceEndpoint(typeof(ITrailerProxy), new NetNamedPipeBinding(), "net.pipe://localhost/MBTrailers");
            host.Open();
            //and initialize it
            using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
            {
                ITrailerProxy proxyServer = factory.CreateChannel();
                proxyServer.Init(this.cacheDir, this.port);
                (proxyServer as ICommunicationObject).Close();
            }

            TcpListener listener = new TcpListener(IPAddress.Loopback, port);

            listener.Start(10);
            while (true)
            {
                var client = listener.AcceptTcpClient();

                while (incomingConnections >= MAX_CONNECTIONS)
                {
                    Thread.Sleep(10);
                }

                Interlocked.Increment(ref incomingConnections);

                Logger.ReportInfo("Request accepted.  Queueing item.");

                ThreadPool.QueueUserWorkItem(_ => ServiceClient(client));
            }
        }
Ejemplo n.º 2
0
        public string ProxyUrl(MBTrailers.ITunesTrailer trailer)
        {
            Uri         uri         = new Uri(trailer.RealPath);
            ProxyInfo   proxyInfo   = new ProxyInfo(uri.Host, uri.PathAndQuery, ProxyInfo.ITunesUserAgent, uri.Port);
            TrailerInfo trailerInfo = new TrailerInfo(TrailerType.Remote, proxyInfo.LocalFilename, trailer.ParentalRating, trailer.Genres);

            using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
            {
                ITrailerProxy proxyServer = factory.CreateChannel();
                try
                {
                    proxyServer.SetProxyInfo(proxyInfo);
                    proxyServer.SetTrailerInfo(trailerInfo);
                }
                catch (Exception e)
                {
                    Logger.ReportException("Error setting proxy info", e);
                    Logger.ReportError("Inner Exception: " + e.InnerException.Message);
                }
                finally
                {
                    (proxyServer as ICommunicationObject).Close();
                }
            }

            var target = Path.Combine(cacheDir, proxyInfo.LocalFilename);

            return(File.Exists(target) ? target : string.Format("http://localhost:{0}/{1}", this.port, proxyInfo.LocalFilename));
        }
Ejemplo n.º 3
0
        public override void ValidateChildren()
        {
            System.Threading.Thread.Sleep(5000); //wait to be sure the service process is up...

            //only validate once per day or when forced or on service refresh
            if (Kernel.LoadContext == MBLoadContext.Service || Plugin.PluginOptions.Instance.Changed || DateTime.Now > lastUpdated.AddHours(23))
            {
                Logger.ReportInfo("MBTrailers validating MyTrailers " + lastUpdated);
                Plugin.PluginOptions.Instance.Changed = false;
                Plugin.PluginOptions.Save();
                lastUpdated = DateTime.Now;
                base.ValidateChildren();
                Kernel.Instance.ItemRepository.SaveItem(this);
            }
            else
            {
                //just go through our existing children and be sure the proxy has them in the list
                using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
                {
                    ITrailerProxy proxyServer = factory.CreateChannel();
                    try
                    {
                        foreach (Movie item in this.Children)
                        {
                            var trailerInfo = new TrailerInfo(TrailerType.Local, item.Path.ToLower(), item.ParentalRating, item.Genres);
                            proxyServer.SetTrailerInfo(trailerInfo);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.ReportException("Error setting trailer info", e);
                        Logger.ReportError("Inner Exception: " + e.InnerException.Message);
                    }
                    finally
                    {
                        (proxyServer as ICommunicationObject).Close();
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void SetTrailerInfo(MediaBrowser.Library.Entities.Show trailer)
        {
            TrailerInfo trailerInfo = new TrailerInfo(TrailerType.Local, trailer.Path.ToLower(), trailer.ParentalRating, trailer.Genres);

            using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
            {
                ITrailerProxy proxyServer = factory.CreateChannel();
                try
                {
                    proxyServer.SetTrailerInfo(trailerInfo);
                }
                catch (Exception e)
                {
                    Logger.ReportException("Error setting trailer info", e);
                    Logger.ReportError("Inner Exception: " + e.InnerException.Message);
                }
                finally
                {
                    (proxyServer as ICommunicationObject).Close();
                }
            }
        }
Ejemplo n.º 5
0
        public List <TrailerInfo> GetTrailers()
        {
            List <TrailerInfo> list = new List <TrailerInfo>();

            using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
            {
                ITrailerProxy proxyServer = factory.CreateChannel();
                try
                {
                    list = proxyServer.GetTrailerList();
                }
                catch (Exception e)
                {
                    Logger.ReportException("Error setting trailer info", e);
                    Logger.ReportError("Inner Exception: " + e.InnerException.Message);
                }
                finally
                {
                    (proxyServer as ICommunicationObject).Close();
                }
            }
            return(list);
        }
Ejemplo n.º 6
0
        private void ServiceClient(TcpClient client)
        {
            string requestedPath = "";
            var    stream        = client.GetStream();

            try {
                byte[]        buffer = new byte[8000];
                StringBuilder data   = new StringBuilder();
                bool          httpRequestComplete = false;
                while (client.Connected)
                {
                    if (stream.DataAvailable && !httpRequestComplete)
                    {
                        int bytes_read = stream.Read(buffer, 0, buffer.Length);
                        data.Append(ASCIIEncoding.ASCII.GetString(buffer, 0, bytes_read));

                        if (data.ToString().Contains("\r\n\r\n"))
                        {
                            Logger.ReportInfo("Request complete");
                            Logger.ReportInfo("Data were: " + data.ToString());
                            httpRequestComplete = true;
                        }
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }

                    if (httpRequestComplete)
                    {
                        ProxyInfo info;
                        var       headers = new HttpHeaders(data.ToString());
                        requestedPath = headers.Path.Replace("/", "");
                        using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
                        {
                            ITrailerProxy proxyServer = factory.CreateChannel();
                            info = proxyServer.GetProxyInfo(requestedPath);
                            (proxyServer as ICommunicationObject).Close();
                        }
                        if (info == null)
                        {
                            //probably a request from the player for art - ignore it
                            //Logger.ReportError("Unable to get info for item: " + requestedPath);
                            break;
                        }
                        var target = Path.Combine(cacheDir, info.LocalFilename);

                        if (File.Exists(target))
                        {
                            ServeStaticFile(stream, buffer, info, target);
                            break;
                        }

                        string cacheFile = Path.Combine(cacheDir, info.LocalFilename + ".tmp");

                        if (File.Exists(cacheFile))
                        {
                            ServeCachedFile(stream, cacheFile, info);
                            break;
                        }

                        try {
                            ProxyRemoteFile(stream, buffer, info, target, cacheFile);
                        } catch (Exception ee) {
                            Logger.ReportException("Failed to proxy file : " + requestedPath, ee);
                        }
                    }
                }
            } catch (Exception e) {
                Logger.ReportException("Failed to serve file : " + requestedPath, e);
            } finally {
                Interlocked.Decrement(ref incomingConnections);

                try
                {
                    Logger.ReportInfo("MB Trailers closing connections.");
                    stream.Close();
                    client.Close();
                }
                catch
                {
                    // well we tried
                }
            }
        }
Ejemplo n.º 7
0
        private void DownloadProc()
        {
            //background thread to download all the trailers - with throttling
            downloadInProgress = true;
            Logger.ReportInfo("MBTrailers Starting process to background download all trailers.  Max Bandwidth: " + maxBandwidth);
            List <ProxyInfo> proxiedFiles = new List <ProxyInfo>();

            using (ChannelFactory <ITrailerProxy> factory = new ChannelFactory <ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers"))
            {
                ITrailerProxy proxyServer = factory.CreateChannel();
                try
                {
                    proxiedFiles = proxyServer.GetProxiedFileList();
                }
                catch (Exception e)
                {
                    Logger.ReportException("Error getting proxy files in background downloader", e);
                    Logger.ReportError("Inner Exception: " + e.InnerException.Message);
                }
                finally
                {
                    (proxyServer as ICommunicationObject).Close();
                }
            }
            string target;

            foreach (var info in proxiedFiles)
            {
                target = Path.Combine(cacheDir, info.LocalFilename);

                if (File.Exists(target + ".tmp"))
                {
                    continue;                               //already downloaded or downloading
                }
                if (File.Exists(target))
                {
                    continue;                      //already downloaded and committed
                }
                //none of the local copies exist - go get it
                Logger.ReportInfo("MBTrailers Background downloading file: " + target + " Bytes per Second: " + maxBandwidth);

                TcpClient server = new TcpClient();
                server.Connect(info.Host, info.Port);

                var serverStream = server.GetStream();
                var writer       = new StreamWriter(serverStream);

                writer.Write(string.Format("GET {0} HTTP/1.1\r\n", info.Path));
                if (info.UserAgent != null)
                {
                    writer.Write(string.Format("User-Agent: {0}\r\n", info.UserAgent));
                }
                writer.Write(string.Format("Host: {0}\r\n", info.Host));
                writer.Write("Cache-Control: no-cache\r\n");
                writer.Write("\r\n");
                writer.Flush();



                FileStream fs;
                long       bufferSize = maxBandwidth > 8000 ? 8000 : maxBandwidth;
                byte[]     buffer     = new byte[bufferSize];

                using (fs = new FileStream(target + ".tmp", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read))
                {
                    var  bytesRead      = serverStream.Read(buffer, 0, buffer.Length);
                    long readThisSecond = bytesRead;


                    StringBuilder header        = new StringBuilder();
                    bool          gotHeader     = false;
                    int           contentLength = -1;
                    int           totalRead     = 0;
                    int           headerLength  = 0;
                    DateTime      start         = DateTime.Now;

                    while (bytesRead > 0)
                    {
                        if (!gotHeader)
                        {
                            header.Append(ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead));
                            string headerString = header.ToString();
                            if (headerString.Contains("\r\n\r\n"))
                            {
                                gotHeader = true;
                                foreach (var line in headerString.Split('\n'))
                                {
                                    if (line.StartsWith("Content-Length:"))
                                    //                   123456789123456
                                    {
                                        contentLength = int.Parse(line.Substring(16).Trim());
                                        //Logger.ReportInfo("Content Length " + contentLength);
                                    }
                                }

                                headerLength = headerString.IndexOf("\r\n\r\n") + 4;
                            }
                        }


                        lock (info)
                        {
                            info.BytesRead += bytesRead;
                        }
                        totalRead += bytesRead;

                        fs.Write(buffer, 0, bytesRead);

                        var amountToRead = buffer.Length;
                        if (contentLength > 0)
                        {
                            amountToRead = Math.Min(buffer.Length, (contentLength + headerLength) - totalRead);
                        }
                        if (amountToRead == 0)
                        {
                            break;
                        }
                        if (readThisSecond >= maxBandwidth)
                        {
                            var sleepTime = (int)(1000 - (DateTime.Now - start).TotalMilliseconds);
                            if (sleepTime > 0)
                            {
                                //Logger.ReportInfo(readThisSecond+"bytes read. Throttling... for " + sleepTime + "ms");
                                Thread.Sleep(sleepTime); //poor-man's throttling...
                            }
                            readThisSecond = 0;
                            start          = DateTime.Now;
                        }
                        bytesRead       = serverStream.Read(buffer, 0, amountToRead);
                        readThisSecond += bytesRead;
                    }

                    Logger.ReportInfo("Finished Downloading " + target);
                    // file was completely read ... rename it and strip header
                    CommitTempFile(fs, target);
                }
            }
            downloadInProgress = false;
            lastAutoDownload   = DateTime.Now;
        }