Example #1
0
        public static Stream DownloadWebBinary(string url)
        {
            try
            {
                AniDBRateLimiter.GetInstance().ensureRate();

                HttpWebResponse response = null;
                HttpWebRequest  webReq   = (HttpWebRequest)WebRequest.Create(url);
                // Note: some network proxies require the useragent string to be set or they will deny the http request
                // this is true for instance for EVERY thailand internet connection (also needs to be set for banners/episodethumbs and any other http request we send)
                webReq.UserAgent = "Anime2MP";
                webReq.Timeout   = 20000; // 20 seconds
                response         = (HttpWebResponse)webReq.GetResponse();

                if (response != null) // Get the stream associated with the response.
                {
                    return(response.GetResponseStream());
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error in APIUtils.DownloadWebBinary: {0}");
                return(null);
            }
        }
Example #2
0
        public void ForceReconnection()
        {
            try
            {
                if (JMMService.AnidbProcessor != null)
                {
                    logger.Info("Forcing reconnection to AniDB");
                    JMMService.AnidbProcessor.Dispose();
                    AniDBRateLimiter.GetInstance().ensureRate();

                    JMMService.AnidbProcessor.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password,
                                                   ServerSettings.AniDB_ServerAddress,
                                                   ServerSettings.AniDB_ServerPort, ServerSettings.AniDB_ClientPort);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.ToString());
            }
        }
Example #3
0
        public static string DownloadWebPage(string url)
        {
            try
            {
                AniDBRateLimiter.GetInstance().ensureRate();

                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
                webReq.Timeout = 20000; // 20 seconds
                webReq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
                webReq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
                HttpWebResponse WebResponse = (HttpWebResponse)webReq.GetResponse();

                Stream   responseStream = WebResponse.GetResponseStream();
                String   enco           = WebResponse.CharacterSet;
                Encoding encoding       = null;
                if (!String.IsNullOrEmpty(enco))
                {
                    encoding = Encoding.GetEncoding(WebResponse.CharacterSet);
                }
                if (encoding == null)
                {
                    encoding = Encoding.Default;
                }
                StreamReader Reader = new StreamReader(responseStream, encoding);

                string output = Reader.ReadToEnd();

                WebResponse.Close();
                responseStream.Close();

                return(output);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error in APIUtils.DownloadWebPage: {0}");
                return("");
            }
        }
Example #4
0
        public void ProcessCommand(ref Socket soUDP,
                                   ref IPEndPoint remoteIpEndPoint, string sessionID, Encoding enc)
        {
            this.sessionID = sessionID;
            Encoding changeencoding = null;

            encoding = enc;
            EndPoint RemotePoint = remoteIpEndPoint;

            mcommandText  = commandText;
            errorOccurred = false;

            AniDBRateLimiter.GetInstance().ensureRate();

            if (commandType != enAniDBCommandType.Ping)
            {
                if (commandType != enAniDBCommandType.Login)
                {
                    if (commandType != enAniDBCommandType.Logout && commandType != enAniDBCommandType.GetMyListStats)
                    {
                        mcommandText += "&";
                    }
                    mcommandText += "s=" + sessionID;
                }
                else
                {
                    encoding       = System.Text.Encoding.ASCII;
                    changeencoding = enc;
                    string encod = changeencoding.EncodingName;
                    if (changeencoding.EncodingName.StartsWith("Unicode"))
                    {
                        encod = "utf-16";
                    }
                    mcommandText += "&enc=" + encod;
                }
            }
            bool     multipart     = false;
            int      part          = 0;
            int      maxpart       = 1;
            string   fulldesc      = "";
            string   decodedstring = "";
            DateTime start         = DateTime.Now;

            do
            {
                if (part > 0)
                {
                    mcommandText = mcommandText.Replace("part=" + (part - 1).ToString(), "part=" + part.ToString());
                    AniDBRateLimiter.GetInstance().ensureRate();
                }
                if (commandType != enAniDBCommandType.Login)
                {
                    string msg = string.Format("UDP_COMMAND: {0}", mcommandText);
                    JMMService.LogToSystem(Constants.DBLogType.APIAniDBUDP, msg);
                }
                else
                {
                    //string msg = commandText.Replace(MainWindow.settings.Username, "******");
                    //msg = msg.Replace(MainWindow.settings.Password, "******");
                    //MyAnimeLog.Write("commandText: {0}", msg);
                }
                bool   repeatcmd;
                int    received;
                Byte[] byReceivedAdd = new Byte[2000]; // max length should actually be 1400
                do
                {
                    repeatcmd = false;
                    // Send Message
                    Byte[] SendByteAdd = Encoding.GetBytes(mcommandText.ToCharArray());

                    try
                    {
                        JMMService.LastAniDBMessage    = DateTime.Now;
                        JMMService.LastAniDBUDPMessage = DateTime.Now;
                        if (commandType != enAniDBCommandType.Ping)
                        {
                            JMMService.LastAniDBMessageNonPing = DateTime.Now;
                        }
                        else
                        {
                            JMMService.LastAniDBPing = DateTime.Now;
                        }

                        soUDP.SendTo(SendByteAdd, remoteIpEndPoint);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, ex.ToString());
                        //MyAnimeLog.Write(ex.ToString());
                        errorOccurred = true;
                        errorMessage  = ex.ToString();
                    }


                    // Receive Response
                    received = 0;
                    try
                    {
                        //MyAnimeLog.Write("soUDP.ReceiveTimeout = {0}", soUDP.ReceiveTimeout.ToString());


                        received = soUDP.ReceiveFrom(byReceivedAdd, ref RemotePoint);
                        JMMService.LastAniDBMessage    = DateTime.Now;
                        JMMService.LastAniDBUDPMessage = DateTime.Now;
                        if (commandType != enAniDBCommandType.Ping)
                        {
                            JMMService.LastAniDBMessageNonPing = DateTime.Now;
                        }
                        else
                        {
                            JMMService.LastAniDBPing = DateTime.Now;
                        }

                        //MyAnimeLog.Write("Buffer length = {0}", received.ToString());
                        if ((received > 2) && (byReceivedAdd[0] == 0) && (byReceivedAdd[1] == 0))
                        {
                            //deflate
                            Byte[] buff  = new byte[65536];
                            Byte[] input = new byte[received - 2];
                            Array.Copy(byReceivedAdd, 2, input, 0, received - 2);
                            Inflater inf = new Inflater(false);
                            inf.SetInput(input);
                            inf.Inflate(buff);
                            byReceivedAdd = buff;
                            received      = (int)inf.TotalOut;
                        }
                    }
                    catch (SocketException sex)
                    {
                        // most likely we have timed out
                        logger.Error(sex, sex.ToString());
                        errorOccurred = true;
                        errorMessage  = sex.ToString();
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, ex.ToString());
                        errorOccurred = true;
                        errorMessage  = ex.ToString();
                    }
                    if ((commandType == enAniDBCommandType.Login) && (byReceivedAdd[0] == 0xFE) &&
                        (byReceivedAdd[1] == 0xFF) &&
                        (byReceivedAdd[3] == 53) && (byReceivedAdd[5] != 53) &&
                        !Encoding.EncodingName.ToLower().StartsWith("unicode") && (changeencoding != null) &&
                        changeencoding.EncodingName.ToLower().StartsWith("unicode"))
                    {
                        //Previous Session used utf-16 and was not logged out, AniDB was not yet issued a timeout.
                        //AUTH command was not understand because it was encoded in ASCII.
                        encoding  = changeencoding;
                        repeatcmd = true;
                    }
                } while (repeatcmd);

                if (!errorOccurred)
                {
                    if (changeencoding != null)
                    {
                        encoding = changeencoding;
                    }
                    System.Text.Encoding enco;
                    if ((byReceivedAdd[0] == 0xFE) && (byReceivedAdd[1] == 0xFF))
                    {
                        enco = encoding;
                    }
                    else
                    {
                        enco = Encoding.ASCII;
                    }
                    decodedstring = enco.GetString(byReceivedAdd, 0, received);

                    if (decodedstring[0] == 0xFEFF) // remove BOM
                    {
                        decodedstring = decodedstring.Substring(1);
                    }
                    if (commandType == enAniDBCommandType.GetAnimeDescription ||
                        commandType == enAniDBCommandType.GetReview)
                    {
                        //Lets handle multipart
                        part++;
                        string[] sp1 = decodedstring.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                        if (sp1[0].StartsWith("233 ANIMEDESC") || sp1[0].StartsWith("233  ANIMEDESC"))
                        {
                            string[] sp2 = sp1[1].Split('|');
                            fulldesc += sp2[2];
                            maxpart   = int.Parse(sp2[1]);
                        }

                        if (sp1[0].StartsWith("234 REVIEW") || sp1[0].StartsWith("234  REVIEW"))
                        {
                            string[] sp2 = sp1[1].Split('|');

                            if (sp2.Length == 3)
                            {
                                fulldesc += sp2[2];
                            }
                            else
                            {
                                for (int i = 2; i < sp2.Length; i++)
                                {
                                    fulldesc += "|" + sp2[i];
                                }
                            }


                            maxpart = int.Parse(sp2[1]);
                        }
                        multipart = true;
                        if (part == maxpart)
                        {
                            decodedstring = sp1[0] + "\n0|1|" + fulldesc + "\n";
                            multipart     = false;
                        }
                    }
                }
            } while (multipart && !errorOccurred);

            if (errorOccurred)
            {
                socketResponse = string.Empty;
            }
            else
            {
                // there should be 2 newline characters in each response
                // the first is after the command .e.g "220 FILE"
                // the second is at the end of the data
                int i = 0, ipos = 0, foundpos = 0;
                foreach (char c in decodedstring)
                {
                    if (c == '\n')
                    {
                        //MyAnimeLog.Write("NEWLINE FOUND AT: {0}", ipos);
                        i++;
                        foundpos = ipos;
                    }
                    ipos++;
                }

                if (i != 2)
                {
                    socketResponse = decodedstring;

                    TimeSpan ts  = DateTime.Now - start;
                    string   msg = string.Format("UDP_RESPONSE in {0} ms - {1} ", ts.TotalMilliseconds, socketResponse);
                    JMMService.LogToSystem(Constants.DBLogType.APIAniDBUDP, msg);
                }
                else
                {
                    socketResponse = decodedstring.Substring(0, foundpos + 1);

                    TimeSpan ts  = DateTime.Now - start;
                    string   msg = string.Format("UDP_RESPONSE_TRUNC in {0}ms - {1} ", ts.TotalMilliseconds,
                                                 socketResponse);
                    JMMService.LogToSystem(Constants.DBLogType.APIAniDBUDP, msg);
                }
            }
            int val = 0;

            if (socketResponse.Length > 2)
            {
                int.TryParse(socketResponse.Substring(0, 3), out val);
            }
            this.ResponseCode = val;

            // if we get banned pause the command processor for a while
            // so we don't make the ban worse
            if (ResponseCode == 555)
            {
                JMMService.AnidbProcessor.IsBanned  = true;
                JMMService.AnidbProcessor.BanOrigin = "UDP";
            }
            else
            {
                JMMService.AnidbProcessor.IsBanned  = false;
                JMMService.AnidbProcessor.BanOrigin = "";
            }

            // 598 UNKNOWN COMMAND usually means we had connections issue
            // 506 INVALID SESSION
            // 505 ILLEGAL INPUT OR ACCESS DENIED
            // reset login status to start again
            if (ResponseCode == 598 || ResponseCode == 506 || ResponseCode == 506)
            {
                JMMService.AnidbProcessor.IsInvalidSession = true;
                logger.Trace("FORCING Logout because of invalid session");
                ForceReconnection();
            }

            // 600 INTERNAL SERVER ERROR
            // 601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
            // 602 SERVER BUSY - TRY AGAIN LATER
            // 604 TIMEOUT - DELAY AND RESUBMIT
            if (ResponseCode == 600 || ResponseCode == 601 || ResponseCode == 602 || ResponseCode == 604)
            {
                string errormsg = "";
                switch (ResponseCode)
                {
                case 600:
                    errormsg = "600 INTERNAL SERVER ERROR";
                    break;

                case 601:
                    errormsg = "601 ANIDB OUT OF SERVICE - TRY AGAIN LATER";
                    break;

                case 602:
                    errormsg = "602 SERVER BUSY - TRY AGAIN LATER";
                    break;

                case 604:
                    errormsg = "TIMEOUT - DELAY AND RESUBMIT";
                    break;
                }
                logger.Trace("FORCING Logout because of invalid session");
                JMMService.AnidbProcessor.ExtendPause(300, errormsg);
            }
        }