• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed [Arduino C++] Wczytywanie kontentu z requestu get do serwera

VPS Starter Arubacloud
0 głosów
125 wizyt
pytanie zadane 14 marca 2022 w C i C++ przez Marak123 Stary wyjadacz (11,190 p.)
zamknięte 12 maja 2022 przez Marak123

Witam smiley

Mam problem z wczytaniem contentu z zapytania typu get do githuba o pobranie zawartości z pliku w repozytorium.

To jest link do pliku na githubie który pobieram z serwera i chcę wczytać jego zawartość. https://api.github.com/repos/Marak123/test/git/blobs/2228adff467aa743f438ec03a3585857a06ef6e2

Ma on ponad 1MB jest to plik z obrazem SPIFFS do ESP32 bo robię automatyczny updater ESP32 który będzie się samemu aktualizował gdy wykryje aktualizację.

Tylko ze pobierać się pobiera i jest fajnie mam cały nagłówek i według nagłówka cały kontent ale gdy próbuję wczytać ten kontent to nie wczytuje się cały tylko gdzieś tak do połowy i jest to tak naprawdę losowo raz więcej się wczyta raz mniej a nie raz nawet cały się wczyta i nie wiem o co chodzi.

To są metody wczytywania które probowałem:

String response = "";
for(int i=0; i<contentLength; i++){
   int c = client.read();
   if(c == -1 && c == 0){
      i--;
      continue;
   }
   ile++;
   response += (char)c;
}
Serial.println(response);
 while (client.available()) {
   char c = client.read();
   Serial.write(c);
 }
while (client.connected()) {
   String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
   }
 }
String content = "";
while (client.available()) {
                content += client.readStringUntil('\n');
}

 

Niektóre metody wziąłem z neta ale i tak nie działają żadna z powyższych nie wczytuje całego kontentu za każdym razem. Wie ktoś może dlaczego tak się może dziać?? 

Dodam jeszcze ze mniejszy plik ok. 200 kb wczytało parę razy cały kontent ale jeżeli chodzi o plik który ma 1.5MB to nigdy mi nie wczytało go jeszcze całego. 

Ma ktoś jakieś pomysły??

Edit::

Do pobrania kontektu używam biblioteki WifiClient

To jest kod pobierania danych:

const char github_cert [] PROGMEM = R"CERT(
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
)CERT";

const char* github_host = "api.github.com";
const uint16_t github_port = 443;
String github_token = "token";

WiFiClientSecure client;
client.setCACert(github_cert);

if(!client.connect(github_host, github_port)){
   Serial.println("Failed to connect to server");
   return;
}
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
   "Host: " + github_host + "\r\n" +
   "Cache-Control: no-cache\r\n" +
   "User-Agent: Awesome-Octocat-App\r\n" +
   "Authorization: token " + github_token + "\r\n" +
   "Connection: close\r\n\r\n");

unsigned long timeout = millis();
while (client.available() == 0) {
   if (millis() - timeout > 5000) {
      Serial.println("Client Timeout!");
      client.stop();
      return;
   }
}

while (client.available()) {
   String line = client.readStringUntil('\n');
   Serial.println(line);
   line.trim();

   if(!line.length()) break;
   if (line.startsWith("HTTP/1.1")) {
      if (line.indexOf("200") < 0) {
         Serial.println("Got a non 200 status code from server. Exiting OTA Update.");
        break;
      }
   }
   if (line.startsWith("Content-Length: ")) {
      contentLength = atol((line.substring(strlen(String("Content-Length: ").c_str()))).c_str());
      Serial.println("Got " + String(contentLength) + " bytes from server");
   }
   if (line.startsWith("Content-Type: ")) {
      String contentType = line.substring(strlen(String("Content-Type: ").c_str()));
      Serial.println("Got " + contentType + " payload.");
      if (contentType == "application/octet-stream") {
         isValidContentType = true;
      }
   }
}

 

komentarz zamknięcia: Problem rozwiązany, za mała pamięć ram

1 odpowiedź

+1 głos
odpowiedź 14 marca 2022 przez Oscar Nałogowiec (29,290 p.)
wybrane 12 maja 2022 przez Marak123
 
Najlepsza

Rozumiem, że ta funkcja służy od odczytania danych:

String response = "";
for(int i=0; i<contentLength; i++){
   int c = client.read();
   if(c == -1 && c == 0){
      i--;
      continue;
   }
   ile++;
   response += (char)c;
}
Serial.println(response);

Dziwny masz warunek - c nie może być -1 i jednocześnie 0. W ogóle dlaczego chcesz specjalnie traktować 0? Nie przewidujesz bajtu o takiej wartości w odpowiedzi?

Czy zmienna typu String może przechowywać bajt o wartości 0?

Może lepiej użyć po prostu tablicy bajtów?

 

komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)
No nie ale zrobiłem to do sprawdzenia bo 0 to jest null ale tylko sprawdzałem bo męczę się z tym już od paru dni i nie wiem co mam zrobić aby wczytało całość więc różnego typu kombinacje z myślą ze zadziała.
komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)
I tak to jest jedna z funkcji którą napisałem aby sprawdzić czy zadziała i odczyta całość.
komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)

@Oscar, odnośnie warunku to tam miało być "||" - or, lub 

komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)
W jakim sensie tablic bajtów uint8_t czy co bo i tak muszę to wrzucić na String aby na json zamienić i odczytać tylko komórkę content z pobrane obiektu.
komentarz 14 marca 2022 przez Oscar Nałogowiec (29,290 p.)
Sprawdziłem ten link - faktycznie odbierasz tekst (json), więc zero nie powinno się pojawić. Początkowo zakładałem, że ściągasz plik binarny bezpośrednio. Kiedyś robiłem update firmwaru po HTTP, i po prostu użyłem If-modified-since. Wystarczyło wgrać nową wersję na serwer i przy najbliższej okazji się updatowało.

Masz w ogóle ponad 2MB wolnego ramu w tym urządzeniu?
komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)
Ty teraz to mi oczy otworzyłeś esp32 w wersji której mam ma 512kb pamięci ram xd.

Więc nie wczytam takiego pliku. Jakiś pomysł jak w takim razie zrobić update z taką przestrzenią pamięci??
komentarz 14 marca 2022 przez Marak123 Stary wyjadacz (11,190 p.)
A odnośnie tego If-modified-since to dobry pomysł tylko że ja nie chcę zastępować nowego oprogramowania nowym tylko aby istniały także starsze wersje aby nie zmuszać urządzenia do aktualizacji tylko aby istniało prawo wyboru przez użytkownika. Ale dzięki za protip przyda się na pewno kiedyś.

Podobne pytania

0 głosów
1 odpowiedź 286 wizyt
+1 głos
0 odpowiedzi 243 wizyt
pytanie zadane 1 maja 2021 w C i C++ przez Marak123 Stary wyjadacz (11,190 p.)
0 głosów
1 odpowiedź 521 wizyt
pytanie zadane 28 kwietnia 2021 w C i C++ przez Marak123 Stary wyjadacz (11,190 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...