отправка get запроса

b1ba_
Offline
Зарегистрирован: 17.02.2021

первый  раз вообще работаю с вайфаем , подключил себе бесплатный ddns . Для обновления айпи , предлагает сделать следующее :

Попытался понять как делать этот запрос , у меня вышло следующее : 

 if (client.connect(ip_update_host,80)) { }
    client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=токен[цензура]&myip=");
    client.println ("HTTP/1.1");
    client.println ("Host: dynupdate.alviy.com");                       
    client.println();                                         
    client.println(); 

, в ответ получаю : 

Response of DDNS-Server:
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>cloudflare</center>
</body>
</html>

 

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

rkit
Offline
Зарегистрирован: 23.11.2016

Открывать esp8266 в интернет, да еще и под доменом - плохая затея. Будет падать от сканеров постоянно.

Ну и http запросы делаются библиотекой, а не вручную.

b1ba_
Offline
Зарегистрирован: 17.02.2021

а что мне еще делать? мне нужно как-то из вне отправить именно на мою esp пакет, так вот у нее постоянно меняется айпи , а ddns сервер знает какой он .Его роль отправить пакет моей esp , вне зависимости от ее айпи, который я могу не знать. я это делаю через библиотеки  <WiFiClient.h>  <ESP8266WiFi.h>  

sadman41
Offline
Зарегистрирован: 19.10.2016

Прям в голый сокет на 80-й порт валите текст? HTTP тоись устраиваете врукопашную? А GET должен по HTTPS производится.

Да и сам cloudfire побрить может, кстати, если IP не понравится.

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Ну, на самом-то деле уже неплохо. Только client должен быть clientSecure из WifiSecureClient.h, и порт 443. А cloudflare он такой, да.

b1ba_
Offline
Зарегистрирован: 17.02.2021

не могу нигде найти WifiSecureClient.h , можете дать ссылку? после смены порта  , выдал это : 

Response of DDNS-Server:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>cloudflare</center>
</body>
</html>

 

b1ba_
Offline
Зарегистрирован: 17.02.2021

если честно , вообще не понимаю , зачем указывать порт при подключении, разве этот порт тебе выдает не провайдер? NAT , он тебе дает внутренний порт , а при подключении , вообще его  меняет на свой.  А если и нужно , то зачем  и как мне узнать какой? 80 порт я увидел в примере другого человека , вот и написал. Максимально далек от этой темы...

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Cloudflare всё правильно написал, вы попытались отправить незашифрованный запрос на порт, который этого не ожидает. Кстати, CF также порежет довольно много сканеров, что в данном случае есть хорошо, хоть лично я и не особо люблю CF.

Библиотека WifiSecureClient (или WifiClientSecure, не помню) входит в поставку, и там даже есть пример https запроса, прямо в вашей IDE у вас на компе.

b1ba_ пишет:

если честно , вообще не понимаю , зачем указывать порт при подключении, разве этот порт тебе выдает не провайдер? NAT , он тебе дает внутренний порт , а при подключении , вообще его  меняет на свой.  А если и нужно , то зачем  и как мне узнать какой? 80 порт я увидел в примере другого человека , вот и написал. Максимально далек от этой темы...

Вы "подключаетесь" к комбинации ip-адрес + порт. Порт нужен потому, что на одном адресе может быть несколько служб, например, на 80м http-сервер, на 443м https сервер, на 27015 игровой сервер (все три запущены на одном компьютере, ip одинаковый), и порт нужен для того, чтобы определить, какой из трёх серверов получит ваш запрос.

С вашей стороны тоже присутствует ip+port, за натом или без, в случае клиента неважно, tcp-соединение устанавливается между двумя ip/port-ами. Ваш клиентский ip+port (ардуина esp) обращается к серверному ip+port-у (сервер dyndns), просто библиотека от вас это прячет.

Если максимально далеки - придётся подтянуться, без этих базовых знаний ничего не получится, только глумиться дальше будут.

b1ba_
Offline
Зарегистрирован: 17.02.2021

спасибо , разбираюсь по тихоньку. Переписал на HTTPS , удалось подключится , вот только в ответ получил 
 

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>

внизу написано про cloudflare , я так понимаю , что это его рук дело ,а не в неправильном запросе? 
скину код целиком ,На всякий случай :


#include <ESP8266WiFi.h>                                      // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
#include <WiFiClientSecure.h>                        // Библиотека для связи с сетевыми хостами (локальными и интернет)
#include <ESP8266WebServer.h>                                 // Библиотека для поднятия веб-сервера    ww

const char* ssid = "a1a";                                // Указываем имя WiFi-сети, к которой будет подключаться ESP8266
const char* password = "30";                            // Указываем пароль для подключения к WiFi-сети

const char* ip_update_host = "dynupdate.alviy.com";                      // Указываем хост (адрес сайта) службы DynDNS
const char fingerprint[] PROGMEM = "61 58 CC 6C C3 B8 00 96 DB 17 88 52 8A 4D 5E 11 0E DC DF 53";

ESP8266WebServer server(10200);                               // Создаём объект для работы с нашим веб-сервером, указав номер порта, по которому он будет доступен в WWW
WiFiClientSecure  client;                                            // Создаём объект для работы с удалёнными хостами

void setup(void){
  Serial.begin(9600);                                         // Инициализируем вывод данных на серийный порт со скоростью 9600 бод
  WiFi.begin(ssid, password);                                 // Соединяемся с WiFi-сетью 
  while (WiFi.status() != WL_CONNECTED)                       // Пока соединение не установено
    delay(500);                                               //  делаем задержку в пол секунды, пока соединение не установится
  Serial.println("WiFi connected");  
  Serial.print("Connected to ");
  Serial.println(ssid);// Выводим сообщение о том, что устройство соединилось с WiFi-сетью 
  server.begin();                                             // Инициализируем работу веб-сервера
  server.on("/", root);                                       // Сообщаем о том, что при обращении к корневой директории нашего веб-сервера должна вызываться функция root
  Serial.println("HTTP server started");                      // Выводим на монитор серийного порта сообщение о том, что веб-сервер запущен
  Serial.print("Local IP: ");                                 // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить локальный IP
  Serial.println(WiFi.localIP());                             // Выводим локальный IP-адрес ESP8266
  Serial.print("MAC-address: ");                              // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить MAC-адрес ESP8266
  Serial.println(WiFi.macAddress());                          // Выводим MAC-адрес ESP8266
  client.setFingerprint(fingerprint) ;
  ip_update();                                                // Вызываем функцию, обновляющую IP маршрутизатора (роутера) в службе динамических DNS
  
} 

void loop(void){

}

void ip_update(){                                             // Функция, обновляющая IP маршрутизатора (роутера) в службе динамических DNS
    
  while (!client.connect(ip_update_host,443)) { 
    Serial.println ("connection to ddns error");
    }
    Serial.println ("conection to ddns successfull!");
    Serial.println (" GET request senting...");
    
    client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=2f6памыпррыу71&myip="); //отправка запроса на обновление айпи в ddns
    client.println ("HTTPS/1.1");
    client.println ("Host: dynupdate.alviy.com");                
    client.println ("Connection: close");          
    client.println();                                         
    client.println(); 
                                       
    delay(200);                                               //  Задержка в 0.2 сек., чтобы дать удалённому серверу возможность обработать и отправить ответ на наш запрос
    Serial.println("\nResponse of DDNS-Server:");             //  Шлём в монитор серийного порта сообщение о том, что далее будет выводиться ответ от сервера службы DynDNS
    while (client.available()) {                              //  Пока сервер на связи
      char a = client.read();                                 //    считываем его ответ по одному символу 
      Serial.print(a);                                        //    и выводим на монитор серийного порта
    
    
    }
}
void root(){                                                   // Функция,вызывающаяся при обращении клиента к корневой дирректории нашего веб-сервера
  server.send(200, "text/html","<h1>Web-server ESP8266</h1>"); // Сервер отправляет клиенту информацию о том, что
}                                                              // 200 - запрос успешно обработан
                                                               // text/html - ответ на запрос предоставляется в формате HTML
                                                               // третий параметр (<h1>Web-server ESP8266</h1>) содержит текст ответа в формате HTML

 

что-то немного поправил, теперь получаю : 

14:51:42.554 -> Response of DDNS-Server:
14:51:42.554 -> ⸮
BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

403я ошибка - это ты обратился к серверу туда, куда доступ не всем разрешён. Проверь адрес и/или токен. 

b1ba_
Offline
Зарегистрирован: 17.02.2021

токен скопировал тот , что мне дал ddns , все правильно.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

В браузере у себя на пк пробовал по сформированному url заходить? Что получается?

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020
client.println ("HTTPS/1.1");

удалите, нету такого заголовка, не нужно такую херню слать серверу

client.println ("Connection: close"); 

это не обязательно отправлять в данном случае, всё равно же сами закрываете соединение, но это пофигу, не страшно, можно и отправлять

b1ba_
Offline
Зарегистрирован: 17.02.2021

с браузера удалось зайти.
переписал , как мне и сказали , удалив лишнее :

 client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=а87478141&myip=");
    client.println ("Host: dynupdate.alviy.com");                        
    client.println();                                         
    client.println(); 
                          

результат не изменился -  403.

b1ba_
Offline
Зарегистрирован: 17.02.2021

все же не в этом дело , ничего не изменилось .

 client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=2427507310535729057891&myip=");
    client.println ("Host: dynupdate.alviy.com");                        
    client.println();                                         
    client.println(); 

ответ : 403 .

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

ннууу

откройте новую вкладку браузера, нажмите ctrl+shift+i, откроются devtools

скопипастьте в эту вкладку ваш урл https://dynupdate.alviy.com/token/update?hostname=esp8266-x.dynnamn.ru&token=2234328371&myip= нажмите enter

в devtools откройте вкладку network, щёлкните на запрос, откроется ещё вкладка, там выберите headers и чуть промотайте вниз, до request headers

скопируйте оттуда, можете хоть всё, но я думаю хватит user-agent, accept-encoding и accept-language, и отправьте после заголовка Host: серверу

client.println ("accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
client.println ("accept-encoding: gzip, deflate, br");
client.println ("accept-language: en-US,en;q=0.9,ru;q=0.8");
client.println ("user-agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");

может, поможет, побороть cloudflare

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016
void ddnsUpdate(void) {

  WiFiClient client;
  HTTPClient http;
  const uint32_t DdnsUpdateInterval = 30ul*60ul*1000ul;
  static uint32_t lastUpdateDdns = millis();
  static bool isOK = false;
  String rq = "http:" +"//www." + "duckdns.org/update?domains=********&token=******************************=" + myIPv6;  

  if (!isOK || millis() - lastUpdateDdns > DdnsUpdateInterval) {
  lastUpdateDdns = millis();
  Serial.print("reques is:");
  Serial.println(rq);
  
  if (http.begin(client, rq)) {  

      int httpCode = http.GET();
      if (httpCode > 0) {
        Serial.printf("[HTTP] GET... code: %d\n", httpCode);
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = http.getString();
          Serial.println(payload);
          isOK = true;
        }
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
      }
      http.end();
  }}
}

Вот так это делается. Это ТОЧНО работает с DuckDNS. На 8266 (Вемос Д1). Мне было нужно с IPv6, но разницы никакой.

PS: Форум URL в коде переписывает... Чорт! Забыл как это обойти. Поделил URL на куски, так съел.

подключенные встроенные библиотеки:

#include <ESP8266WiFi.h>
#include <AddrList.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

 

b1ba_
Offline
Зарегистрирован: 17.02.2021

к сожалению не помогло ,вообще не понимаю ,зачем они туда поставили cloudflare? это же токен явно не  для ручного обновления айпи , напишу им в поддержку , а пока поищу другой бесплатный ddns.
Спасибо за помощь!