Bugi Nucleuksessa ja kuinka se korjataan

Nucleuksessa tulee mukana tiedosto, joka listaa uusimmat jutut RSS-muodossa. Koodissa on valmiiksi tehtynä koodi, jonka avulla RSS-virran pitäisi tukea conditional getiä ja vähentää näin kaistan tarvetta, koska sen avulla RSS-virta lähetetään vastaanottajalle vain, jos sisältö on muuttunut. Ikävä kyllä koodissa on bugi, jonka takia systeemi ei toimi. Itse asiassa koodin kirjoittajakin on sen huomannut ja kommentoinut sen koodiin.

Conditional get toimii niin, että RSS-virran versio merkitään tietyllä koodilla, joka vaihtuu aina kun sisältö muuttuu. Kun RSS-lukijaohjelma hakee RSS-virtaa uudestaan, ohjelma lähettää tuon koodin ”If-None-Match”-headerissa serverille, joka voi halutessaan sen perusteella lähettää lukijaohjelmalle ”304 Not Modified”-headerin. Jos sisältö on muuttunut, lähetetään ohjelmalle uusi sisältö ja sen mukana uusi koodi.

Sisällön yksilöivä koodi laitetaan headeriin nimeltä ”Etag”. Koodi voi olla esimerkiksi viimeinen muutospäivämäärä tai – kuten Nucleuksessa – MD5-tiiviste sisällöstä. Koodi voi oikeastaan olla millainen vain, mutta sen ympärillä pitää olla lainausmerkit.

Nucleuksen koodissa ongelmana on se, että lukijaohjelman palauttamassa koodissa on mukana lainausmerkit ja vieläpä niin, että niiden edessä on kenoviivat. Siksi sisällöstä laskettu koodi ja lukijaohjelman antama koodi eivät koskaan täsmää ja koko sisältö lähetetään aina vastaanottajalle.

Tässä nykyinen koodi tiedostoissa xml-rss.php ja xml-rss2.php:

// create ETAG (hash of feed)
$eTag = md5($feed);
header('Etag: "'.$eTag.'"');

// compare Etag to what we got
// TODO: serverVar doesn't seem to work :((
if ($eTag == serverVar('HTTP_IF_NONE_MATCH')) {
     header("HTTP/1.0 304 Not Modified");
     header('Content-Length: 0');
} else {
     // dump feed
     echo $feed;
}

Näin sen saa toimimaan oikein:

// create ETAG (hash of feed)
$eTag = '"'.md5($feed).'"';
header('Etag: '.$eTag);

// compare Etag to what we got
if ($eTag == stripslashes(serverVar('HTTP_IF_NONE_MATCH'))) {
     header("HTTP/1.0 304 Not Modified");
     header('Content-Length: 0');
} else {
     // dump feed
     echo $feed;
}

Ongelman selvittämisessä auttoi muuten Interarchyn Traffic Watch, jolla voi kätevästi seurata TCP/IP-liikennettä.