http.server
--- HTTP 服務(wù)器?
源代碼: Lib/http/server.py
這個(gè)模塊定義了用于實(shí)現 HTTP 服務(wù)器的類(lèi)。
警告
不推薦在生產(chǎn)環(huán)境中使用 http.server
。它只實(shí)現了基本的安全檢查功能。
HTTPServer
是 socketserver.TCPServer
的一個(gè)子類(lèi)。它會(huì )創(chuàng )建和偵聽(tīng) HTTP 套接字,并將請求分發(fā)給處理程序。創(chuàng )建和運行 HTTP 服務(wù)器的代碼類(lèi)似如下所示:
def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
- class http.server.HTTPServer(server_address, RequestHandlerClass)?
該類(lèi)基于
TCPServer
類(lèi),并在實(shí)例變量server_name
和server_port
中保存 HTTP 服務(wù)器地址。處理程序可通過(guò)實(shí)例變量server
訪(fǎng)問(wèn) HTTP 服務(wù)器。
- class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)?
該類(lèi)相似于 HTTPServer ,只是會(huì )利用
ThreadingMixIn
對請求進(jìn)行多線(xiàn)程處理。當需要對 Web 瀏覽器預先打開(kāi)套接字進(jìn)行處理時(shí),這就很有用,這時(shí)HTTPServer
會(huì )一直等待請求。3.7 新版功能.
實(shí)例化 HTTPServer
和 ThreadingHTTPServer
時(shí),必須給出一個(gè) RequestHandlerClass,本模塊提供了該對象的三種變體:
- class http.server.BaseHTTPRequestHandler(request, client_address, server)?
這個(gè)類(lèi)用于處理到達服務(wù)器的 HTTP 請求。 它本身無(wú)法響應任何實(shí)際的 HTTP 請求;它必須被子類(lèi)化以處理每個(gè)請求方法(例如 GET 或 POST)。
BaseHTTPRequestHandler
提供了許多供子類(lèi)使用的類(lèi)和實(shí)例變量以及方法。這個(gè)處理程序將解析請求和標頭,然后調用特定請求類(lèi)型對應的方法。 方法名稱(chēng)將根據請求來(lái)構造。 例如,對于請求方法
SPAM
,將不帶參數地調用do_SPAM()
方法。 所有相關(guān)信息會(huì )被保存在該處理程序的實(shí)際變量中。 子類(lèi)不需要重載或擴展__init__()
方法。BaseHTTPRequestHandler
具有下列實(shí)例變量:- client_address?
包含
(host, port)
形式的指向客戶(hù)端地址的元組。
- server?
包含服務(wù)器實(shí)例。
- close_connection?
應當在
handle_one_request()
返回之前設定的布爾值,指明是否要期待另一個(gè)請求,還是應當關(guān)閉連接。
- requestline?
包含 HTTP 請求行的字符串表示。 末尾的 CRLF 會(huì )被去除。 該屬性應當由
handle_one_request()
來(lái)設定。 如果無(wú)有效請求行被處理,則它應當被設為空字符串。
- command?
包含具體的命令(請求類(lèi)型)。 例如
'GET'
。
- path?
包含請求路徑。如果URL的查詢(xún)部分存在,
path
會(huì )包含這個(gè)查詢(xún)部分。使用 RFC 3986 的術(shù)語(yǔ)來(lái)說(shuō),在這里,path
包含hier-part
和query
。
- request_version?
包含請求的版本字符串。 例如
'HTTP/1.0'
。
- headers?
存放由
MessageClass
類(lèi)變量所指定的類(lèi)的實(shí)例。 該實(shí)例會(huì )解析并管理 HTTP 請求中的標頭。http.client
中的parse_headers()
函數將被用來(lái)解析標頭并且它需要 HTTP 請求提供一個(gè)有效的 RFC 2822 風(fēng)格的標頭。
- rfile?
一個(gè)
io.BufferedIOBase
輸入流,準備從可選的輸入數據的開(kāi)頭進(jìn)行讀取。
- wfile?
包含用于寫(xiě)入響應并發(fā)回給客戶(hù)端的輸出流。 在寫(xiě)入流時(shí)必須正確遵守 HTTP 協(xié)議以便成功地實(shí)現與 HTTP 客戶(hù)端的互操作。
在 3.6 版更改: 這是一個(gè)
io.BufferedIOBase
流。
BaseHTTPRequestHandler
具有下列屬性:- server_version?
指定服務(wù)器軟件版本。 你可能會(huì )想要重載該屬性。 該屬性的格式為多個(gè)以空格分隔的字符串,其中每個(gè)字符串的形式為 name[/version]。 例如
'BaseHTTP/0.2'
。
- sys_version?
包含 Python 系統版本,采用
version_string
方法和server_version
類(lèi)變量所支持的形式。 例如'Python/1.4'
。
- error_message_format?
指定應當被
send_error()
方法用來(lái)構建發(fā)給客戶(hù)端的錯誤響應的格式字符串。 該字符串應使用來(lái)自responses
的變量根據傳給send_error()
的狀態(tài)碼來(lái)填充默認值。
- error_content_type?
指定發(fā)送給客戶(hù)端的錯誤響應的 Content-Type HTTP 標頭。 默認值為
'text/html'
。
- protocol_version?
Specifies the HTTP version to which the server is conformant. It is sent in responses to let the client know the server's communication capabilities for future requests. If set to
'HTTP/1.1'
, the server will permit HTTP persistent connections; however, your server must then include an accurateContent-Length
header (usingsend_header()
) in all of its responses to clients. For backwards compatibility, the setting defaults to'HTTP/1.0'
.
- MessageClass?
指定一個(gè)
email.message.Message
這樣的類(lèi)來(lái)解析 HTTP 標頭。 通常該屬性不會(huì )被重載,其默認值為http.client.HTTPMessage
。
- responses?
該屬性包含一個(gè)整數錯誤代碼與由短消息和長(cháng)消息組成的二元組的映射。 例如,
{code: (shortmessage, longmessage)}
。 shortmessage 通常是作為消息響應中的 message 鍵,而 longmessage 則是作為 explain 鍵。 該屬性會(huì )被send_response_only()
和send_error()
方法所使用。
BaseHTTPRequestHandler
實(shí)例具有下列方法:- handle()?
調用
handle_one_request()
一次(或者如果啟用了永久連接則為多次)來(lái)處理傳入的 HTTP 請求。 你應該完全不需要重載它;而是要實(shí)現適當的do_*()
方法。
- handle_one_request()?
此方法將解析并將請求分配給適當的
do_*()
方法。 你應該完全不需要重載它。
- handle_expect_100()?
When an HTTP/1.1 conformant server receives an
Expect: 100-continue
request header it responds back with a100 Continue
followed by200 OK
headers. This method can be overridden to raise an error if the server does not want the client to continue. For e.g. server can choose to send417 Expectation Failed
as a response header andreturn False
.3.2 新版功能.
- send_error(code, message=None, explain=None)?
發(fā)送并記錄回復給客戶(hù)端的完整錯誤信息。 數字形式的 code 指明 HTTP 錯誤代碼,可選的 message 為簡(jiǎn)短的易于人類(lèi)閱讀的錯誤描述。 explain 參數可被用于提供更詳細的錯誤信息;它將使用
error_message_format
屬性來(lái)進(jìn)行格式化并在一組完整的標頭之后作為響應體被發(fā)送。responses
屬性存放了 message 和 explain 的默認值,它們將在未提供時(shí)被使用;對于未知代碼兩者的默認值均為字符串???
。 如果方法為 HEAD 或響應代碼是下列值之一則響應體將為空:1xx
,204 No Content
,205 Reset Content
,304 Not Modified
。在 3.4 版更改: 錯誤響應包括一個(gè) Content-Length 標頭。 增加了 explain 參數。
- send_response(code, message=None)?
將一個(gè)響應標頭添加到標頭緩沖區并記錄被接受的請求。 HTTP 響應行會(huì )被寫(xiě)入到內部緩沖區,后面是 Server 和 Date 標頭。 這兩個(gè)標頭的值將分別通過(guò)
version_string()
和date_time_string()
方法獲取。 如果服務(wù)器不打算使用send_header()
方法發(fā)送任何其他標頭,則send_response()
后面應該跟一個(gè)end_headers()
調用。在 3.3 版更改: 標頭會(huì )被存儲到內部緩沖區并且需要顯式地調用
end_headers()
。
- send_header(keyword, value)?
將 HTTP 標頭添加到內部緩沖區,它將在
end_headers()
或flush_headers()
被發(fā)起調用時(shí)寫(xiě)入輸出流。 keyword 應當指定標頭關(guān)鍵字,并以 value 指定其值。 請注意,在 send_header 調用結束之后,必須調用end_headers()
以便完成操作。在 3.2 版更改: 標頭將被存入內部緩沖區。
- send_response_only(code, message=None)?
只發(fā)送響應標頭,用于當
100 Continue
響應被服務(wù)器發(fā)送給客戶(hù)端的場(chǎng)合。 標頭不會(huì )被緩沖而是直接發(fā)送到輸出流。 如果未指定 message,則會(huì )發(fā)送與響應 code 相對應的 HTTP 消息。3.2 新版功能.
- end_headers()?
將一個(gè)空行(指明響應中 HTTP 標頭的結束)添加到標頭緩沖區并調用
flush_headers()
。在 3.2 版更改: 已緩沖的標頭會(huì )被寫(xiě)入到輸出流。
- flush_headers()?
最終將標頭發(fā)送到輸出流并清空內部標頭緩沖區。
3.3 新版功能.
- log_request(code='-', size='-')?
記錄一次被接受(成功)的請求。 code 應當指定與請求相關(guān)聯(lián)的 HTTP 代碼。 如果請求的大小可用,則它應當作為 size 形參傳入。
- log_error(...)?
當請求無(wú)法完成時(shí)記錄一次錯誤。 默認情況下,它會(huì )將消息傳給
log_message()
,因此它接受同樣的參數 (format 和一些額外的值)。
- log_message(format, ...)?
將任意一條消息記錄到
sys.stderr
。 此方法通常會(huì )被重載以創(chuàng )建自定義的錯誤日志記錄機制。 format 參數是標準 printf 風(fēng)格的格式字符串,其中會(huì )將傳給log_message()
的額外參數用作格式化操作的輸入。 每條消息日志記錄的開(kāi)頭都會(huì )加上客戶(hù)端 IP 地址和當前日期時(shí)間。
- version_string()?
返回服務(wù)器軟件的版本字符串。 該值為
server_version
與sys_version
屬性的組合。
- date_time_string(timestamp=None)?
返回由 timestamp 所給定的日期和時(shí)間(參數應為
None
或為time.time()
所返回的格式),格式化為一個(gè)消息標頭。 如果省略 timestamp,則會(huì )使用當前日期和時(shí)間。結果看起來(lái)像
'Sun, 06 Nov 1994 08:49:37 GMT'
。
- log_date_time_string()?
返回當前的日期和時(shí)間,為日志格式化
- address_string()?
返回客戶(hù)端的地址
在 3.3 版更改: 在之前版本中,會(huì )執行一次名稱(chēng)查找。 為了避免名稱(chēng)解析的時(shí)延,現在將總是返回 IP 地址。
- class http.server.SimpleHTTPRequestHandler(request, client_address, server, directory=None)?
這個(gè)類(lèi)會(huì )為目錄 directory 及以下的文件提供發(fā)布服務(wù),或者如果未提供 directory 則為當前目錄,直接將目錄結構映射到 HTTP 請求。
3.7 新版功能: directory 形參。
在 3.9 版更改: directory 形參接受一個(gè) path-like object。
諸如解析請求之類(lèi)的大量工作都是由基類(lèi)
BaseHTTPRequestHandler
完成的。本類(lèi)實(shí)現了do_GET()
和do_HEAD()
函數。以下是
SimpleHTTPRequestHandler
的類(lèi)屬性。- server_version?
這會(huì )是
"SimpleHTTP/" + __version__
,其中__version__
定義于模塊級別。
- extensions_map?
將后綴映射為 MIME 類(lèi)型的字典,其中包含了覆蓋系統默認值的自定義映射關(guān)系。不區分大小寫(xiě),因此字典鍵只應為小寫(xiě)值。
在 3.9 版更改: 此字典不再填充默認的系統映射,而只包含覆蓋值。
SimpleHTTPRequestHandler
類(lèi)定義了以下方法:- do_HEAD()?
本方法為
'HEAD'
請求提供服務(wù):它將發(fā)送等同于GET
請求的頭文件。關(guān)于合法頭部信息的更完整解釋?zhuān)垍㈤?do_GET()
方法。
- do_GET()?
通過(guò)將請求解釋為相對于當前工作目錄的路徑,將請求映射到某個(gè)本地文件。
如果請求被映射到目錄,則會(huì )依次檢查該目錄是否存在
index.html
或index.htm
文件。若存在則返回文件內容;否則會(huì )調用list_directory()
方法生成目錄列表。本方法將利用os.listdir()
掃描目錄,如果listdir()
失敗,則返回404
出錯應答。如果請求被映射到文件,則會(huì )打開(kāi)該文件。 打開(kāi)文件時(shí)的任何
OSError
異常都會(huì )被映射為404
,'File not found'
錯誤。 如果請求中帶有'If-Modified-Since'
標頭,而在此時(shí)間點(diǎn)之后文件未作修改,則會(huì )發(fā)送304
,'Not Modified'
的響應。 否則會(huì )調用guess_type()
方法猜測內容的類(lèi)型,該方法會(huì )反過(guò)來(lái)用到 extensions_map 變量,并返回文件內容。將會(huì )輸出
'Content-type:'
頭部信息,帶上猜出的內容類(lèi)型,然后是'Content-Length:'
頭部信息,帶有文件的大小,以及'Last-Modified:'
頭部信息,帶有文件的修改時(shí)間。后面是一個(gè)空行,標志著(zhù)頭部信息的結束,然后輸出文件的內容。如果文件的 MIME 類(lèi)型以
text/
開(kāi)頭,文件將以文本模式打開(kāi);否則將使用二進(jìn)制模式。用法示例請參閱
http.server
模塊中的test()
函數的實(shí)現。在 3.7 版更改: 為
'If-Modified-Since'
頭部信息提供支持。
SimpleHTTPRequestHandler
類(lèi)的用法可如下所示,以便創(chuàng )建一個(gè)非常簡(jiǎn)單的 Web 服務(wù),為相對于當前目錄的文件提供服務(wù):
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
http.server
can also be invoked directly using the -m
switch of the interpreter. Similar to
the previous example, this serves files relative to the current directory:
python -m http.server
The server listens to port 8000 by default. The default can be overridden by passing the desired port number as an argument:
python -m http.server 9000
By default, the server binds itself to all interfaces. The option -b/--bind
specifies a specific address to which it should bind. Both IPv4 and IPv6
addresses are supported. For example, the following command causes the server
to bind to localhost only:
python -m http.server --bind 127.0.0.1
3.4 新版功能: 引入了 --bind
參數。
3.8 新版功能: 為了支持 IPv6 改進(jìn)了 --bind
參數。
By default, the server uses the current directory. The option -d/--directory
specifies a directory to which it should serve the files. For example,
the following command uses a specific directory:
python -m http.server --directory /tmp/
3.7 新版功能: --directory
argument was introduced.
By default, the server is conformant to HTTP/1.0. The option -p/--protocol
specifies the HTTP version to which the server is conformant. For example, the
following command runs an HTTP/1.1 conformant server:
python -m http.server --protocol HTTP/1.1
3.11 新版功能: --protocol
argument was introduced.
- class http.server.CGIHTTPRequestHandler(request, client_address, server)?
該類(lèi)可為當前及以下目錄中的文件或輸出 CGI 腳本提供服務(wù)。注意,把 HTTP 分層結構映射到本地目錄結構,這與
SimpleHTTPRequestHandler
完全一樣。備注
由
CGIHTTPRequestHandler
類(lèi)運行的 CGI 腳本不能進(jìn)行重定向操作(HTTP 代碼302),因為在執行 CGI 腳本之前會(huì )發(fā)送代碼 200(接下來(lái)就輸出腳本)。這樣狀態(tài)碼就沖突了。然而,如果這個(gè)類(lèi)猜測它是一個(gè) CGI 腳本,那么就會(huì )運行該 CGI 腳本,而不是作為文件提供出去。 只會(huì )識別基于目錄的 CGI —— 另有一種常用的服務(wù)器設置,即標識 CGI 腳本是通過(guò)特殊的擴展名。
如果請求指向
cgi_directories
以下的路徑,do_GET()
和do_HEAD()
函數已作修改,不是給出文件,而是運行 CGI 腳本并輸出結果。CGIHTTPRequestHandler
定義了以下數據成員:- cgi_directories?
默認為
['/cgi-bin', '/htbin']
,視作 CGI 腳本所在目錄。
CGIHTTPRequestHandler
定義了以下方法:- do_POST()?
本方法服務(wù)于
'POST'
請求,僅用于 CGI 腳本。如果試圖向非 CGI 網(wǎng)址發(fā)送 POST 請求,則會(huì )輸出錯誤 501:Can only POST to CGI scripts"。
請注意,為了保證安全性,CGI 腳本將以用戶(hù) nobody 的 UID 運行。CGI 腳本運行錯誤將被轉換為錯誤 403。
通過(guò)在命令行傳入 --cgi
參數,可以啟用 CGIHTTPRequestHandler
:
python -m http.server --cgi