1. 程式人生 > >仿寫以WSGI為標準的web框架體

仿寫以WSGI為標準的web框架體

return 匹配 無法 元組 錯誤 .cn 通信 服務 關於

1 動態web框架

  1.1 web框架要和web服務器軟件分開(如MVC)

  1.2 web框架要和web服務器有良好的交互通信(python為自身的web框架制定了WSGI標準)

  1.3 web框架要和數據庫有良好的讀寫通信方法

2 關於WSGI標準

技術分享

WSGI將Web服務分成兩個部分:服務器和應用程序。WGSI服務器只負責與網絡相關的兩件事:接收瀏覽器的 HTTP請求、向瀏覽器發送HTTP應答;而對HTTP請求的具體處理邏輯,則通過調用WSGI應用程序進行。

2.1 一個個簡單wsgi實現應用

from wsgiref.simple_server import make_server


def wsgi_app(environ, start_response): status = 200 ok response_header = [(Content_Type, text/html)] start_response(status, response_headers) return there is a wsgi app! httpd = make_server(0.0.0.0,80,wsgi_app) httpd.serve_forever()

environ是一個包含全部HTTP請求信息的字典/Dict,由WSGI服務器解包HTTP請求生成。

2.2 WSGI模型特點:

  1.在web框架模塊,以上面的栗子為例,web服務器軟件會向web框架傳遞一個列表(environ)和一個函數(函數體在web服務器軟件中實現)的引用(start_response),然後web框架要實現一個app函數,並將 "一個列表"和"一個函數的引用",作為兩個參數;

  2.傳遞過來的列表內部存儲了N個元組,這些元組包含了web服務器接收到的客戶端瀏覽器的請求信息, 傳遞過來的函數參數的引用,可以用來返回請求資源的狀態反饋(如果請求的資源可以訪問,就會返回200,如果資源無法訪問,就返回404或502之類的錯誤;

  3.傳遞過來的函數引用的調用比return更靠前,這樣可以在返回正式的網頁之前的這段時間,讓web服務器軟件做好接收數據的準備;(其實可以將函數的引用作為web框架與web服務器軟件傳遞數據的的一種快捷方式);

所以web服務器框架至少要實現三個功能

  1.創建 包含客戶端請求頭消息的列表(作為第一個參數傳遞);

  2.創建一個可以解析返回狀態信息的函數(作為第二個參數傳遞);

  3.接收web框架內app函數返回的body,並將body與作為第二個參數的引用的函數的返回狀態值組合,一同發送給客戶端瀏覽器

3 具體實現

3.1 首先需要實現一個WISG的類作為server

class WSGI(object):
    def __init__(self, port, app):
        裏面主要是初始化的socket定義
        ....
        # 獲取web框架的引用
        self.app = app  
        pass
    
    # 啟動服務器對象入口函數
    def run_forever(self):
        self.create_new_socket()
        pass
        
    def create_new_socket(self):
        while True:
            ...
            # 對請求進行相應的處理
            self.deal_accept_data(new_client_socket)  
        
    def deal_accept_date(self, new_client_socket):
        # 接收數據
        recv_data = new_client_socket.recv(1024)
        # 將接收的數據轉換為列表
        recv_data_list = recv_data.splitlines()
        
        獲取請求頭
        request_header = recv_data_list[0]
        
        # 該方法就是獲取請求頭中.../.../...html,用於app處理
        # GET /index.html HTTP/1.1
        html_name = get_html(request_header)
        
        # 進入動態app處理階段
        # 獲取web框架並且返回數據
        
        #創建一個字典,用於存儲請求的參數
        enverion = dict()
        enverion[PATH_INFO] = html_name
        
        # 啟動web框架進行處理, 返回response的header和body
        dynamic_content = self.app(enverion, start_response)
        
        #發送和關閉
        new_client_socket.send(dynamic_content)
        new_client_socket.close()
        
    
    def main():
        # 導入web框架的app
        app = __import__(file_name)
        
        # 啟動web服務器
        web_server = WSGI(port, app)
        web_server.run_forever()

3.2 按照wsgi標準實現的web框架

def app(enverion, start_response):
    # response是可以根據需求所改變的,可以根據environ的參數
    
    # 設置狀態碼
    status = 200 ok
    # 設置返回的網頁類型
    response_headers = [(Content_Type, text/html)]  
    
    # 向web框架中定義的函數start_response中傳入頭部信息
    # 先處理response的headers, 再對content進行返回
    start_response(status, response_headers)
    
    # 根據匹配的路徑返回需要的response的body
    path_name = enverion[PATH_INFO]
    content = process_path(path_name)
    return content
    
    
def process_path(path_name)
    尋找處理的函數
    v_func = match_path(path_name)
    content = v_func.return_result()
    return content

仿寫以WSGI為標準的web框架體