Функция WebRequest возвращает несуществующий HTTP код

 

В описании функции WebRequest сказано, что она возвращает код ответа HTTP-сервера либо -1 в случае ошибки. Имеется исчерпывающий перечень кодов ответа HTTP-сервера. Следовательно, можно ожидать, что эта функция вернёт один из кодов, описанных в RFC или -1. Но мне она вернула совсем другое.

Вот этот нехитрый код:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {
   char post[], result[];
   string headers, response, url = "https://api.telegram.org/bot375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s/getMe"; 
   int res = WebRequest ( "GET" , url , NULL , NULL , 30000 , post , 0 , result , headers );
   if ( res == - 1 ) {
      Print ( "WebRequest error " , GetLastError() );
      Print ( "result = " , CharArrayToString ( result ) );
      Print ( "headers = " , headers );
      return;
   }
   if ( res != 200 ) {
      Print ( "Bad HTTP response code: " , (string)res );
      Print ( "LastError = " , GetLastError() );
      Print ( "result = " , CharArrayToString ( result ) );
      Print ( "headers = " , headers );
      return;
   }
   response = CharArrayToString ( result );
   Print ( response );
}

возвращает совершенно неожиданный результат:

В настройках терминала установлено разрешение WebRequest для URL https://api.telegram.org

Функция не вернула -1, следовательно, запрос был выполнен и ошибки не было. Однако HTTP кода 1001 не существует и функция GetLastError при этом возвращает код 5203 (ошибка в результате выполнения HTTP запроса). Получается, что проверять нужно не только значение, возвращаемое функцией WebRequest, но ещё и отсутствие ошибки времени выполнения после вызова этой функции?

Дальше самое загадочное.

Если значение параметра url вставить в адресную строку браузера Google Chrome на этом же компьютере (Windows 7, 32bit), то мы получаем ответ сервера с кодом 401 и текстом {"ok":false,"error_code":401,"description":"Unauthorized"}. Именно этот результат я ожидал получить скриптом. Но почему-то получил ошибку.

При этом, если этот же скрипт запустить на другой машине (Windows Server 2012 R2, 64bit), то он работает так, как ожидается:


Пожалуйста, подскажите, почему такое может происходить? 

 


 

Обычно, если функция WebRequest не даёт нужного результата, я призываю на помощь wininet.dll. 

Так, вот, в данном случе попытка пойти этим путём приводит к тому, что системная функция InternetOpenUrlW вызывает системную же ошибку 12007: ERROR_INTERNET_NAME_NOT_RESOLVED, описанную здесь как "The server name could not be resolved". При этом, повторюсь, в браузере этот URL открывается нормально. 

 
Janis Ozols:

Обычно, если функция WebRequest не даёт нужного результата, я призываю на помощь wininet.dll. 

Так, вот, в данном случе попытка пойти этим путём приводит к тому, что системная функция InternetOpenUrlW вызывает системную же ошибку 12007: ERROR_INTERNET_NAME_NOT_RESOLVED, описанную здесь как "The server name could not be resolved". При этом, повторюсь, в браузере этот URL открывается нормально. 

Плохой подход, не отправлять заголовок

string Head="Content-Type: application/x-www-form-urlencoded";
 
не знаю, в тему или не в тему. Может что то из этого подойдёт https://www.mql5.com/ru/forum/342293/page31#comment_16683716 
и снова dll и маркет
и снова dll и маркет
  • 2020.06.02
  • www.mql5.com
День добрый! Правило №1 dll на Маркете запрещен...
 
Vitaly Muzichenko:

Плохой подход, не отправлять заголовок

Я полагал, что первый вариант функции WebRequest, описанный в документации так:

Отправляет HTTP-запрос на указанный сервер. Существует два варианта функции:

1. Для отправки простых запросов вида "ключ=значение" с использованием заголовка Content-Type: application/x-www-form-urlencoded.

добавляет этот заголовок автоматически.
 

Учтите, что у таких сервисов стоят фильтры/антидос/анализаторы, которые запросто после нескольких неправильных запросов блокируют доступ на некоторое время.

1001 означает, что даже физического коннекта нет.
 
Janis Ozols:

Я полагал, что первый вариант функции WebRequest, описанный в документации так:

добавляет этот заголовок автоматически.

Если не ошибаюсь, то WebRequest - это обёртка .dll

Если так, то нужно о всех данных позаботится самому.

 
Janis Ozols:

В описании функции WebRequest сказано, что она возвращает код ответа HTTP-сервера либо -1 в случае ошибки. Имеется исчерпывающий перечень кодов ответа HTTP-сервера. Следовательно, можно ожидать, что эта функция вернёт один из кодов, описанных в RFC или -1. Но мне она вернула совсем другое.

1001 = API not reachable

500 = Cannot connect to API

У меня 1001 было при блокировке Телеграма.

 

Еще, api.telegram.org  работает по IPv4 и IPv6.

Если у вас локальный адрес IPv6, то терминал пытается подключиться по IPv6.

Мы недавно в бетах исправляли подключения к IPv6, так что рекомендую обновить MT5 на последнюю бету и еще раз попробовать.

 
Renat Fatkhullin:

Еще, api.telegram.org  работает по IPv4 и IPv6.

Если у вас локальный адрес IPv6, то терминал пытается подключиться по IPv6.

Мы недавно в бетах исправляли подключения к IPv6, так что рекомендую обновить MT5 на последнюю бету и еще раз попробовать.

К сожалению, я не могу воспользоваться этой рекомендацией вот по этой причине. На другой машине, где установлен Windows Server 2012 R2 x64 и МТ5 build 2815, всё работает нормально.

Уже догадываюсь, какая рекомендация сейчас последует ;)
Но я пишу скрипт не только для себя и не могу предположить, где другие люди будут его запускать.

Видимо, есть что-такое на сервере api.telegram.org, что он не принимает запросы, сделанные через WinAPI из Windows 7 x32. А браузер делает эти запросы как-то по другому. Потому что на другие хосты, в том числе mql5.com, запросы из того же скрипта отправляются и обрабатываются хорошо.

 
Edgar Akhmadeev:


1001 = API not reachable

500 = Cannot connect to API

А где вы нашли описание ошибки 1001? Я не смог обнаружить её в документации.

Edgar Akhmadeev:


У меня 1001 было при блокировке Телеграма.

Если бы это была блокировка, то, наверное, запрос через браузер тоже бы не прошёл.

Причина обращения: