LINUX.ORG.RU

Растолкуйте почему так?

 


0

1

Я тут по совету одного регистранта решил кое-что автоматизировать на своем предприятии.

Данная программа должна проверять доступность сайтов из белого списка, и недоступность их черного.

Пока занимаюсь белым списком.

Столкнулся с тем, что для некоторых сайтов прилетает ошибка доступа, хотя в браузере они открываются нормально. Аналих показал, что как правило это редирект, или уже совсем непонятно почему сайт возвращает страницу вместе с ошибкой 403, например.

using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Reflection;

namespace ConsoleApp1
{
    class Program
    {
        public static List <String> RequestResult = new List<string>();

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            TryToGetUrl("http://wlist.edu-nv.ru/export.txt");

            while(RequestResult.Count == 0)
            {
                Thread.Sleep(10);
            };

            String[] WList = RequestResult[0].Split('\n');

            foreach(string WListUrl in WList)
            {
                if (WListUrl != "")
                {
                    TryToGetUrlWithCheck(WListUrl);
                    Thread.Sleep(100);
                }
                else
                    continue;
            }

            Console.ReadKey();
        }

        static async void TryToGetUrl(String Url)
        {
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(Url);                  
                    response.EnsureSuccessStatusCode();
                    string responseBody = await response.Content.ReadAsStringAsync();
                    RequestResult.Add(responseBody);
                    LogAdd(Url + " - Ok!");
                }
                catch (HttpRequestException e)
                {
                    LogAdd(e.Message + " - " + Url);
                }                
            }
        }

        static async void TryToGetUrlWithCheck(String Url)
        {
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    client.Timeout = System.TimeSpan.FromSeconds(30);
                    HttpResponseMessage response = await client.GetAsync(Url);
                    response.EnsureSuccessStatusCode();
                    if (response.IsSuccessStatusCode)
                    {
                        LogAdd(Url + " - Ok!");
                    }
                }
                catch (HttpRequestException e)
                {
                    LogAdd(e.Message + " - " + Url);
                }
            }
        }

        public static void LogAdd(string Msg)
        {
            try
            {
                string path = @"" + Assembly.GetExecutingAssembly().Location + "-" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                StreamWriter sw = File.AppendText(path);
                sw.WriteLine(DateTime.Now.ToString() + " " + Msg);
                sw.Close();
            }
            catch (Exception ex)
            {
            }
        }
    }
}

Прошу так же покритиковать ход мысли в работе с асинхронными методами.


доступность сайтов из белого списка, и недоступность их черного.

Роскомпозоровец?

Гоните его! Насмехайтесь над ним! Баньте его!

anonymous
()

юзерагент поставь как у браузера
сайты специально проверяют всякие фиговины, чтобы ботов обламывать

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

А ещё можно поставить юзерагент гуглобота и получить доступ в интересные места. А уж если айпишник гугловский, ух разогнаться можно!

anonymous
()
Ответ на: комментарий от anonymous

Неа, это в школах положено чтобы были доступны только сайты из белого списка

Shulman
() автор топика
Ответ на: комментарий от Bad_ptr

Получилось, теперь остался один загадочный вариант с перебросом на https, все остальные сайты открылись, а из там штук 300;

Shulman
() автор топика

Прошу так же покритиковать

ты пишешь код как говно

anonymous
()

Я тут по совету одного регистранта

- Вот главная ошибка ! Советы надо слушать только от анонимусов !

anonymous
()
Ответ на: комментарий от Shulman

Пистон - яп общего назначения, почему ты думаешь, что он только для веб? Портаж на нём написан, например. Это что - веб?

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Вроде бы Visual Studio работает с пистоном. Можно бы попробовать.

Shulman
() автор топика
Ответ на: комментарий от crutch_master

Скажите, а питон православнее Dot Net Core?

А в GUI там можно через сторонние библиотеки, так?

А за питон платят 100К рублей, за Dot Net платят...

Читаю Wiki...

Shulman
() автор топика
Последнее исправление: Shulman (всего исправлений: 1)
Ответ на: комментарий от Shulman

 using (HttpClient client = new HttpClient())
{
 ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
 ServicePointManager.ServerCertificateValidationCallback = 
(z,x,c,v)=>true;

  client.GetAsync();
 ......
}
CrazyAlex25 ★★★
()
Ответ на: комментарий от CrazyAlex25

Понял что ServerCertificateValidationCallback это проверка валидности сертификата, но не пойму саму конструкцию... может подскажите?

Shulman
() автор топика
Ответ на: комментарий от Shulman

ServerCertificateValidationCallback принимает делегат. Я его просто описал лямбдой. Примерно так можно обрабатывать разрешённые домены и сертификаты

...
ServicePointManager.ServerCertificateValidationCallback = ValidateCert;

....

    protected static ValidateCert(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
    {

        // set a list of servers for which cert validation errors will be ignored
        var overrideCerts = new string[]
        {
            "myproblemserver",
            "someotherserver",
            "localhost"
        };

        // if the server is in the override list, then ignore any validation errors
        var serverName = cert.Subject.ToLower();
        if (overrideCerts.Any(overrideName => serverName.Contains(overrideName))) return true;

        // otherwise use the standard validation results
        return errors == SslPolicyErrors.None;
    }

CrazyAlex25 ★★★
()
Последнее исправление: CrazyAlex25 (всего исправлений: 1)

Какая из строчек лишняя?

response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
Выкидывается исключение если не IsSuccessStatusCode, если нет исключения значит if (response.IsSuccessStatusCode) всегда истино. Я бы оставил проверку IsSuccessStatusCode вместо исключения, тк блок try.. catch медленне чем проверка кода ошибки.
String[] WList = RequestResult[0].Split('\n');
Если не получится скачать список, то получишь исключение при доступе к RequestResult[0]. Лучше
String[] WList = RequestResult.FirstOrDefault()?.Split('\n'); if(Wlist!=null)...

CrazyAlex25 ★★★
()
Последнее исправление: CrazyAlex25 (всего исправлений: 1)
Ответ на: комментарий от CrazyAlex25

Какая из строчек лишняя?

Получается, если нет обработчика try, программа прерывается.

Я тут нарыл код кастомного обработчика, и он вроде работает. Вопрос остался по двум сайтам, а именно

Error! - NotFound http://росметодкабинет.рф

NotFound — возникает и для других сайтов, но для этого сайта в Хроме происходит перенаправление на http://росметодкабинет.рф/Новости

Что я пока не понял как работает.

По второму ошибка периодически возникает, но это видимо связано с работой сайта.

Большое спасибо за ответы!

Shulman
() автор топика
Последнее исправление: Shulman (всего исправлений: 2)
Ответ на: комментарий от CrazyAlex25

Я его в код руками вносил, он все равно не найден. К тому же там есть и другие русскоязычные домены, и они отрабатывают норм

Shulman
() автор топика
Ответ на: комментарий от Shulman

Сейчас тоже просто передал кирилический домен. Исключение: Невозможно разрешить удаленное имя: 'росметодкабинет.рф'. Есть подозрение что httpclient не умеет в русские домены. Или Нужно конвертировать их.

CrazyAlex25 ★★★
()
Ответ на: комментарий от CrazyAlex25

Решение: В app.config добавить

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <uri>
    <idn enabled="All" />
    <iriParsing enabled="true" />
  </uri>
</configuration>

И вместо string Url использовать new Uri(Url); т.е будет client.GetAsync(new Uri(Url));

CrazyAlex25 ★★★
()
Последнее исправление: CrazyAlex25 (всего исправлений: 1)
Ответ на: комментарий от CrazyAlex25

Еще раз уточню, все остальные домены русскими буквами нормально отработали...

Но вы все равно помогли.

Shulman
() автор топика
Ответ на: комментарий от CrazyAlex25
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Net;
using System.Threading.Tasks;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        public static List <String> RequestResult = new List<string>();
        public static bool WlistCheckComplited = false;
        public static HttpClient client = new HttpClient(new GlobalRedirectHandler(new HttpClientHandler()));

        static void Main(string[] args)
        {
            Console.WriteLine("Running!");

            client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36");
            client.Timeout = System.TimeSpan.FromSeconds(30);

            //TryToGetUrl("http://wlist.edu-nv.ru/export.txt");

            //while (RequestResult.Count == 0)
            //{
            //    Thread.Sleep(10);
            //};

            //String[] WList = RequestResult[0].Split('\n');

            //foreach (string WListUrl in WList)
            //{
            //    if (WListUrl != "")
            //    {
            //        TryToGetUrlWithCheck(WListUrl);
            //        Thread.Sleep(100);
            //    }
            //    else
            //        continue;
            //}

            String[] BList = File.ReadAllText(@"C:\share\BlackList.txt").Split('\n');
            foreach (string BListUrl in BList)
            {
                if (BListUrl != "")
                {
                    TryToGetUrlWithCheck(BListUrl);
                    Thread.Sleep(100);
                }
                else
                    continue;
            }

            //TryToGetUrlWithCheck("http://росметодкабинет.рф/Новости/");
            //TryToGetUrlWithCheck("http://росметодкабинет.рф");

            Console.ReadKey();
        }

        static async void TryToGetUrl(String Url)
        {

            // Call asynchronous network methods in a try/catch block to handle exceptions
            try
            {                
                HttpResponseMessage response = await client.GetAsync(Url);                  
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                RequestResult.Add(responseBody);
                // Above three lines can be replaced with new helper method below
                // string responseBody = await client.GetStringAsync(uri);

                //Console.WriteLine(responseBody);
                LogAdd("Ok! - " + Url);
            }
            catch (HttpRequestException e)
            {
                LogAdd(e.Message + " - " + Url);
            }                

        }

        static async void TryToGetUrlWithCheck(String Url)
        {
            HttpResponseMessage response = new HttpResponseMessage();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
            ServicePointManager.ServerCertificateValidationCallback = (z, x, c, v) => true;
            try { 
                response = await client.GetAsync(Url);
                //if ((int)response.StatusCode == 200 || (int)response.StatusCode == 201)
                //    LogAdd(Url + " - Ok!");
                //else
                //    response.EnsureSuccessStatusCode();
                switch ((int)response.StatusCode)
                {
                    case 200:
                    case 201:
                        LogAdd("Ok! - " + Url);
                        break;
                    default:
                        LogAdd("Error! - " + response.StatusCode.ToString() + " " + Url);
                        break;
                }
            }
            catch (HttpRequestException e)
            {
                LogAdd("Error! - " + e.Message + " " + Url);
            }
        }

        public static void LogAdd(string Msg)
        {
            try
            {
                string path = @"" + Assembly.GetExecutingAssembly().Location + "-" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                StreamWriter sw = File.AppendText(path);
                sw.WriteLine(DateTime.Now.ToString() + " " + Msg);
                sw.Close();
            }
            catch (Exception ex)
            {
            }


        }
    }

    public class GlobalRedirectHandler : DelegatingHandler
    {

        public GlobalRedirectHandler(HttpMessageHandler innerHandler)
        {
            InnerHandler = innerHandler;
        }

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource<HttpResponseMessage>();

            base.SendAsync(request, cancellationToken).ContinueWith(t =>
                    {
                        HttpResponseMessage response;
                        try
                        {
                            response = t.Result;
                        }
                        catch (Exception e)
                        {
                            response = new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
                            response.ReasonPhrase = e.Message;
                        }
                        if (response.StatusCode == HttpStatusCode.MovedPermanently
                            || response.StatusCode == HttpStatusCode.Moved
                            || response.StatusCode == HttpStatusCode.Redirect
                            || response.StatusCode == HttpStatusCode.Found
                            || response.StatusCode == HttpStatusCode.SeeOther
                            || response.StatusCode == HttpStatusCode.RedirectKeepVerb
                            || response.StatusCode == HttpStatusCode.TemporaryRedirect

                            || (int)response.StatusCode == 308)
                        {

                            var newRequest = CopyRequest(response.RequestMessage);

                            if (response.StatusCode == HttpStatusCode.Redirect
                                || response.StatusCode == HttpStatusCode.Found
                                || response.StatusCode == HttpStatusCode.SeeOther)
                            {
                                newRequest.Content = null;
                                newRequest.Method = HttpMethod.Get;

                            }
                            //newRequest.RequestUri = response.Headers.Location;
                            //Program.LogAdd(newRequest.RequestUri.ToString());
                            base.SendAsync(newRequest, cancellationToken).ContinueWith(t2 => tcs.SetResult(t2.Result));
                        }
                        else
                        {
                            tcs.SetResult(response);
                        }
                    }
                );

            return tcs.Task;
        }

        private static HttpRequestMessage CopyRequest(HttpRequestMessage oldRequest)
        {
            var newrequest = new HttpRequestMessage(oldRequest.Method, oldRequest.RequestUri);

            foreach (var header in oldRequest.Headers)
            {
                newrequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }
            foreach (var property in oldRequest.Properties)
            {
                newrequest.Properties.Add(property);
            }
            if (oldRequest.Content != null)
                newrequest.Content = new StreamContent(oldRequest.Content.ReadAsStreamAsync().Result);
            return newrequest;
        }
    }
}
Shulman
() автор топика

Защита от ботов м.б. Попробуй через puppeter

Int0l ★★
()

Прошу так же покритиковать ход мысли в работе с асинхронными методами.

Регистранты, лавсанчка кастаните :)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.