Toutes les réponses aux demandes-cadres sont basées sur un principe requête http --> serveur wsgi --> interface wsgi (en fait, la fonction implémentée par une implémentation personnalisée dans le framework est encapsulée en bas) --> Vous pouvez vous référer à l'explication de l'interface wsgi dans le tutoriel de Liao Xuefeng
class HeaderDict(dict):''' A dictionary with case insensitive (titled) keys. You may add a list of strings to send multible headers with the same name.'''def __setitem__(self, key, value):return dict.__setitem__(self,key.title(), value) #注意这里使用title函数,它能将每个单词的开头大写def __getitem__(self, key):return dict.__getitem__(self,key.title())def __delitem__(self, key):return dict.__delitem__(self,key.title())def __contains__(self, key):return dict.__contains__(self,key.title())def items(self):""" Returns a list of (key, value) tuples """for key, values in dict.items(self):if not isinstance(values, list): values = [values]for value in values:yield (key, str(value)) def add(self, key, value):""" Adds a new header without deleting old ones """if isinstance(value, list):for v in value:self.add(key, v) #注意这里使用了递归elif key in self:if isinstance(self[key], list):self[key].append(value)else:self[key] = [self[key], value]else: self[key] = [value]
HeaderDict encapsule le dict et met en majuscule la première lettre du mot dans la clé du dictionnaire. Et transformez la valeur en un objet itérable et transformez la valeur en un objet de liste, c'est-à-dire value=[value]. Le standard WSGI définit qu'un type chaîne doit être converti en type liste, ce qui lui donnera une meilleure représentation. Le serveur n'a pas besoin de produire tout en même temps, mais peut utiliser le rendement pour contrôler la sortie afin d'éviter d'en produire trop à la fois. Au total, cette classe qui encapsule dict implémente deux fonctions :
Convertir la valeur en liste, optimiser la représentation des données
Convertir la première lettre de le mot dans la clé est en majuscule
def abort(code=500, text='Unknown Error: Appliction stopped.'):""" Aborts execution and causes a HTTP error. """raise HTTPError(code, text)def redirect(url, code=307):""" Aborts execution and causes a 307 redirect """response.status = code response.header['Location'] = urlraise BreakTheBottle("")def send_file(filename, root, guessmime = True, mimetype = 'text/plain'):""" Aborts execution and sends a static files as response. """root = os.path.abspath(root) + '/'filename = os.path.normpath(filename).strip('/') filename = os.path.join(root, filename)#判断文件是否可获得if not filename.startswith(root): #主目录下的文件不可以下载abort(401, "Access denied.")if not os.path.exists(filename) or not os.path.isfile(filename): abort(404, "File does not exist.")if not os.access(filename, os.R_OK): abort(401, "You do not have permission to access this file.")# 获得文件类型if guessmime: guess = mimetypes.guess_type(filename)[0]if guess: response.content_type = guesselif mimetype: response.content_type = mimetypeelif mimetype: response.content_type = mimetype#设置Content_typestats = os.stat(filename)# TODO: HTTP_IF_MODIFIED_SINCE -> 304 (Thu, 02 Jul 2009 23:16:31 CEST)if 'Content-Length' not in response.header: response.header['Content-Length'] = stats.st_sizeif 'Last-Modified' not in response.header: ts = time.gmtime(stats.st_mtime) ts = time.strftime("%a, %d %b %Y %H:%M:%S +0000", ts) response.header['Last-Modified'] = tsraise BreakTheBottle(open(filename, 'r'))
Les trois fonctions ci-dessus implémentent respectivement les erreurs internes du serveur, la redirection et le téléchargement de fichiers. Cette fonction de téléchargement de fichiers implémente le jugement du type de fichier, le réglage de Content_type, le jugement des autorisations de fichier, l'obtention de l'état du fichier, etc. Cette fonction reste très simple et peut être personnalisée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!