Na urovni TCP dostane potvrzeni (66 bajtovy packet). Na urovni php scriptu by funkce connection_aborted() vratila true. Pravdepodobne by prisla vyjimka pri pokusu o print do rozpadnuteho spojeni. Server ovsem nema sanci zjistit, co klient dostal a co zustalo nekde po ceste.
3. 11. 2022, 10:48 editováno autorem komentáře
Přijde mi trochu zavádějící (a možná i zbytečné) argumentovat počtem bajtů v klasickém http spojení, když většina komunikace jede na http2. To tuhle matematiku (pro opakované dotazy) mění.
Mimochodem, je SSE http2 (a/nebo 3) kompatibilní? Když jsem se posledně díval tak websockety nebyly, ale u sse nevidím proč by to jít nemělo.
Takze http2 optimalizuje provoz po lince, z hlediska webove stranky je vicemene transparentni. Na aplikacni urovni neprinasi zadne zmeny, takze pokud potrebujes dostavat ze serveru asynchronni data, musis pouzit SSE. Delat polling pres ajax by bylo i v pripade prenosu pres http2 stale znacne neefektivni.
Problem http2 je ovsem v tom, ze prakticky existuje jenom ve forme https potrebuje TLS, klice, certifikaty a podobne nesmysly, absolutne neni vhodny pro embeded zarizeni.
Tady nejde ani tak o vykon, jako spis o komplikace. Https je podle me navrzeno naprosto spatne. Neexistuje zpusob, jak by zarizeni mohlo mit platne VEREJNE certificaty. Nemam absolutne nic proti self-signed certifikatum, ale browsery je neakceptuji. Musis se proklikat nekolika varovanimi, abys povolil vyjimku. Pak se pripojis jinym browserem nebo z jineho telefonu a jsi tam, kde jsi byl, zase musis pridavat vyjimky.
Vubec si nedokazu predstavit, jak by se dalo dosahnout toho, aby embeded zarizeni, ktere je za trema NATama, melo certifikat od LetsEncrypt nebo nekoho podobneho. Navic by byla polovina flash zabita jenom staranim se o certifikaty.
7. 11. 2022, 09:04 editováno autorem komentáře
Tak jestli je za 3 NATama, tak se na něj zvenku stejně nedostaneš. Jak píšu výše, tohle se dnes řeší aplikací. I kdyby to byl jen zabalený webový prohlížeč (ale s integrovaným tím self signed certifikátem). Koneckonců obecné prohlížeče jsou na tom stejně, taky maj přibalené certifikáty (těch veřejných autorit).
7. 11. 2022, 10:56 editováno autorem komentáře
Josef Pavlik: Jak byste HTTPS navrhl lépe? To, že prohlížeče vyžadují platné veřejné certifikáty je správně. Chyba je jen to, že DV certifikáty neumí stáhnout z DNS.
Zařízení ve vnitřní síti může mít platné veřejné certifikáty. Měl by to zařizovat „router“ té sítě, stejně jako zařizuje přidělení IP adres a DNS záznamy. (U větších sítí to fyzicky může být jiné zařízení, než router, v SOHO sítích to typicky je jedna krabička.) Že je to zařízení za NATy je chyba, to zařízení má mít IPv6. Ale je to jedno, certifikát pro něj má zajistit router.
Ovšem to samozřejmě platí v případě, kdy je to koncové zařízení něco většího a má to mít vlastní HTTPS server – třeba NAS. Pokud jde o nějaké malé IoT zařízení, to nemá vůbec přímo komunikovat s prohlížečem. To má jen poskytovat data nějakému komplexnějšímu systému, který bude ukládat historii, vyhodnocovat a podobně. To malé zařízení může běžet na baterku, bude mít výkon na to, aby něco jednou za deset minut změřilo a odeslalo, ale je zbytečné takovéhle zařízení trápit HTTPS komunikací s trvale běžícím serverem.
Ja mam na mysli iot zarizeni, ktere ma web intefrace tak akorat na setup, pripadne na to, aby se na nej clovek mohl cas od casu podivat, kdyz je nekde nejaky problem. Za normalnich okolnosti dodava data uplne jinym protokolem nekam na server. Cpat do takoveho zarizeni https by byla zvracenost.
Jak bych https navrhl lepe? Predevsim tak, aby byla oddelena funkce kryptovani komunikace od funkce overeni protistrany. Pri prihlasovani se na iot jsem si (vetsinou) celkem jisty tim, s kym komunikuji. Ale to, ze heslo potom jde viditelne pres http, to se mi moc nelibi. Kdokoliv na siti ho muze wiresharkem odchytit. Ale pro takove zarizeni je vicemene nemozne udrzovat si platny verejny https certifikat. Nemam predstavu, jak by ho dodaval router, o certifikatech mam jenom mlhave predstavy, vim jenom, ze je to pekny bolehlav.
Ja mam na mysli iot zarizeni, ktere ma web intefrace tak akorat na setup, pripadne na to, aby se na nej clovek mohl cas od casu podivat, kdyz je nekde nejaky problem.
Pořád ale není důvod, proč na takové zařízení lézt s běžným prohlížečem.
Predevsim tak, aby byla oddelena funkce kryptovani komunikace od funkce overeni protistrany.
To je ale pro web nepoužitelné. A pokud chce někdo používat protokol určený pro web, musí se přizpůsobit požadavkům toho protokolu. Pokud mu nevyhovují, ať použije jiný protokol. Je nesmysl rozbíjet web kvůli tomu, že se někomu zalíbil protokol, který používá, ale potřeboval by si ho přizpůsobit tak, že by byl pro web nepoužitelný.
Nemam predstavu, jak by ho dodaval router
ACME protokolem, tak, jako to dělá třeba Let's Encrypt. Akorát by router nevystavil ten certifikát sám, ale zajistil by jeho vystavení u LE.
Proč na to zařízení lézt přes prohlížeč? Protože je to nejjednodušší řešení bez dalších závislostí, a dělá se to tak už desítky let!
Desítky let se to nedělá, před dvaceti lety se na to běžně používaly specializované aplikace, byť se startovaly z prohlížeče (různé Active.X, Java Applety apod.). No a hlavně pokud chce někdo využít prohlížeč, tak musí splňovat požadavky, které prohlížeče mají – tj. HTTPS, aktuální verze TLS, důvěryhodné certifikáty atd. Pokud je to pro vás pořád nejjednodušší řešení, pak to tak klidně dělejte.
Specializovane aplikace jsou metla lidstva. Predstav si, ze mas router, ktery si uz 5-10 let vesele routuje. Ted potrebujes neco zmenit v konfiguraci. Spojis se na nej (pres http), vzpomenes si na heslo, prihlasis se a udelas co je potreba.
Pokud by na to byla potreba specialni aplikace, kde ji ted po 5-10 letech budes hledat? Na kterem computeru jsi ji mel nainstalovanou? Odkud se da stahnout (nezapomen, nefunguje ti router), protoze ten computer je uz nekde vyhozeny? Nebo proste ten windows xp nebootne, tak z nej linuxem bootnutym z druhe partition tahas ten blbej program, co se neda nikde stahnout, abys ho nainstaloval na jiny windows, ktery jeste bootuje (osobni zkusenosti).
Jestlize to bude neco jako java applet, je hodne pravdepodobne, ze to skonci s "unhandled java exception #123456, protoze tvoje dnesni verze javy neni kompatibilni s tehdejsi javou. To je bolehlav. Pokud to bude activex, bude to jeste lepsi, kde ti to pojede?
Takze NASTESTI naprosta vetsina zarizeni maji pristup pres normalni http a i prestoze je to nebezpecne, nejak se na to dostanes i po 10 letech.
Desim se okamziku, kdy vsechny browsery ve tvem vlastnim zajmu uplne zakazou http a budou vyzadovat https s platnym verejnym certifikatem (nezapomenme na certifikaty, kterym treba propadne platnoust nebo upadnou v nemilost a browsery, jeden jako druhy, je nebudou akceptovat.
Josef Pavlik: Myslíte si, že 5–10 let staré webové rozhraní toho zařízení bude nějaká výhra? Poběží to v konkrétní verzi Internet Exploreru, nebo ve starých verzích Chrome, protože to používá nějaké tehdy experimentální API, které je dnes už finální a funguje jinak. Nějaké soubory rozhraní to bude stahovat z už neexistujícího webu a server bude podporovat maximálně SSLv3.
Ale i ta komunikace se zařízením se dá udělat ve webovém prohlížeči, bez proprietární aplikace a bezpečně. Samotnou webovou aplikaci můžete dostat jako statické soubory, které dáte na libovolný web server (nebo to provozuje výrobce toho zařízení). Zařízení může vystavit API přes HTTP, a mezi prohlížeč a to zařízení dáte proxy server, který bude univerzální pro všechna zařízení, na jednu stranu bude s prohlížečem komunikovat přes bezpečné HTTPS a na druhou stranu může komunikovat s tím zařízením klidně po HTTP. Ta zařízení (spolu se „zadní“ stranou toho proxy serveru) pak mohou být v oddělené síti, kam se nikdo jiný nedostane.
Takže řešitelné to je, akorát je to holt trochu víc práce. Ale jinak to nepůjde – je bláhové myslet si, že celý svět bude používat web nebezpečným způsobem jenom proto, že vy se chcete připojovat k bezdrátovému teploměru bezpracně.
Ted jsi popsal naprosto presne zpusob, jakym delame pristup na nase zarizeni :-) :-) :-).
Mame server, na ktery se klient pripojuje pres https. Tento server nedela nic jineho, nez reverse proxy na nase zarizeni po http, ovsem po kryptovane vpn. Certifikaty udrzujeme jenom na jednom miste, vsechno ostatni jede pres stary dobry http, protoze nektere z techto zarizeni bezi na 20 let starem hardware a stejne tak stare verzi Connectiva, coz je odnoz Redhat, radove tak Redhat 8. Zapomen na https, to v te dobe sice asi uz existovalo, ale nejsou tam kompatibilni knihovny, ktere by byly schopny delat SSL kompatibilni s dneskem. Uz jenom dostat se na to pres ssh je komplikovane, musis mit nastavene optiony, ze povolujes historicke zpusoby kryptovani :-). Tohle se ovsem tyka pouze urcitych specialnich extra funkci, zarizeni jako takove jede i offline. Tento system resi hlavne problem zarizeni, ktere je za trema NATama.
Ovsem reknni klientovi, ze si ma koupit novy hardware. Uvidis, kam te posle. Zvlast dnes, kdy koupit novy hardware je skoro jak za komunismu. Jak zpivaval Kryl "K shaneni ma cas jen ten, co marodi".
Jeste se vratim k zarizeni pripojitelne pouze pres nejaky server nejakeho obskurniho vyrobce. Pokud ten cinan mezitim zkrachoval a server uz nejede, mas smulu, uz se na svoje zarizeni nedostanes. Takze tohle taky neni rozumna cesta.
Samozřejmě nejste jediní, kdo to tak dělá. Nejvíc v tom samozřejmě jedou Google, Amazon a Apple se svými domácími asistenty. S jednou drobnou odlišností – oni to uživateli nezpřístupňují přes zdokumentované otevřené rozhraní přes HTTPS, ale skrze svůj proprietární cloud. Nicméně účelem je to samé. Ostatní mají na výběr dvě možnosti – buď to pozorovat, smát se jim, jak to dělají blbě a za pár let se zase divit, že mají oligopol v další oblasti. A nebo se dohodnout na standardu, který budou moci implementovat domácí routery a z druhé strany ta IoT zařízení. Tak, aby router zařízení nově připojenému do sítě (po odsouhlasení majitelem) nejen přidělil IP adresu, ale také zaregistroval veřejný DNS název a zprostředkoval k němu vydání certifikátu (pro nadupanější zařízení typu NAS) nebo zprostředkoval komunikaci skrz vlastní proxy server (pro IoT zařízení typu okenní kontakt). Protokoly na to existují, jde jenom o doladění toho, jak se mají konkrétně používat.
Nemel jsem to ani vzpomenout. Zrovna dnes se tady uz od rana se**me zrovna s timto shitoznim access pointem. Nekde neco zmenili, nedari se ho upgradnout pracne pripravenyma scriptama. Bylo nutno nainstalovat ten jejich shitozni 'Unifi network', coz je monstrozni uzavrena aplikace, nechci ani vedet jaky bordel mi dela v systemu. Je to napsane v jave, ma to asi 160M, bezi to jako daemon, na ktery se pres web interface pripojis a pak konfigurujes access point. Kdyz uz chteli delat monstrozni web aplikaci, proc ji nedali primo do toho access pointu bez nutnosti instalovat pochybne programy a registrovat se na jeste pochybnejsich sitech. A stejne to nejde upgradnout ani takhle. Celkovy zaver je takovy, ze asi budeme muset vyhodit 5 uplne novych access pointu, protoze s originalnim firmware nejsou k nicemu a ubyquyty od tohoto okamziku nechci az do smrti videt.
Mimochodem, pripojujes se na to pres https nemaji tam ani platny certifikat, musis presvedcit firefox, ze jim veris a ze ma pouzit tento neduveryhodny certifikat. Jak mam neco takoveho udelat, kdyz jim neverim?
15. 11. 2022, 14:36 editováno autorem komentáře
Zda se, ze je to jeste dalsi, dnes jiz zapomenuty, dobastl do HTTP. Bohuzel toho na te wikipedii moc neni. Na Francouzske verzi je alespon priklad teto komunikace i s hlavickou. Neni ovsem zrejme, jakym zpusobem (jestli vubec) se da takovyhle prenos po kouskach prijimat javascriptem.
HTTP/1.1 200 OK\r\n Content-Type: text/plain\r\n Transfer-Encoding: chunked\r\n \r\n 26\r\n Voici les données du premier morceau\r\n\r\n 1C\r\n et voici un second morceau\r\n\r\n 20\r\n et voici deux derniers morceaux \r\n 12\r\n sans saut de ligne\r\n 0\r\n \r\n
Tej otazke nerozumiem.
Javascript to predsa prijima - nehovorim, ze ignoracia nespravnych riadkov nefunguje, ale toto je obycajny chunked transfer, kde su tie bajty sucast protokolu a preto sa pouziju automaticky tam.
Nie je to vobec zabudnute - pouzivaju to vsetky velke firmy v ich reverznych proxy. Vdaka tomu ide validne poslat treba prvy 1kB stranky, ked este nie je uplne jasne, co ma byt dalej.
+1, chunked se ale obecně používá kdekoliv, kde je velikost stránky neznámá. V závislosti na serveru se za neznámou může považovat cokoliv, co není ukončeno v nějaké krátké době, má větší než přijatelnou velikost bez předchozího oznámení finální velikosti nebo třeba explicitní použití streaming interface na straně servletu. Tady to vypadá, že to server detekuje podle content-type=text/event-stream , možná podle timeout.
Ty chunk size a CRLF (velikost dalšího bloku jako hex number) jsou pouze součástí HTTP protokolu, ne samotného obsahu. JavaScript se k tomu vůbec nedostane.
Není to žádný zapomenutý dobastl. Je to jediný způsob, jak přes HTTP/1.1 posílat data, jejichž délku předem neznáte. Což je typické pro veškeré generování na serveru – obvykle nechcete všechna data generovat do paměti, abyste zjistil jejich délku, a teprve pak je začít posílat. Naopak je chcete posílat hned, jak jsou k dispozici.
JavaScriptem to po těchto kouskách nepřijmete jinak, protože jste v protokolu o úroveň výš. Je to jako kdybyste chtěl na úrovni HTTP protokolu vědět, kde byly hranice paketů. Toto je jenom způsob transportu, na aplikační úrovni se to ale stále jeví tak, že dostáváte po částech přijímaný soubor – a nevíte, jestli ty části vznikají chunkováním, rozdělováním do paketů nebo třeba bufferováním na úrovni OS. Prostě dostáváte další a další bajty, jak přicházejí, dokud nedojdete na konec. A obvykle se s tím v JavaScriptu nepracuje jako s bajtstreamem, ale necháte prohlížeč sestavit celý text odpovědi nebo ho rozparsovat jako JSON, tj. v JavaScriptu pracujete až s celým výsledným souborem. Ale ta možnost načítat po sekvencích bajtů v JS existuje.
To už je asi skoro archeologie, ale minimálně v HTTP/1.0 to šlo jednodušeji a méně ošklivě tím že se content-length neuvedl a konec byl při uzavření spojení.
https://datatracker.ietf.org/doc/html/draft-loreto-http-bidirectional-07
Já to považuju naopak za ošklivější řešení, protože za prvé předčasné ukončení spojení někdy vypadá jako ukončení uzavřením spojení a nedozvíte se, že nemáte celý obsah. Za druhé vás to nutí uzavřít spojení, pro další komunikaci tedy musíte otvírat nové spojení, což je drahá operace. Ale ano, v HTTP/1.0 se to řešilo ukončením spojení. Pak se ale přidala podpora persistentních spojení, která umožnila jedním spojením posílat víc požadavků. V HTTP/1.1 se pak přidala možnost chunked transfer encoding.
Rozjet CORS na jiný server s SSE je možné, jen to nejdůležitější je, že server(!) musí odpovídat s hlavičkou Allow-Origin
a uvést doménu, z které je možné se přihlásit. Takže například z webu web.cz na server.cz musí server.cz odpovídat s hlavičkou Allow-Origin: web.cz
.
3. 11. 2022, 17:05 editováno autorem komentáře
Len doplním, že pre podporu aj iných HTTP metód než GET/HEAD (a v niektorých prípadoch POST, viď https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), napr. DELETE alebo POST posielajúci JSON alebo cookies, je nutné aby server vedel správne odpovedať na OPTIONS požiadavok s správnymi hlavičkami Access-Control-Allow-Origin a Access-Control-Allow-Methods.
Viac tu: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
Server musí umět přjímat HTTP OPTION zprávy, aby prohůížeč mohl udělal tzv. preflight. Pokud to na serveru nepovolíte a neobslujete, v moderních prohlížečích CORS nebude fungovati, prototže ty preflight dělají u cross-origin requestů vždy (dřívější metody se už nepoužívají). Taky musí být správěn nastavena hlavička strict-origin. Myslím, že Chrome celkem jasně diagnosticky vypisuje v konzoli, proč CORS request zdechnul.
Myslim si, ze to mohlo byt kvuli tomu, ze jsi tam nedelal flush. Pozor na to, ze v php je jeden flush vnitrni, ktere flushne buffery php, ale pak musis udelat jeste flush operacniho systemu, aby se to vsechno poslalo ven.
ob_end_flush(); # tohle je flush php, aby to poslal do systemu flush(); # tohle je flush systemu, aby to poslal na linku
No nebolo to tým. Flush tam bol.
Ale kedže mi to beží na ngnix, tak som tam pridal ešte jednu hlavičku:
header("X-Accel-buffering: no");
Link: https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-buffering
No a potom už vypísanie zbytočných 4096 znakov nebolo ďalej potrebné.
// echo str_repeat(' ', 4096);
Líbí se mi historický exkurz a důraz na nižší vrstvy (TCP). Jen tak dál, díky!
Diky za ten clanek, nemel jsem o EventSource potuchy. Na hostingu to pouziju v jedne hre. Lokalne s tim mam ale problem, provozuju php-fpm a tam je s tim vyprazdnovanim bufferu problem.
Jak prosím řešíte autorizace (JWT Bearer)? Standardně EventSource neposílá hlavičku.
Našel jsem, že toto řeší knihovna https://github.com/Yaffle/EventSource
Tak v rámci knihovny https://github.com/Yaffle/EventSource mi autorizace funguje. Proč to vlastně EventSource neumí od základu :)