Lachen met programmeertalen en -frameworks

Gewoon 2 geek-linkjes, om te lachen op deze vrijdagmiddag. Of is het al zaterdagmorgen bij U, misschiens?

En misschien toch 1 gerelateerd serieus linkje: Choosing a JVM web framework (pdf, door Matt Raible)

Michel Vuijlsteke vs Firefox (en post redirect warnings)

elementary, dear vuijlsteke!Michel Vuijlsteke heeft het moeilijk met Firefox. Het is “het véruit meest onstabiele programma op heel mijn computer” en dat kan op zich al tellen. Maar laatst vroeg diezelfde browser hem:

“This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location?”.

Michel was verward, een beetje geërgerd zelfs:

“Nee, Firefox, dat wil ik niet. Of misschien wel. Of nee… aargh! Ik weet het niet! I’m so confused! Ik héb helemaal geen form data ingevuld, en ik wil die helemaal niet doorsturen!”.

Omdat het welzijn van deze opperblogger me nauw aan het hart ligt en -ge moet dat durven toegeven Goossens- omdat ik een Firefox fanboy ben, haalde ik mijn Dearstalker-hoed, kalebas-pijp en vergrootglas nog eens uit de serverkast en leerde al speurend toch weer één en ander bij. Ontdekt U mee?
Alzo: bovenstaande waarschuwing in Firefox wordt door de browser zelf getoond bij een specifiek soort redirect van POST-requests. Er is geen setting in about:config waarmee deze functionaliteit af- en aangezet kan worden en je krijgt de popup niet bij triviale GET-redirects.
De flow van zo een POST-redirect (ik heb snel een voorbeeldje gemaakt, test gerust zelf) ziet er als volgt uit:

  1. gebruiker submit (bewust of m.b.v. javascript) een form met method POST naar server xyz.be
  2. server xyz.be retourneert een http status code 307 met Location abc.be
  3. browser POST de data van het formulier naar abc.be

Een soort bounce dus. Nu hebben de HTTP/1.1 specs (RFC 2616) blijkbaar ook een mening over hoe zo een 307 door de browser moet worden afgehandeld:

“If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.”

Eh! Tiens! Een browser moet in principe dus een waarschuwing geven als een POST-request wordt gebouncet? Straf. En wat doen Safari, Opera en MSIE dan? Awel: Opera vraagt ook wat er moet gebeuren (brave jongens, die Noren). Safari volgt de specs al iets minder en redirect zonder morren, maar alle formdata gaat wel verloren (oeps). Enkel MSIE (ook 7) volgt de redirect en herpost zonder een kik te geven. Akkoord, MSIE verwart de gebruikers op die manier niet met onduidelijke waarschuwingen, maar dat middels wat XSS of phishing in combinatie met zo een 307 logins en andere confidentiële data ongemerkt ontfutseld kunnen worden, daar malen we niet om. Toch?
Soit, conclusie voor webdevelopers: gebruik geen form redirects met status 307! De juiste manier om Post/Redirect/Get te implementeren is de form data bij de eerste (post-)request te verwerken en dan pas met een http status 303 (of 302, als ge persé moeilijk wilt doen) een redirect te triggeren.
En een tip voor Michel: Safari 3 voor Windows komt eerstdaags officieel uit (ik gok tegelijkertijd met Leopard, dat zou dus … vandaag zijn). Dat betekent misschien het einde van je Firefoxmiserie? 😉

3 stylesheets to rule them all?

Sony Ericsson P910i with Opera web browser. Author: Lzur, wikimediaIk schreef eerder al dat ik me voor mijn nieuwe blogthuis (het duurt allemaal wat langer, maar het is dan ook goed toeven op wordpress.com) op het WordPress theme Indigo het gesmeten. Wat me verwondert bij het bekijken van zowat alle WP-themes (en zelfs veel web-software tout court), is het ontbreken van css voor print- en handheld-versies.
Het principe is nochtans eenvoudig; je definieert in je html welke css voor de media “screen” (de default voor gewone browsers), “print” en “handheld” gebruikt moeten worden en de browser kiest dan naargelang de context de juiste css. Makkelijk zat, toch? En toch lijkt bijna geen enkel WordPress-theme dit te doen. Meer nog, je hebt WordPress-plugins om voor een print– en pda-vriendelijke versie te zorgen. Plugins! PHP! CPU en memory-vretende code! Voor iets wat in bloody css kan!?! Maar panikeer niet lieve vriendjes, ik ben er dus mee bezig!
Aangezien print- en handheld-versies in CSS enerzijds makkelijk te bouwen zijn, maar omdat dat anderzijds zo weinig gebruikt lijkt te worden, is mijn vraag van de week: zijn er dan toch fundamentele problemen met het gebruik van print- en handheld-css? Waarom gebruikt gij geen print- en handheld-css? Uw professionele input wordt, zoals steeds, ten zeerste geapprecieerd!

Search crawlers & cookies?

Vraag voor SEO- en andere search-software-specialisten: hoe gaan search engine crawlers om met cookies? Google beschouwt cookies alleszins als een “fancy feature”, maar het is niet helemaal duidelijk of ze dat nu wel of niet ondersteunen (“search engine spiders may have trouble crawling your site”). En wat doet Nutch bijvoorbeeld?
Ik heb een klein experimentje opgezet. Een stomme pagina zet 4 soorten cookies: een combinatie van session cookies en cookies die expiren na 1 uur met host-afhankelijke en domain-cookies. In de value van die cookies staat mijn naam en het type cookie dat gezet werd. Dat alles serverside, ik ga er immers van uit dat crawlers al helemaal niks kunnen doen met cookies die in javascript worden gezet (of gelezen). Op die setcookie-pagina staat er dan een gewone href-link naar de readcookie pagina, waar al die cookies serverside worden uitgelezen en in gewone html getoond. Crawlers die langskomen, krijgen dus potentieel 4 cookies te verteren en volgen dan mooi de link naar de readcookie-pagina. Als de zoekrobot mijn koekjes gegeten heeft, staat de tekst van die cookies op die 2de pagina en zit die dus ook in de searchindex. Spannend!
Om te besluiten waarmee we ook begonnen waren: heeft er iemand in tussentijd goeie tips of info over dit onderwerp?

Hoe het met “gezocht: search” gaat?

Een tijdje geleden vroeg ik jullie op deze blog naar input over website search oplossingen. Een maand later is een korte update misschien op zijn plaats?

xapian logoLaat ons eerst de oplossingen even overlopen die in de comments van mijn eerdere blogpost werden voorgesteld: pvandewyngaerde linkte naar Xapian en Strigi. Over Strigi kunnen we kort zijn: het is een desktop search en geen website search, volgende dus. De andere link was inderdaad direct veelbelovender: Xapian is een open source search library in c++. Omega is een voorbeeld-implementatie van Xapian in perl. Ik vond niet veel documentatie over Omega, dus even geïnstalleerd en mee gespeeld. Eerste probleem: alle configuratie zit in txt-files, niet van dien aard dat onze business-collega’s daar direct mee aan de slag kunnen. Tweede probleem: crawlen van websites wordt niet ondersteund. Omega gaat er namelijk van uit dat je website lokaal (op dezelfde machine) staat en indexeert statische html via het filesysteem. Voor echte crawling verwijst de wiki naar wget (zo heb je je site toch lokaal) of htdig. Niet handig om het zachtjes uit te drukken en “as such” dus toch niet echt bruikbaar voor onze doeleinden.
lucene logoLuc stelde Nutch voor. Nutch is een broertje van het quasi alomtegenwoordige Lucene; open source, ook onder de rokken van de Apache foundation en ook java. Nutch is een mooi uitgangspunt voor een website search, maar features als stemming en logical operators worden niet ondersteund. Configuratie is heel flexibel (want via tekstfiles), maar er is anderzijds ook hier geen ‘leuke webinterface’ om de boel te administreren. In mijn nota’s (maar ik vind niet direct terug waar ik die info gevonden heb) lees ik tenslotte dat Nutch out of the box geen ‘collections’ ondersteund. Alles wordt dus in 1 index bewaard, wat voor onze implementatie (een 10-tal sites in 2 of 3 talen die we ook apart willen kunnen bevragen) nodig was.
Omdat ik ook maar een onwetend eenzaat in een groot telecom-bedrijf zonder eigen (web-)developers ben, schreven we een tijd geleden ook een paar bedrijven aan met de vraag een oplossing voor ons te formuleren en budgetteren. We kregen 4 nutch logooffertes, 2 voor custom-built solutions en 2 product-gebaseerde voorstellen. De 2 “build” oplossingen gingen beiden uit van Lucene als “core”, de ene met Nutch, de andere met Compas (een high-level api voor Lucene met integratie van Spring, Hibernate, JDBC, …) erbovenop. Omwille van de risico’s verbonden aan custom development (scope-bepaling, functionele analyse en development van de administratie-schermen om er maar enkele te noemen) en omwille van de strikte deadline besloten we om niet te opteren voor nog te ontwikkelen oplossingen.
gast logoDe 2 “buy”-gebaseerde voorstellen lagen betrekkelijk ver uit elkaar; aan de ene kant hadden we Fast, een enterprise search solution die veel meer kan dan website search alleen, maar met een licentieprijs en een doorlooptijd voor installatie en configuratie die natuurlijk navenant waren.
In het andere voorstel kwamen we gelukkig een oude bekende tegen: Searchblox is een op Lucene gebaseerde mid-market search-oplossing. Crawling en indexing, de search-interface (incl. stemming en fuzzy search), een goeie searchblox logobackend voor administratie, een REST-api en de mogelijkheid om met xslt de business logica van de presentatie van zoekresultaten te wijzigen, zijn standaard functionaliteiten die in 1 eenvoudig te deployen WAR zitten. U raadt het al; omwille van doorlooptijd, geboden functionaliteit en kostprijs opteerden we uiteindelijk inderdaad voor Searchblox. Benieuwd wat dat gaat geven!

De NMBS wilt mijn e-mail-adres, maar…

nmbs smile promoVandaag als pendelaar-met-treinabonnement van de NMBS een brief in de bus gekregen. Ze hebben mijn mailadres niet, schreven ze en dat ze me daarom wel een papieren brief moésten sturen. En dat er niet minder dan 4 goede redenen waren voor een smile (“Reden 3: Als U snel reageert, wint U misschien wel 2 weekendbiljetten”). Ook al ontving ik nog nooit papieren post van de NMBS, toch vind ik het geen slecht idee om “de papierberg te beperken”. Ik heb het als super-pendelaar daarenboven ook nogal voor de trein en ik smile ook al eens graag, dus trok ik naar e-perron www.nmbs.be om daar mijn mail-adres achter te laten. Maar toen liep één en ander toch een beetje mis …


Op de nmbs-site moest je, zo schreef ir. Sabin S’heeren, Directeur-Generaal Reizigers Nationaal, op de banner met het lachende gezichtje klikken. Dat lachende gezichtje ziet er op de site overigens maar triestig uit; heeft iemand die mooie brief van de Directeur-Generaal op de scanner gelegd en het resultaat op de site gegooid? Maar alleszins, er zit geen link onder die corny smilies. De tekst eronder is vetjes en donkerblauw, daar misschien? Nee, ook geen link achter de titel. Ah, een “Meer”-knop. Klik!
Alzo kwam ik een paar kliks later op de eigenlijke applicatie-pagina. Spijtig genoeg met de mededeling dat de toepassing niet beschikbaar is. Vreemd. Te veel volk die hun mailadres willen weggeven? Niet op tijd klaar geraakt met deployen? Of is de load op de backends te hoog?
Hoedanook, 10 minuten later opnieuw geprobeerd en ik kwam daadwerkelijk op een eerste invulscherm. Treinkaartnummer en geboortedatum. Abo erbij gehaald voor dat 12-cijferige nummer, geboortedatum ging zo wel lukken. Of niet? 10-12-1968 is niet juist, 10/12/1968 wel. Dat schreven ze ook mooi zag ik daarna, maar hoe moeilijk is het om een datumveld met wat javascript te normaliseren?
Submitten en een goeie minuut of zo wachten en ier seh daar seh, het tweede scherm staat daar toch wel te blinken zekers! Mijn adresgegevens staan mooi vooraf ingevuld, synchrone connectie naar mainframe moeten doen, afgaande op de traagheid der applicatie?. Maar kom, een mens moet niet altijd klagen, vooruit met de geit! Mijn mailadres toevoegen, enkele checkboxes uitvinken (want nee, ik wil geen mails over promoties en nee, ik wil niet deelnemen aan enquêtes), submitten en … Halt, stop, eeks; bij submit zie ik dat die checkboxes allemaal terug aan staan!!! WTF! Cancel. Uitvinken. Opnieuw submit en die checkboxen flitsen terug aan, brrr … Doorbijten dan maar, ik zal die opties straks nog wel kunnen wijzigen veronderstel ik?
Even later, ik moest deze keer zelfs geen minuut wachten, een bevestigingsscherm. En wonder boven wonder, ze hebben mijn checkbox-vinkjes toch mooi verwerkt, geen spam van de NMBS voor Goossens. Jeuij! Maar er is blijkbaar nog een probleempje met het postcode-veld (dat uit die stoffige mainframe kwam). Of ik dat manueel wil verbeteren? Off course, we passen ‘9160 Eksaarde’ aan naar ‘9160 Lokeren’ en proberen opnieuw.
Twintig minuten en een half grof brood later (een mens leeft niet van internet alleen, maar van elke boterham die uit zijn vrouw haar pollen komt) kijken of er op dat nmbs-scherm al iets staat over het te winnen weekendbiljet. Auw. Nééééééééééé! Boel kapot. Een monsterachtige null-pointer-exception (de eigenlijke stacktrace liet ik weg);

The servlet at /updateAddr.do in WAR /cartetrain/SilverStream/Objectstore/Jars/addronline generated an exception
The error occurred on a ‘POST’ request to URL http://cartetrain.b-rail.be/cartetrain//addronline/updateAddr.do.
Aug 29, 2007 1:02:03 PM


Exception Information
com.sssw.shr.http.AgoServletException
The servlet at /updateAddr.do in WAR /cartetrain/SilverStream/Objectstore/Jars/addronline generated an exception
java.lang.NullPointerException

Niks aan te doen, ga terug naar start, u ontvangt geen geld? En terug naar start gaan, dat probeer ik nu alweer een kwartiertje, maar ik krijg na het invoeren van treinkaartnummer en geboortedatum steevast:

De toepassing die u wilt gebruiken is momenteel buiten dienst.
Wij verontschuldigen ons voor dit ongemak.

Pffff … Ik zal het straks even aan mijn vrouw vragen, maar ik denk echt niet dat ik nog steeds aan het smilen ben.
Persoonlijk bericht voor Directeur-Generaal Reizigers Nationaal Dhr. Ir. Sabin S’heeren: dit moet echt beter kunnen! Haal uw mainframe-mensen uit hun ivoren toren als het over ontsluiting van data op het web gaat. Laat de communicatie-ploeg, die uw sobere maar propere papieren brief schreven, meewerken aan de het online luik van de actie (op voorwaarde dat die mensen ook web ademen, natuurlijk). Betrek web-frontend-developers en usability-specialisten om de toepassing aangenaam in gebruik te maken (ook als het fout gaat, een woeste java stacktrace op argeloze bezoekers loslaten is tegenwoordig echt wel not done). En laat die dingen heel grondig testen, functioneel en technisch. Geef maar een seintje als het gerepareerd is. U kent mijn mailadres toch, niet?

Terracotta: transparante clustering voor Java?

terracotta logoNet gelezen op CMSWatch Trends; Terracotta is een nifty open source oplossing om Java-applicaties transparant te clusteren. CMSWatch vat de werking vlotjes als volgt samen:

“it works by clustering the Java Virtual Machine in such a way that even a participating JVM itself doesn’t know that it has been enlisted in a coordinated effort of any kind. Through a clever bit of boot-time dependency injection, Terracotta patches a handful of core JVM memory-management bytecode instructions, achieving transparent virtualization across any number of enlisted VMs, under the control of a Terracotta server that lives in “aspect space.” The Java memory model is not altered. Application code does not have to handle locks any differently or follow any special APIs, or even know that it’s been clustered.”

Terracotta kan op die manier zowat alle bekende Java-frameworks en -applicaties clusteren. Een greep uit het lijstje; Spring, Struts, Hibernate, Lucene, Wicket, Rife, Tomcat, JBoss, maar ook Bea Weblogic en IBM Websphere. Terracotta kan voorts instaan voor HTTP session replicatie (volgens benchmarks veel sneller dan Tomcat Pooled Sessions) en voor Distributed cache management (met Terracotta kan de beperking van de JVM heap size omzeilen).
Dat ziet er mooi uit, ook al snap ik het allemaal nog niet 100% (straks de demo eens bekijken, ziet er mij ‘for dummies’ uit). Maar U bent misschien wel al volledig mee? In dat geval: waar wacht U dan nog op? 😉
Aanvullende vraag: heeft er hier iemand al ervaring mee? In een productie-omgeving? Commentaar welkom!

Gezocht: website search

We zijn op het werk op zoek naar een nieuwe search-oplossing. De huidige zoek kan enkel content in het eCMS-repository van onze portal ontsluiten. Aangezien verschillende subsites niet meer in die te complexe omgeving zitten, ontbreken er veel relevante resultaten. Daarom zoeken we dus een min of meer kant-en-klare crawler-based oplossing (software of “in asp”) die al onze sites moet indexeren (gescheduled en ‘on demand’) en die, mits aangeroepen met de juiste parameters, resultaten voor 1, enkele of alle sites teruggeeft in de juiste taal en in de juiste look & feel.


Ik bekeek Searchblox (software) en Google Custom Search Business Edition (asp) al, maar ik twijfel er niet aan dat er nog goeie (en misschien wel volledig open source) oplossingen zijn. Wie ervaring met deze of andere producten heeft; de comment box hieronder is all yours, of contacteer me rechtstreeks.

Web 2.0 insecure? Bullshit (of dan toch grotendeels en nu ook met update)!

Op de Black Hat conference in LA werd gedemonstreerd hoe een GMail- of Facebook-sessie kan worden gehackt.


Voor zover ik kan zien, werd hier eigenlijk een wijd open deur ingetrapt; op een (Wifi-)netwerk alle verkeer naar bv. gmail of facebook sniffen, de session-waarde uit de cookie overnemen in de eigen cookie en voor je het weet zit ik in uw mailbox te snuisteren.
Het probleem heeft eigenlijk helemaal niets met web 2.0 te maken, maar gaat over de vreemde beslissing van oa. Google en Facebook (en eigenlijk zie je dat bijna overal) om enkel het login-proces te beveiligen (achter https te zetten). Eenmaal succesvol aangelogd ga je terug naar onbeveiligd verkeer (http zonder de s van secure) en dan is je cookie dus leesbaar voor iedereen die aan je netwerkverkeer kan.
De oplossing voor GMail is alvast eenvoudig: als je als URL zelf https://mail.google.com ingeeft, ben en blijf je in https en is ook je cookie niet meer zomaar te lezen. Ik heb mijn bookmark al aangepast 🙂 Bij Facebook en Linkedin lijkt dat alvast niet te lukken.
Meer info:

Update: ondertussen zit ik op de trein (bovenstaande had ik nog snel-snel op het werk geschreven) en ik heb nu even tijd om wat verder uit te weiden (en open deuren in te trappen) in de vorm van een paar vragen en antwoorden.
V: waarom zijn die (sessies in) cookies nodig?
A: omdat het web (het onderliggende http-protocol) eigenlijk ‘stateless’. Een request (de logon op Facebook bv.) kan aan serverkant enkel aan een volgende request (narcistisch bekijken van je vriendenlijst) gelinkt worden door middel van een sessie. Die sessie wordt geïdentificeerd door een sessionid, die maar op een paar manieren kan worden uitgewisseld; in een cookie, in een url (als parameter in een GET-request) of in een form (als parameter in een POST-request). Van die drie methodes is een cookie ontegensprekelijk de properste, maar qua security zijn ze in principe quasi even (on-)veilig.
V: waarom steken Google en al die andere hot-shots hun applicaties dan niet volledig achter https?
A: de s in https betekent dat alles geëncrypteerd wordt. Encryptie betekent dat de processoren aan ontvangende maar vooral verzendende kant wat meer werk hebben en dat de hoeveelheid data groter wordt (wat een geëncrypteerde tekst bestaat in principe uit meer karakters dan het origineel). Omdat Google, maar meer nog Facebook, Linkedin en andere fancy applicaties gebaat zijn bij het beperken van CPU-load en te versturen data, werken ze dus liever gewoon in http.
V: en kan die sessie dan niet op een andere manier beveiligd worden?
A: in principe wel, maar dan begeeft een developer zich in woelige wateren. Je zou aan serverkant kunnen bijhouden vanop welk ip-adres de gebruiker inlogt (evt. met nog een paar andere parameters zoals useragent van de browser) en dat voor elke request opnieuw controleren. Als een hacker dan met een sessie aan de haal gaat, is de kans groot (maar niet gegarandeerd) dat die parameters niet overeenkomen en dan kun je die malafide gebruiker vragen terug in te loggen. Andere (aanvullende) mogelijkheden zijn het beperken van de geldigheid van een sessie en het afblokken van gelijktijde gebruik van dezelfde login (het gelijktijdig gebruik van dezelfde sessie). Maar met al deze “oplossingen” is de kans groot dat je op bonafide gebruikers zult moeten lastigvallen om terug aan te loggen of zelfs buitensluiten (in het geval van concurrent sessions) . En dat maakt gebruikers zenuwachtig.
Conclusie: er is geen ontkomen aan, je moet https echt vanaf login tot aan de logout gebruiken (en voor alles, ook images in die pagina’s, anders krijg je in sommige browsers lelijke security-warnings). Eén troost: er bestaan hardware-oplossingen (ssl-encryptie devices en insteekkaarten) om de impact op CPU-load tot een minimum te beperken. Met de grotere hoeveelheid dataverkeer zul je dan maar moeten leren leven 🙂