Python BaseHTTPServer 介紹

發表於2017-02-21

本文針對 python 2.7 版本,介紹了 BaseHTTPServer 這個庫的使用方法。

這個庫是 python 自帶的標準庫的一部分,不需要額外安裝,在 linux 系統下,位置在 /usr/lib/python2.7/BaseHTTPServer.py

HTTP 協議

HTTP 請求(request)

http 請求分為三個部分:

  1. 第一行:請求型別、地址和版本號
  2. 頭部資訊:HTTP header
  3. 資料部分

標準的 HTTP 請求是:

標準的 HTTP 響應頭部:

使用 BaseHTTPServer 寫一個簡單的 web server

這個類可以幫助你快速編寫一個 HTTP 服務端 server。別說了,先上程式碼:

這段程式碼實現的功能很簡單,就是一個簡單的 Todo 管理:你可以新增 todo,也可以查詢 todo。更新和刪除 todo 可以根據上面的程式碼自行新增。

程式碼也不難理解,在關鍵的步驟我已經新增了註釋,在這裡就不再解釋了。

好了,我們用 httpie 來和它互動一下,最開始的時候返回的資料是空的

然後,新增幾條試試:

這個時候,再來看一下內容:

我們剛剛建立的 todo 就出現了!前面也說了,這段程式碼不支援更新和刪除功能,而且資料也沒有落地,關閉程式之後,資料就消失了。

BaseHTTPServer 原始碼解析

BaseHTTPServer 這個模組提供了兩個類讓開發者實現 HTTP server:HTTPServerBaseHTTPRequestHandler

HTTPServer 繼承了 SocketServer.BaseServer,主要功能是:建立和監聽 socket,把請求轉發給 handler 去處理。主要的工作都是在 BaseHTTPRequestHandler 中處理的,它把和請求有關的資訊都封裝成自己的例項變數,可以在子類中直接使用。這些變數包括:

  • client_address:客戶端的地址,存放在一個 tuple 裡 (host, port)
  • server: server 例項
  • command:請求型別,比如,GET、POST 等
  • path:請求路徑,比如 /index.html
  • request_version: 請求版本號,比如 HTTP/1.0
  • headers:mimetools.Message 的例項物件,包含了頭部資訊
  • rfile:rfile 是一個輸入流,用來讀取請求的資料
  • wfile:wfile 是一個輸出流,用來回寫響應,回寫的資料必須遵守 HTTP 協議的格式

除了這些例項變數之外,還有其他的類變數:

  • server_version:伺服器的版本號,比如 BaseHTTP/0.2
  • sys_version:python 的版本號,比如 Python/1.4
  • error_message_format:錯誤 response 的格式
  • error_content_type:錯誤 response 的 Content-Type,預設是 text/html
  • protocol_version:HTTP 協議版本號
  • responses:error code 對應錯誤訊息的匹配關係

當然,還有一些方法可以使用:

  • handle():呼叫底層的實現來處理一次請求
  • send_response():傳送應答訊息和狀態碼

更多的內容可以檢視文末的連結。

為什麼這個類不會被廣泛使用?

寫了這麼多,我們也看到這個類缺點很多,比如:

  • 不支援 url 解析和轉發,如果有多個 endpoint,需要使用者自己解析
  • 回寫的響應也需要使用者自己維護格式,容易出錯
  • 沒有模板支援,如果要寫 HTML 頁面,也需要自己維護

所以在正式的工作中,編寫 HTTP server 端應用的時候,都是使用 web 框架的。因為 web 框架幫你封裝了底層的這些細節,還提供了很多便利的功能,讓開發者把中心更多地放到業務邏輯的實現。

如果有時間,以後講講怎麼自己寫一個簡單的 HTTP Server。

參考資料

相關文章