Jak již bylo ukázáno v
minulém článku, je soubor dispatch_table.py základním souborem při použití Poor API.
handlers
Jedinou podmíněnou komponentou souboru dispatch_table.py je slovník handlers. Ten pak musí obsahovat pár metoda a tuple typ metody a funkce, která metodu obslouží. Funkce v parametru dostane objekt Request. Zřejmé to bude z ukázky:
handlers = {
'/' : (http.METHOD_GET, index),
'/login' : (http.METHOD_GET, login),
'/dologin' : (http.METHOD_POST, dologin),
'/dologout' : (http.METHOD_GET_POST, dologout),
}
Typ METHOD_GET_POST značí, že metoda aplikace bude obsloužena jak v případě GET tak POST požadavku. V případě že nějaká metoda aplikace má nastavený pouze typ METHOD_POST, nebude obsloužena GET požadavkem a server vrátí chybu 404 Not Found. Z výše popsaného také vyplývá, že každý typ požadavku může být obsloužen jinak. Například metoda / může mít obsluhu na typ METHOD_HEAD, která bude jen testovat ostatní komponenty aplikace, třeba spojení do databáze.
errors
Slovník errors je nepovinný a musí obsahovat páry http_chyba, funkce obsluhy chyb. Stejně jako funkce obsluhující metodu aplikace, i funkce obsluhující http chybu dostávají v parametru objekt Request. Tento slovník se tedy používá, chceme-li obsloužit chybové stavy aplikace vlastními stránkami. V případě, že potřebujeme rozlišit obsluhu různých druhů výjimek v aplikaci, můžeme v handleru chyby 500 testovat hodnotu sys.exc_type.
errors = {
http.HTTP_INTERNAL_SERVER_ERROR : my_internal_server_error,
http.HTTP_NOT_FOUND : my_page_not_found,
}
Definice vlastního chybového handleru zpracovávající status 500 Internal Server Error:
def my_internal_server_error(req):
req.status = HTTP_INTERNAL_SERVER_ERROR
if sys.exc_type == exceptions.MemoryError:
req.write(„problem s pameti”)
elif sys.exc_type == exceptions.TypeError:
req.write(„divny typ”)
else:
req.write(„Proste chyba”)
return DONE
setreq
Funkce setreq pokud je v souboru dispatch_table.py definována, je volána před každou obsluhou http požadavku, tedy ještě dříve než je známa informace, zda tento požadavek může být vůbec obsloužen. Tato funkce se hodí například na zpracování konfigurace, případě před-vypočítání nějakých hodnot. Stejně jako ostatní handlery (obsluhující funkce) i tento dostává v parametru objekt Request.
init = False
re_mail = None
def setreq(req):
global re_mail
global init
if not init:
re_mail = re.compile("^[a-z0-9\-_\.]+@[a-z0-9\-_\.]+$")
req.log_error('Reinicalizace ...', http.LOG_DEBUG)
init = True
#endif
req.re_mail = re_mail
#enddef
V ukázce je využíváno situace, kdy apache je puštěn v režimu prefork, nebo poor http v režimu single příp. thread. Tyto režimy importují soubor dispatch_table.py jen jednou, případně jednou za N požadavků. Díky tomu je možné v jeho namespace nastavit nějaké proměnné, které pak zjišťují poslední stav, a jeli to třeba provedou příslušnou inicializaci. Zkompilování regulárního výrazu je samozřejmě jen příklad, protože to se může dít přímo v souboru mimo jakou-koli funkci. Po testování této funkce, se v při různých režimech serveru objeví v logu hlášení o reinicializaci různě často.
Soubor dispatch_table.py samozřejmě může obsahovat i jednotlivé funkce, nebo chcete-li handlery. Ty je však vhodné dát do jiných souborů. Z tohoto textu bude vycházet i připravovaná dokumentace, budu proto velmi rád, pokud jej budete připomínkovat v diskuzi pod článkem.