abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 05:33 | Pozvánky

    Protože je už po aprílu, můžou strahováci opět zveřejnit program další Virtuální Bastlírny, aniž by připravená témata působila dojmem, že jde o žert. Vězte tedy, že již v úterý 7. dubna od 20:00 proběhne VB, kde se setkají bastlíři, technici, učitelé i nadšenci do techniky a kde i vy se můžete zapojit do družného hovoru, jako by všichni seděli u pomyslného piva. Co mají bastlíři tento měsíc na srdci? Pravděpodobně by nás musel zasáhnout meteorit

    … více »
    bkralik | Komentářů: 0
    včera 23:33 | Nová verze

    Byla vydána verze 26.1 aneb čtvrtletní aktualizace open source počítačového planetária Stellarium (Wikipedie, GitHub). Vyzkoušet lze webovou verzi Stellaria na Stellarium Web.

    Ladislav Hagara | Komentářů: 1
    včera 23:00 | Zajímavý projekt

    VOID (Video Object and Interaction Deletion) je nový open-source VLM model pro editaci videa, který dokáže z videí odstraňovat objekty včetně všech jejich fyzikálních interakcí v rámci scény (pády, kolize, stíny...) pomocí quadmaskingu (čtyřhodnotová maska, která člení pixely scény do čtyř kategorií: objekt určený k odstranění, překrývající se oblasti, objektem ovlivněné oblasti a pozadí scény) a dvoufázového inpaintingu. Za projektem stojí výzkumníci ze společnosti Netflix.

    NUKE GAZA! 🎆 | Komentářů: 0
    včera 05:22 | Zajímavý software

    Design (GitHub) je 2D CAD pro GNOME. Instalovat lze i z Flathubu. Běží také ve webovém prohlížeči.

    Ladislav Hagara | Komentářů: 12
    včera 04:11 | Zajímavý software

    Příspěvek na blogu herního enginu Godot představuje aplikaci Xogot přinášející Godot na iPad a iPhone. Instalovat lze z App Storu. Za Xogotem stojí Miguel de Icaza (GitHub) a společnost Xibbon.

    Ladislav Hagara | Komentářů: 1
    4.4. 04:22 | Komunita

    Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za březen (YouTube).

    Ladislav Hagara | Komentářů: 13
    3.4. 16:44 | Nová verze

    ESP-IDF (Espressif IoT Development Framework), tj. oficiální vývojový framework pro vývoj aplikací na mikrokontrolérech řady ESP32, byl vydán v nové verzi 6.0. Detaily na portálu pro vývojáře.

    Ladislav Hagara | Komentářů: 0
    3.4. 12:33 | Nová verze

    DeepMind (Alphabet) představila novou verzi svého multimodálního modelu, Gemma 4. Modely jsou volně k dispozici (Ollama, Hugging Face a další) ve velikostech 5-31 miliard parametrů, s kontextovým oknem 128k až 256k a v dense i MoE variantách. Modely zvládají text, obrázky a u menších verzí i audio. Modely jsou optimalizované pro běh na desktopových GPU i mobilních zařízeních, váhy všech těchto modelů jsou uvolněny pod licencí Apache 2.0. Návod na spuštění je už i na Unsloth.

    NUKE GAZA! 🎆 | Komentářů: 11
    3.4. 03:55 | Nová verze

    Cursor (Wikipedie) od společnosti Anysphere byl vydán ve verzi 3. Jedná se o multiplatformní proprietární editor kódů s podporou AI (vibe coding).

    Ladislav Hagara | Komentářů: 0
    2.4. 19:55 | Zajímavý projekt

    Průkopnická firma FingerWorks kolem roku 2000 vyvinula vícedotykové trackpady s gesty a klávesnice jako TouchStream LP. V roce 2005 ji koupil Apple, výrobu těchto produktů ukončil a dotykové technologie využil při vývoji iPhone. Multiplatformní projekt Apple Magic TouchstreamLP nyní implementuje funkcionalitu TouchStream LP na současném Apple Magic Trackpad, resp. jejich dvojici. Diskuze k vydání probíhá na Redditu.

    |🇵🇸 | Komentářů: 0
    Které desktopové prostředí na Linuxu používáte?
     (14%)
     (7%)
     (1%)
     (12%)
     (30%)
     (3%)
     (6%)
     (1%)
     (14%)
     (23%)
    Celkem 1223 hlasů
     Komentářů: 30, poslední 3.4. 20:20
    Rozcestník

    Servlety a kódování znaků

    17.5.2006 21:43 | Přečteno: 2443× | Java | poslední úprava: 18.5.2006 10:11

    Zatímco nastavení správného kódování souborů odesílaných webovým serverem do prohlížeče je už celkem zvládnutá věc, příjem textů z formulářů na webovém serveru může záludnostmi souvisejícími s kódováním ještě potrápit. Protože jsem při hledání jedné chyby na Abíčku zabrousil do hlubin zdrojových kódu Servlet API a servlet kontejneru Jetty, a nechci to za půl roku zkoumat znovu, popíšu (si) závěry výzkumu sem.

    Ani s vynálezem Unicode není problémům s různými kódováními znaků konec. Většinou už se s nimi nesetkávají běžní uživatelé, ale programátoři si jich stále ještě užijí dost a dost. Jedním z klasických problémů je komunikace přes HTTP.

    Každý slušný webový server, pokud posílá nějaký text, přidá do HTTP hlaviček informaci o jaký typ dat se jedná (např. HTML, čistý text) a také v jakém jsou kódování:

    HTTP/1.x 200 OK
    Date: Wed, 17 May 2006 18:24:59 GMT
    Server: Jetty/4.2.17
    Content-Type: text/html; charset=UTF-8
    

    Při odesílání dat z webového formuláře na server je ale situace horší. application/x-www-form-urlencoded nebo multipart/form-data , o použitém kódování ani čárka. Nějak mezi prohlížeči není zvykem tam informaci o kódování přidávat. Ona by nejspíš také spoustu serverů zmátla, a zbytek by s ní neuměl pracovat. A servery se tuto informaci zase nepokoušejí číst, protože ji prohlížeče neposílají. Začarovaný kruh.

    Naštěstí je mezi prohlížeči dobrým zvykem odesílat data zpět v kódování, v jakém ho přijala (resp. v kódování, které má na dané stránce uživatel zrovna nastavené, takže změní-li si uživatel z nějakého důvodu kódování stránky, pošlou se data v jiném kódování, než čekáte). Vynechám teď speciální případy, kdy mám v jednom projektu stránky v různých kódováních, nebo kdy bych chtěl odesílat data do formuláře, který nemám pod kontrolou (na cizí web) a musel bych se kódováním své stránky trefit do kódování cílového webu. I v jednoduchém případě, že odesílám formulář na svůj vlatní web, který má konzistení kódování znaků, pořád je tu problém: já jako autor aplikace vím, v jakém kódování mám stránky, a tedy v jakém kódování očekávat odpověď. Ale ta aplikace to neví.

    Konkrétně ve specifikaci Servlet API k tomu, aby se to aplikace dozvěděla, slouží metoda ServletRequest.setCharacterEncoding(String), doplněná do API od verze 2.3. Tím sdělíte Servlet API, v jakém kódování bude odpověď. (Jak jsem popsal výše, Servlet API nemá žádný způsob, jak kódování zjistit z HTTP požadavku. Spoléhá tedy na programátora, že dopředu ví, jaké to kódování bude. Ještě stále dokážou programátoři z pohledu počítačů magické věci – zde třeba věštit budoucnost.) Dobrým zvykem tedy je na začátku servletu (ještě před jakýmkoliv čtením z HTTP požadavku) zavolat tuto metodu se správným kódováním – a o zbytek už se není potřeba starat, Servlet API se postará o správné rozkódování parametrů dotazu a programátor v dalším kódu už jen může vrnět blahem nad tím, jak Java pěkně pracuje s řetězci, že String je prostě řetězec Unicode znaků a o nějaké kódování se nemusím starat, dockud nechci řetězec poslat zase někam ven.

    Pokud tuhle metodu programátor na začátku nezavolá, předpokládá servlet kontejner nějaké defaultní kódování – např. Jetty ve verzi 4.2.x předpokládalo kódování iso-8859-1, verze 5 a výš předpokládají UTF-8. Poměrně častý způsob zacházení s kódováním požadavku (a před přidáním metody ServletRequest.setCharacterEncoding(String) jediný možný) tedy bylo:

    Že tuhle rozcvičku text přežil ve zdraví je dáno shodou okolností: URLkódování kóduje oktety (osmibitové znaky) – kódování původního textu, který prohlížeč posílal, tedy vždy muselo pro svou reprezentaci používat oktety (ona se dnes snad ani jiná kódování nepoužívají, i UTF-16 ukládá do dvojic oktetů). A kódování iso-88592-1 plně pokrývá celý rozsah oktetů – jinými slovy, ať si zvolíte jakýkoli oktet, vždy to v iso-8859-1 znamená nějaký platný znak. U UTF-8 je situace horší, tam by zřejmě bylo možné vyrobit takovou sekvenci oktetů, které v UTF-8 neznamenají nic – tam už by tedy mohlo dojít ke ztrátě některých znaků nebo dokonce k chybě při překódování. Naštěstí u znakových sad iso-8859-2 a Windows-1250 se všechny běžné znaky vyjádřené v oktetech namapují na nějaké znaky UTF-8, takže ke ztrátě informace nedojde (alespoň jsem se s tím zatím nesetkal).

    Až dosud by to byla docela známá věc, a nebylo by potřeba nic zkoumat. Kdyby mi při testování nevracelo Servlet API tvrdošíjně řetězce překódované podle iso-8859-1 nezávisle na tom, jaké kódování jsem nastavil. (V situaci, kdy Jetty je spuštěné pod Windows a tedy kódovou stránkou windows-1250, konzole ve Windows zobrazuje v CP852, HTML stránky a tedy parametry jsou v iso-8859-2 a Servlet API si o tom myslí, že je to iso-8859-1, taky chvíli trvalo, než jsem zjistil, kde se to vlastně špatně překóduje…)

    Kamenem úrazu se zde stalo ono před jakýmkoli čtením požadavku. Debugování naustále ukazovalo, že parametry požadavku už někdo četl… Pochvíli byl jasný i pachatel: Filtr jakarta_compression (nejspíš součást Tomcatu), který komprimuje odpovědi gzipem, aby se po síti přenášelo míň dat. Tento filtřík s 60 řádky copyrightu a 200 řádky kódu se zcela nevinně dotazoval na parametr gzip. Sloužil mu k tomu, aby v případě, že je nastaven na false, data nekomprimoval. Taková drobná fíčurka usnadňující ladění… Tím pádem už někdo četl parametry, tedy četl požadavek, a tedy jakékoli snahy o změnu kódování vyšly naprázdno.

    Jak z toho ven? Napadají mne dvě možnosti: za prvé – pokaždé, když Servlet API získá informaci o změně kódování, zahodit nakešované parametry a načíst je znovu, tentokrát ve správném kódování (fuj). Taky by to zřejmě znamenalo pamatovat si celý požadavek po celou dobu zpracováníní… Druhá možnost: všem filtrům a veškerému zpracování požadavku předřadit ještě jeden filtr, který nastaví předpokládané kódování (dvakrát fuj). Všechny filtry mezi tím prvním nastavovacím a mým servletem budou už pracovat s nějakým kódováním, a nebudou o tom vědět. Navíc nastavení kódování parametrů, které potřebuji v Servletu, musím udělat úplně někde jinde, v nesouvisející části, a ještě nesmím zapomenout to všude přidat. Asi jako kdyby se už u zápisu do 1. třídy ptali, z jakých předmětů chci maturovat…

    Bohužel, nezbyde než použít metodu dvakrát fuj, protože jak mě upozornil Greg Wilkins, autor Jetty, specifikace k metodě ServletRequest.setCharacterEncoding(String) říká:

    Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader(). Otherwise, it has no effect.
    Tedy volně řečeno: dokud požadavek nikdo nečetl, lze měnit kódování libovolně, jakmile se někdo byť jen na písmenko podíval, je se změnami kódování utrum.

    A závěr? Příště už si nebudu myslet, že volání setCharacterEncoding na prvním řádku servletu je dostatečně brzo. Bez Filteru nastavujícího správné kódování už v Servlet webaplikacích ani ránu. Aneb

    public class EncodingFilter implements Filter{
      public void init(FilterConfig filterConfig) {
        this.encoding = filterConfig.getInitParameter("encoding");
      }
    
      public void doFilter ( ServletRequest request, ServletResponse response,
          FilterChain chain ) throws IOException, ServletException {
        request.setCharacterEncoding(this.encoding);
        chain.doFilter(request, response);
      }
    }
    
    do každé rodiny. A příležitostně pošťouchnout Mozillí Bugzillu, jestli by třeba nechtěl Firefox s formulářovými daty posílat i jejich kódování, pozeptat se ve fóru Servlet API, Apache a dalších, jestli by z takových údajů nechtěli informace o kódování získávat, a tak. A nebo doplnit křišťálovou kouli jako standardní výbavu webserverů…

    PS: A mimochodem – ta chyba na Abíčku nakonec byla úplně v něčem jiném. Věřili byste, že je možné přes chránku vložit do textového pole formuláře ve Firefoxu znaky jako Escape (kód 27)? A zřejmě občas někdo považoval za dobrý nápad takovéhle znaky vložit třeba do diskuze… Ale exkurze po zdrojácích Jetty z toho byla rozhodně zajímavá, vyzkoušet si vzdálené ladění Jetty s pomocí eclipse se také hodilo, a zase jsem o něco chytřejší… :-)

           

    Hodnocení: 100 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    18.5.2006 07:49 mivrap | blog: Mirkovo
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    Zajímavé... Ovšem odstavec "Že tuhle rozcvičku..." mi přijde nějaký hóódně podezřelý. Napadla mě při tom otázka: Co máš vůbec za sebou v rámci počítačového vzdělávání? Gympl? Samouk?
    18.5.2006 10:00 Filip Jirsák | skóre: 67 | blog: Fa & Bi
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    Co je na něm podezřelého? OK, UTF-16 nekóduje do 2 oktetů ale do 16 bitů, což je ale vzájemně triviálně převoditelné…

    Co já vím, jak je to s mým počítačovým vzděálním? Samouk, gympl jako student, učitel i správce sítě, přednášky na VŠ…
    Jiří Poláček avatar 18.5.2006 08:53 Jiří Poláček | skóre: 47 | blog: naopak | Sivice
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    Před pár měsíci jsem se také s kódováním znaků z formulářů trápil. Řešení jsem našel na wiki Tomcatu.
    Sudoku omrzelo? Zkuste bobblemaze! | Statistiky jsou jak bikiny. Napoví hodně, všechno ale neukážou.
    18.5.2006 10:10 Filip Jirsák | skóre: 67 | blog: Fa & Bi
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    No jo, jenže to první popsané řešení na té wiki je právě špatně :-( Za prvé, IE ani jiný prohlížeč neposílá data v iso-8859-1, ale v kódování, v jakém je stránka s formulářem. Je na to jednuduchý test – pokusit se odeslat text třeba s č, ř, š apod. – tyhle znaky není jak v iso-8859-1 zakódovat. Ale prohlížeč je zpravidla odešle :-) A za druhé se tam provádí ono dvojí překódování znaků, což nemusí dopadnout vždycky dobře. Navíc se tam předpokládá, že to první překódování bylo podle iso-8859-1, což taky nemusí být vždy pravda. To druhé řešení je správné, je tam dokonce i celý ten filtr i jeho použití, takže copy–&–paste toho filtru doporučuji z wiki Tomcatu :-)
    Jiří Poláček avatar 19.5.2006 09:17 Jiří Poláček | skóre: 47 | blog: naopak | Sivice
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    Kdyby prohlížeče odesílaly data v kódování, v jakém je stránka s formulářem, tak bych s tím neměl žádné problémy a nehledal řešení ... Nevím, jestli v tom nemá prsty Tomcat, ale u mě se data posílají v iso-8859-1 bez ohledu na kódování stránky.
    Sudoku omrzelo? Zkuste bobblemaze! | Statistiky jsou jak bikiny. Napoví hodně, všechno ale neukážou.
    19.5.2006 09:54 Filip Jirsák | skóre: 67 | blog: Fa & Bi
    Rozbalit Rozbalit vše Re: Servlety a kódování znaků
    Důkazem, že prohlížeč neodesílá data v kódování iso-8859-1, je samotný váš komentář :-) V kódování iso-8859-1 nejsou znaky ř, ž, č – vám se je přes prohlížeč přesto podařilo odeslat… Jestli pod Tomcatem máte v servletu znaky rozkódované, jakoby byly iso-8859-1, ale stránka je v jiném kódování, je to přesně to, o čem byl můj spot – a nejjednodušší řešení je použít filtr popsaný na konci spotu nebo na vámi odkazované wiki Tomcatu.

    Mimochodem, pro ladění servletů doporučuji rozšíření do Firefoxu LiveHTTPheaders, tam můžete zjistit, v jakém kódování prohlížeč stránku dostává, jaká data odesílá atd.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.