HTTP Klient: První Produktová Řada

Verze z 5. 7. 2021, 09:09, kterou vytvořil Adamn (diskuse | příspěvky) (Založena nová stránka s textem „ Tato stránka popisuje programovací jazyk '''SDS-C''', který je dostupný na vybraných zařízeních SDS. Některá zařízení používají FULL-C,…“)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Tato stránka popisuje programovací jazyk SDS-C, který je dostupný na vybraných zařízeních SDS. 
Některá zařízení používají FULL-C, pro který máme návody jinde na této WiKi.


Síťové funkce SDS-C: provedení HTTP GET respektive HTTP POST

Zařízení SDS umožňuje odeslat HTTP-GET, respektive HTTP-POST, dotaz na zvolený HTTP server. SDS-C program určuje cílový server (IP adresu a Host název), a současně určuje obsah (Body) v dotazu.

Za tímto účelem jsou k dispozici tyto dvě funkce:

 http_get  (ip[0], ip[1], ip[2], ip[3], 'host', ...geturl_text...);
 http_post (ip[0], ip[1], ip[2], ip[3], 'host', 'geturl', ...post_text...);

a doplňková funkce

 http_close();


Princip

SDS se po zavolání funkce http_get() / http_get() spojí s webovým serverem na zadané IP adrese a předá tomuto serveru GET/POST požadavek. Odpověď je pak v SDS zpracována a předána SDS-C programu.

Volbu, zda-li se jedná o GET nebo POST požadavek, provádí programátor právě volbou názvu použité funkce.


Detaily

Funkce vytvoří TCP spojení na vzdálený server, pošle HTTP GET/POST příkaz s uživatelem stanovenou URL cestou. Data, které server vrátí, můžete nechat uložit do pole ram[] (viz text dále), každopádně vždy je uložen návratový kód HTTP protokolu (číselná hodnota, např. 200 pro OK).

Uživatel si může sestavit libovolné parametry. Pozor, funkce neprovádí překódování speciálních znaků, tak jak jsou parametry předány funkci, tak jsou poslány ven. Neprovádí se URL ENCODE (to lze udělat ručně pomocí jiné SDS-C funkce) !


Maximální velikost odeslaných dat (z SDS na server)

Všechna SDS která mají SDS-C mají následující omezení:

  • HTTP GET: lze odeslat max 1395 znaků (bajtů) uživatelského obsahu (délka GET text)
  • HTTP POST: lze odeslat max 1339 znaků (bajtů) uživatelského obsahu (délka GET textu spolu s délkou POST textu)


http_get()

První čtyři vstupní parametry jsou IP adresa, následuje název host (rozlišení pro více serverů na stejné IP), a všechny následující parametry jsou seskládány do GET požadavku. Pokud žádné další parametry nezadáte, je vytvořen prázdný GET /.

  http_get(ip[0],ip[1],ip[2],ip[3], 'host', ...geturl_text...);

Proč je potřeba zadávat jak jednak IP adresu, tak i název host? Protože častá praxe poskytovatelů webového prostoru je ta, že na jedné společné IP adrese je stroj, který poskytuje celou řadu virtuálních serverů. Protože je však potřeba adresovat konkrétní server, je potřeba vyplnit jak IP (adresa serveru - stroje) tak i položku host (konkrétní webový server na společném stroji). Pokud není rozlišení přes 'host' nutné, vyplňte danou položku IP adresou (takže tam bude jednak IP na začátku jako čísla, a pak zopakovaná jako text).

Důležitá informace: 'host' je jen jedna položka (parametr funkce), všechny následující parametry jsou již vloženy do URL.

Důležitá informace: 'host' se předává 1:1 do hlavičky odeslané webovému serveru. Proto můžete do 'host' napsat pouze text, který přímo webový server akceptuje. Nelze tam psát jakékoliv doplňky, které vás napadnou (např. www.x.qa:80 to je špatně, to :80 je tam navíc - nepište to tam, ale naopak použijte sys[76]).


Příklad:

- vytvoří spojení na server (zadaný vždy pomocí IP) a pošle požadavek GET /store.php?teplota1=2205 (pozn. hodnota 2205 je aktuálním obsahem systémové proměnné, viz kód příkladu).

 http_get(10,20,0,85, 'www.foo.com', '/store.php?teplota1=', sys[310]);

Vždy musíte zadat IP adresu (a také správně vyplnit parametr 'host'). Pokud máte pracovat s textovou (URL) adresou serveru, musíte samozřejmě nejprve využít DNS pomocí dns_resolv() funkce, tím se získá IP a to se pak dosadí jako parametry do http_get().

Od verze SDS-C č. 03 máte možnost změnit TCP port, na kterém je provedena komunikace s WWW serverem. Změnu musíte provést před zavoláním funkce http_get(). Jakmile funkci zavoláte, další změny se již na prováděné komunikaci neprojeví - ale až pro další zavolání funkce. Změna se provádí zápisem platného čísla portu do systémové proměnné (viz seznam).

Pozor, po zavolání funkce http_get() je spuštěn proces komunikace s webovým serverem, ale je to prováděno "na pozadí", tzn. SDS-C program dále pokračuje v práci (lze tedy dělat další věci), ovšem program nesmí zapomenout na kontrolu průběhu spuštěné aktivity a správně reagovat.

Důležité: Před zavoláním funkce http_get() musí být všechny ostatní "OSI7" funkce (např. smtp_send() atd.) plně ukončeny (s výjimkou modbus-client a mqtt-client).

NÁVRATOVÉ HODNOTY - viz OSI7 stavové hodnoty


HTTP GET hlavička

Veškerá data jsou přenášeny jako text/plain, a SDS neprovádí URL encode !

Od verze SDS-C 09 vypadá hlavička takto:

GET xxxTEXTxxx HTTP/1.1
Host: xxxHOSTxxx
Pragma: no-cache
Connection: close

Toto je celý HTTP GET požadavek odeslaný na cílový webový server.


Příklad

 /* tento příklad získá stav webového serveru www.onlinetechnology.cz, konkrétně www.onlinetechnology.cz/index.html */

 // nelze zacit pokud neni aktivni sit (ethernet)
wait_for_eth:
 if (sys[24] == 0) goto wait_for_eth;

 // ethernet je zapojen, muzeme pokracovat

 // nelze zacit pokud neni pridelena platna IP adresa
wait_for_ipaddr:
 if (sys[27] == 0) goto wait_for_ipaddr;

 // --- priklad HTTP GET:

 // port WWW serveru
 sys[76] = 80; // eventualne si cislo portu upravte dle sveho serveru

 // provedeme DNS překlad
 dns_resolv('www.onlinetechnology.cz');

 // pockam az probehne funkce do konce
label cekam_na_dns:
 if (sys[65] == 0) goto cekam_na_dns; 

 // otestujeme úspěch DNS překladu
 if (sys[65] != 512) goto preskocit_protoze_chyba_DNS;

 // a posledni povinny test 
 if (sys[65] == 128) // -> 128 : funkce prerusena kvuli vypadku Ethernet
  goto jina_chyba;


 // OK, mame IP ziskanou pomoci DNS (ta je tedy v sys[66] - sys[69])


 // takze: volame http_get, chceme stahnout soubor "index.html"
 
 http_get(sys[66],sys[67],sys[68],sys[69], 'www.onlinetechnology.cz', '/index.html');

 // nejprve test jestli se to vubec spustilo
 if (sys[65] == 1029)
  goto moc_brzo_musim_jeste_cekat;

 // CEKACI SMYCKA:

 // pockam az probehne funkce do konce
label cekam_na_http:

 // stala se nejaka chyba ? (1025, 1026, atd. . . . )
 if (sys[65] > 1024) goto chyba_www_serveru;

 // zatim pracuje, takze cekam dale
 if (sys[65] != 1024) goto cekam_na_http; 

 // HOTOVO: mame vysledek (1024)

 // overime navratovou hodnotu
 if (sys[75] != 200) goto chyba_www_serveru;

 // je to 200 OK
 echo('Server hlasi 200 OK    - HOTOVO');

 // vse hotovo
 goto final;

label preskocit_protoze_chyba_DNS:
 // obsluha chyby - např. provést chybové hlášení na konzoli

 echo('Chyba, nelze provest DNS preklad.');

 goto final;

label chyba_www_serveru:
 // obsluha chyby - www server

 echo('Chyba, www server nedostupny nebo nevratil 200 OK - konkretni http kod je: ',sys[75]);

 goto final;

label moc_brzo_musim_jeste_cekat:
 // 1029

 echo('Volani http_get bylo moc brzo, protoze se jeste nedokoncila predchozi zavolana funkce.');

 goto final;

label jina_chyba:
 // jina chyba

 echo('Jina chyba: ',sys[65]);

 //
label final:

 //konec prikladu


Všimněte si způsobu, jakým je zpracováván stav sys[65] v tomto ukázkovém programu.


Poznámky

Od verze SDS-C č. 04 je k dispozici možnost uložit uživatelem určený počet bajtů (viz příslušný sys[]) z textu, vráceného serverem. Tyto data se ukládají do pole ram[] od indexu [1], kde index [0] obsahuje skutečný počet uložených znaků, vše viz detaily v popisu systémových proměnných. Tuto funkci můžete ovládat nebo zakázat (nedojde k přepsání ram[]) nastavením příslušné systémové proměnné.

Od verze SDS-C č. 06 je k dispozici možnost uložit uživatelem určený počet bajtů (viz příslušný sys[]) z textu, vráceného serverem do pole text[]. Provede se to nastavením sys[77] na hodnotu 2 (hodnota 1 naopak zapíše výsledek do pole ram[] a hodnota 0 zakáže jakýkoliv zápis přijatých dat). I při volbě zápisu do pole text[] se zapisuje skutečně přijatý počet znaků do položky ram[0].

Od verze SDS-C č. 06 je rozšířen datový prostor celé zprávy. To znamená, že je možné posílat o něco větší celkovou HTTP zprávu na server, než v předchozích verzích. Velikost rozšíření je různá podle typu SDS.


http_post()

Funkce je prakticky shodná se vším co bylo uvedeno pro http_get(), jsou zde pouze tyto dva zásadní rozdíly:

  • specifický způsob zápisu parametrů při volání funkce
  • webový server dostane POST požadavek

Zadávání parametrů se tedy specificky (od http_get() funkce) liší, a to tak, že pro GET URL je napevno určen jen jeden jediný parametr (ihned za HOST parametrem), a pak už jsou všechny následující parametry sloučeny do POST body textu.


Příklad

Kód příkladu je stejný jako výše pro http_get(), s tím rozdílem, že samozřejmě zavoláte http_post()

  http_post(sys[66],sys[67],sys[68],sys[69], 'www.onlinetechnology.cz', '/form.php', 'hodnota1=', sys[310] ,'&hodnota2=', sys[311]);

Odeslaný POST v rámci takového příkladu pak má následující datový text (body) (pozn. číselné hodnoty v sys jsou smyšlené pro tento příklad):

hodnota1=2205&hodnota2=-1200

Samozřejmě formát obsahu POST body si určujete sami (respektive vývojář webového serveru, který daný POST požadavek má přijmout).


HTTP POST hlavička

Veškerá data jsou přenášeny jako text/plain, a SDS neprovádí URL encode !

POST xxxTEXTxxx HTTP/1.1
Host: xxxHOSTxxx
Pragma: no-cache
Content-Type: text/plain
Content-Length: xxxLENxxx
Connection: close

xxxPOSTTEXTxxx

Cílový webový server tedy dostává všechny potřebné údaje.


http_close()

K dispozici v aktuálním firmware (nejstarší FW tuto funkci nenabízí!).

Umožňuje slušným způsobem uzavřít tcp spojení na server (SDS pošle TCP FIN).

Využívá se, pokud už nechcete aby váš SDS-C program čekal na další část odpovědi ze serveru.

Obvykle to není potřeba, ale mohou nastat specifické případy. Nelze totiž chtít po SDS aby se provedl další a další http_get/post, dokud není plně ukončen a uzavřen právě probíhající. A pokud se délka odpovědi ze serveru liší, tak je spojení stále otevřeno - a váš program tak může spojení zavřít sám, kdy uzná za vhodné (např. podle odpovědi), právě touto funkcí.

Obecně ale není tato funkce vůbec potřeba, využijete ji skutečné jen ve specializovaných případech.


Obecné poznámky

TCP spojení se pro každé volání otevře NOVÉ, a ihned po provedení dojde jeho uzavření. Což je žádoucí a záměr.

Co v případě nefunkčnosti ?

Vždy správně kontrolujte všechny sys[], potřebné minimum je uvedeno v příkladu.

V případě že HTTP klient nefunguje na vašem SDS, zkontrolujte si důvod - právě přes tyto sys[] prvky.

Informace

Pokud chcete odesílat větší počet dat (ze SDS na server) než je nahoře uvedené omezení, musíte použít takové SDS která má FULL-C programovací jazyk. SDS se SDS-C programovacím jazykem mají tato výše uvedená omezení pevná a nelze s tím nic udělat.

Dlouho trvající ukončení http_get nebo http_post ?

Je to záležitost chování serveru. SDS odesílá "connection:close" a umožňuje ukončit spojení dříve (pokud dojde vámi očekávaný počet bajtů odpovědi, nebo když zavoláte http_close funkci). Nicméně, dokud SDS nedostane vámi nastavený (a očekávaný) počet bajtů v odpovědi od serveru, je tcp spojení na server stále otevřené. Záleží pak čistě na serveru kdy jej slušně uzavře, respektive zda-li dříve nevyprší delší timout na SDS (a pak to uzavře SDS). Pokud nechcete čekat, musíte použít výše zmíněné metody.