[php] pagina cache "poisonen"

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 08:20
Voor een CMS ben ik bezig met een cache. Hierin wordt de uitvoer van de template-engine van het CMS opgeslagen. Veel voorbeelden die ik (via search) vond doen ongeveer dit:

- Neem $_SERVER['REQUEST_URI'] en stop dit in md5()
- Plak er een extensie achter om een bestandsnaam te krijgen
- Kijk in een bepaalde dir of er een bestand bestaat met die bestandsnaam
- Als het bestand bestaat, kijk hoe oud het is, en update eventueel het bestand
- Stuur de inhoud van het bestand naar de browser

Het probleem echter met deze methode is -volgens mij- dat je het wel makkelijk maakt om je server "over zijn nek te helpen". Als je namelijk het URL maar 1 teken wijzigt komt er een nieuw bestand op de server. Kortom als je een scriptje schrijft dat een paar duizend verschillende URL's stuurt (countertje erin opnemen), dan komen er even zovele bestandjes bij op de server. Theoretisch gezien zou je hier dus net zolang mee door kunnen gaan tot de server vol staat (in de praktijk zal dit lang duren maar dat even terzijde).

De enige echte oplossing voor dit probleem leek me het niet meer cachen van templates waarbij GET/POST data gebruikt wordt en dan cachen op templatenaam i.p.v. request_uri. Maar dan kunnen dus behoorlijk wat templates niet meer gecached worden. :(

Andere oplossingen waar ik zo snel op kon komen waren:
- niet meer dan x cachefiles per template aanmaken
- cache niet groter dan x files

Maar dat levert dus wel wat extra rekenwerk op. Iemand misschien een beter idee?

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 12:54

Bosmonster

*zucht*

Wat je kunt doen is als er een foutmelding gegenereert wordt door je systeem (je errorhandler), de pagina niet cachen. Zo voorkom je dat mensen tot oneindig door foute argumenten mee gaan geven.

Combineer dit met het bewerken en opnieuw samenstellen van je url voor je hem md5't en opslaat. Pak dus ff parse_url en laat alleen die argumenten staan die voor jouw applicatie van belang zijn.

Nu moet je kwaadwillige bezoeker wel erg goed weten hoe je systeem in elkaar zit wil die je server nog om zeep helpen ;)

Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 08:20
Bosmonster, bedankt voor je snelle respons, maar ik vrees dat die oplossing niet gaat werken vanwege de opzet van het systeem... Het werkt ongeveer zo, de beheerder kan in het CMS een template aanmaken, bijvoorbeeld:

template = "nieuwsbericht"
code:
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head></head>
<body>
{section query = nieuws}
{$titel}<br />
<br />
{$bericht}<br />
{noresults}
<b>Het bericht bestaat niet...</b><br />
{/section}
</body>
</html>


Bij het "section"-stuk wordt de bijbehorende query opgehaald en eventuele variabelen erin worden vervangen (en uiteraard gestript van nare tekens):

query "nieuws":
code:
1
SELECT * FROM `nieuws` WHERE `id` = '{$id}';


Als je de pagina dus aanroept met "view.php?template=nieuwsbericht&id=1" dan wordt het template ingevuld met de data van het nieuwsbericht met id = 1. Als dat bericht er niet is komt er "Het bericht bestaat niet..." te staan.

Aangezien de beheerder zelf de templates en de queries aan kan maken, er meerdere secties en variabelen in kunnen zitten etc. is het nogal lastig te bepalen welke variabelen in de URL van toepassing zijn. Daarnaast is een sectie waar geen resultaten inzitten niet per definitie "fout": een andere sectie kan wel gevuld zijn en zou dus ook gecached moeten worden...

Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-09 16:19

alienfruit

the alien you never expected

Waarom laat je het niet gewoon de proxy de caching doen :-)
Overigens kun je natuurlijk wel, een time out functie in de caching bouwen zodat de caching zelf naar x dagen/minuten zichzelf killed.

Zelf maak ik niet gebruik van caching, omdat ik anders geen dynamic content, dynamic metadata e.d. kan gebruiken. In iedergeval ik heb zelf er nog geen goede oplossing voor gevonden. Overigens kan ik nou niet zeggen dat output caching een goede methode is om de performance op te hogen.

[ Voor 92% gewijzigd door alienfruit op 06-07-2003 20:45 ]


Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 08:20
Een proxy zou een goed idee zijn, ware het niet dat het op een (zeer goedkope) host moet draaien en er dus geen proxy is :)

Die timeout zou tenslotte erg kort moeten zijn omdat het opvragen van een paar duizend URL's in een minuutje gebeurd is: dan heeft cachen ook niet zo'n zin meer...

Verder ben ik met je eens dat output-cachen geen wondermiddel is, maar het kan zeker op erg drukke sites een hoop server-resources schelen. Om de performance gaat het me dan nog niet eens zo zeer, omdat het parsen door de template engine volgens mij best ok gaat (geen direct vergelijkingsmateriaal), maar meer om die resources.

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 12:54

Bosmonster

*zucht*

Als je dan toch een volledig CMS- en component-based systeem hebt dat veel bezoekers aan moet kunnen, laat dan onderdelen voorgenereren als een gebruiker deze heeft aangemaakt. Maak onderscheid tussen werkelijk dynamische delen (bijvoorbeeld datum/tijd afhankelijke delen) en statische componenten. De losse componenten (includes) kun je zo voorrenderen of zelfs grote delen van de template.
view.php?template=nieuwsbericht&id=1
Dit zijn al hele lekkere urls natuurlijk om flink mee te lopen kutten. Als je dan toch templates opslaat in de database, geef dan de ID mee. Of beter nog, zorg dat de template al aan je pagina is gekoppeld en geef alleen de id van de pagina mee. Anders kunnen mensen alsnog zomaar wat templates op gaan geven met wat id's. Nogal nutteloos :)

[ Voor 36% gewijzigd door Bosmonster op 06-07-2003 21:04 ]


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-09 16:19

alienfruit

the alien you never expected

Volgens mij helpt het gebruiken van human readable urls ook nog in de output caching ;)

Overigens verder heb ik laatst nog een interessante white paper gevonden, hoe IBM de Olympische Spelen en Wimbledon web-site qua hardware structuur heeft opgebouwd; hartstikke interessant op te lezen: http://domino.watson.ibm....0673626/$File/RC22426.pdf

Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 08:20
Tsja een soort compiler van templates zou natuurlijk beter zijn dan een simpele output cache, maar ik ga dat ff niet redden op de korte termijn: dat vergt flink wat werk nl.

Daarnaas is het URL maar een voorbeeld, maar het zal idd modelijk blijven om een zootje templates & id's op te geven. Daarom wil ik dus ook per template cachen (en ik kan natuurlijk wel makkelijk controleren of het template bestaat). Verder mag iedereen best combo's van templates & id's gaan proberen: je krijgt dan of een "template not found" of "nieuwsbericht niet gevonden". Ik zie het probleem daarvan niet zo, of met name: een andere oplossing niet.

De ID's in de database kan niet: dan moet ik voor ieder nieuwsbericht een apart template op gaan slaan wat ook nog voor 99% hetzelfde is. Da lijkt me ook niet zo zinvol toch? :)

Tenslotte is de literatuur over IBM best wel interessant, maar _zoveel_ bezoekers zal het ook weer niet gaan trekken ;)

[ Voor 7% gewijzigd door Morrar op 06-07-2003 23:04 ]


Acties:
  • 0 Henk 'm!

  • Rense Klinkenberg
  • Registratie: November 2000
  • Laatst online: 03-09 14:12
Morrar schreef op 06 July 2003 @ 23:04:
Tsja een soort compiler van templates zou natuurlijk beter zijn dan een simpele output cache, maar ik ga dat ff niet redden op de korte termijn: dat vergt flink wat werk nl.
Kijk een naar Smarty. Dat is een template engine die de templates compileert naar geoptimaliseerde php code.

Verder is het misschien handig om ook eens naar PEAR::Cache of PEAR::Cache_Lite te kijken. Biede classes doen hetzelfde als jij wilt (het opslaan van data die geidentificeerd wordt door een bepaalde key). PEAR::Cache is de uitgebreidere versie waarmee je, als je host het toestaat, zelf naar shared memory kan cachen. PEAR::Cache_Lite is, zoals de naam al aangeeft, de simpelere versie die alleen maar een file-based cache container heeft.

Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 08:20
freak007 schreef op 07 July 2003 @ 12:14:
[...]
Verder is het misschien handig om ook eens naar PEAR::Cache of PEAR::Cache_Lite te kijken. Biede classes doen hetzelfde als jij wilt (het opslaan van data die geidentificeerd wordt door een bepaalde key). PEAR::Cache is de uitgebreidere versie waarmee je, als je host het toestaat, zelf naar shared memory kan cachen. PEAR::Cache_Lite is, zoals de naam al aangeeft, de simpelere versie die alleen maar een file-based cache container heeft.
Ja Smarty heb ik een beetje als uitgangspunt genomen en is idd wat ik wil. Maar Smarty viel niet helemaal te integreren in het CMS. Vandaar dat ik zelf (en voor de sport natuurlijk) ben gaan friemelen :)

Verder was ik PEAR::Cache ook tegengekomen, maar ik kon daar zo snel ff geen goede docs van vinden. Moe ik dus nog ff voor Googlen... Ownee dat mocht niet meer: met Google naar zoeken :P

//edit: meest uitgebreide doc was dus deze:
http://www.onlamp.com/pub/a/php/2001/10/11/pearcache.html, waarbij je ook weer ziet dat ze tuch URI en variabelen gebruiken voor de output cache:
code:
1
2
3
4
5
6
7
$cache_id = $cache->generateID(
  array(
    'url' => $REQUEST_URI,
    'post' => $HTTP_POST_VARS,
    'cookies' => $HTTP_COOKIE_VARS
  )
);

[ Voor 17% gewijzigd door Morrar op 07-07-2003 13:25 ]

Pagina: 1