http.server
--- HTTP 服務(wù)器?
源代碼: Lib/http/server.py
這個(gè)模塊定義了用于實(shí)現(xiàn) HTTP 服務(wù)器的類。
警告
不推薦在生產(chǎn)環(huán)境中使用 http.server
。它只實(shí)現(xiàn)了基本的安全檢查功能。
HTTPServer
是 socketserver.TCPServer
的一個(gè)子類。它會(huì)創(chuàng)建和偵聽 HTTP 套接字,并將請求分發(fā)給處理程序。創(chuàng)建和運(yùn)行 HTTP 服務(wù)器的代碼類似如下所示:
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)?
該類基于
TCPServer
類,并在實(shí)例變量server_name
和server_port
中保存 HTTP 服務(wù)器地址。處理程序可通過實(shí)例變量server
訪問 HTTP 服務(wù)器。
- class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)?
該類相似于 HTTPServer ,只是會(huì)利用
ThreadingMixIn
對請求進(jìn)行多線程處理。當(dāng)需要對 Web 瀏覽器預(yù)先打開套接字進(jìn)行處理時(shí),這就很有用,這時(shí)HTTPServer
會(huì)一直等待請求。3.7 新版功能.
實(shí)例化 HTTPServer
和 ThreadingHTTPServer
時(shí),必須給出一個(gè) RequestHandlerClass,本模塊提供了該對象的三種變體:
- class http.server.BaseHTTPRequestHandler(request, client_address, server)?
這個(gè)類用于處理到達(dá)服務(wù)器的 HTTP 請求。 它本身無法響應(yīng)任何實(shí)際的 HTTP 請求;它必須被子類化以處理每個(gè)請求方法(例如 GET 或 POST)。
BaseHTTPRequestHandler
提供了許多供子類使用的類和實(shí)例變量以及方法。這個(gè)處理程序?qū)⒔馕稣埱蠛蜆?biāo)頭,然后調(diào)用特定請求類型對應(yīng)的方法。 方法名稱將根據(jù)請求來構(gòu)造。 例如,對于請求方法
SPAM
,將不帶參數(shù)地調(diào)用do_SPAM()
方法。 所有相關(guān)信息會(huì)被保存在該處理程序的實(shí)際變量中。 子類不需要重載或擴(kuò)展__init__()
方法。BaseHTTPRequestHandler
具有下列實(shí)例變量:- client_address?
包含
(host, port)
形式的指向客戶端地址的元組。
- server?
包含服務(wù)器實(shí)例。
- close_connection?
應(yīng)當(dāng)在
handle_one_request()
返回之前設(shè)定的布爾值,指明是否要期待另一個(gè)請求,還是應(yīng)當(dāng)關(guān)閉連接。
- requestline?
包含 HTTP 請求行的字符串表示。 末尾的 CRLF 會(huì)被去除。 該屬性應(yīng)當(dāng)由
handle_one_request()
來設(shè)定。 如果無有效請求行被處理,則它應(yīng)當(dāng)被設(shè)為空字符串。
- command?
包含具體的命令(請求類型)。 例如
'GET'
。
- path?
包含請求路徑。如果URL的查詢部分存在,
path
會(huì)包含這個(gè)查詢部分。使用 RFC 3986 的術(shù)語來說,在這里,path
包含hier-part
和query
。
- request_version?
包含請求的版本字符串。 例如
'HTTP/1.0'
。
- headers?
存放由
MessageClass
類變量所指定的類的實(shí)例。 該實(shí)例會(huì)解析并管理 HTTP 請求中的標(biāo)頭。http.client
中的parse_headers()
函數(shù)將被用來解析標(biāo)頭并且它需要 HTTP 請求提供一個(gè)有效的 RFC 2822 風(fēng)格的標(biāo)頭。
- rfile?
一個(gè)
io.BufferedIOBase
輸入流,準(zhǔn)備從可選的輸入數(shù)據(jù)的開頭進(jìn)行讀取。
- wfile?
包含用于寫入響應(yīng)并發(fā)回給客戶端的輸出流。 在寫入流時(shí)必須正確遵守 HTTP 協(xié)議以便成功地實(shí)現(xiàn)與 HTTP 客戶端的互操作。
在 3.6 版更改: 這是一個(gè)
io.BufferedIOBase
流。
BaseHTTPRequestHandler
具有下列屬性:- server_version?
指定服務(wù)器軟件版本。 你可能會(huì)想要重載該屬性。 該屬性的格式為多個(gè)以空格分隔的字符串,其中每個(gè)字符串的形式為 name[/version]。 例如
'BaseHTTP/0.2'
。
- sys_version?
包含 Python 系統(tǒng)版本,采用
version_string
方法和server_version
類變量所支持的形式。 例如'Python/1.4'
。
- error_message_format?
指定應(yīng)當(dāng)被
send_error()
方法用來構(gòu)建發(fā)給客戶端的錯(cuò)誤響應(yīng)的格式字符串。 該字符串應(yīng)使用來自responses
的變量根據(jù)傳給send_error()
的狀態(tài)碼來填充默認(rèn)值。
- error_content_type?
指定發(fā)送給客戶端的錯(cuò)誤響應(yīng)的 Content-Type HTTP 標(biāo)頭。 默認(rèn)值為
'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
這樣的類來解析 HTTP 標(biāo)頭。 通常該屬性不會(huì)被重載,其默認(rèn)值為http.client.HTTPMessage
。
- responses?
該屬性包含一個(gè)整數(shù)錯(cuò)誤代碼與由短消息和長消息組成的二元組的映射。 例如,
{code: (shortmessage, longmessage)}
。 shortmessage 通常是作為消息響應(yīng)中的 message 鍵,而 longmessage 則是作為 explain 鍵。 該屬性會(huì)被send_response_only()
和send_error()
方法所使用。
BaseHTTPRequestHandler
實(shí)例具有下列方法:- handle()?
調(diào)用
handle_one_request()
一次(或者如果啟用了永久連接則為多次)來處理傳入的 HTTP 請求。 你應(yīng)該完全不需要重載它;而是要實(shí)現(xiàn)適當(dāng)?shù)?do_*()
方法。
- handle_one_request()?
此方法將解析并將請求分配給適當(dāng)?shù)?
do_*()
方法。 你應(yīng)該完全不需要重載它。
- 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ā)送并記錄回復(fù)給客戶端的完整錯(cuò)誤信息。 數(shù)字形式的 code 指明 HTTP 錯(cuò)誤代碼,可選的 message 為簡短的易于人類閱讀的錯(cuò)誤描述。 explain 參數(shù)可被用于提供更詳細(xì)的錯(cuò)誤信息;它將使用
error_message_format
屬性來進(jìn)行格式化并在一組完整的標(biāo)頭之后作為響應(yīng)體被發(fā)送。responses
屬性存放了 message 和 explain 的默認(rèn)值,它們將在未提供時(shí)被使用;對于未知代碼兩者的默認(rèn)值均為字符串???
。 如果方法為 HEAD 或響應(yīng)代碼是下列值之一則響應(yīng)體將為空:1xx
,204 No Content
,205 Reset Content
,304 Not Modified
。在 3.4 版更改: 錯(cuò)誤響應(yīng)包括一個(gè) Content-Length 標(biāo)頭。 增加了 explain 參數(shù)。
- send_response(code, message=None)?
將一個(gè)響應(yīng)標(biāo)頭添加到標(biāo)頭緩沖區(qū)并記錄被接受的請求。 HTTP 響應(yīng)行會(huì)被寫入到內(nèi)部緩沖區(qū),后面是 Server 和 Date 標(biāo)頭。 這兩個(gè)標(biāo)頭的值將分別通過
version_string()
和date_time_string()
方法獲取。 如果服務(wù)器不打算使用send_header()
方法發(fā)送任何其他標(biāo)頭,則send_response()
后面應(yīng)該跟一個(gè)end_headers()
調(diào)用。在 3.3 版更改: 標(biāo)頭會(huì)被存儲(chǔ)到內(nèi)部緩沖區(qū)并且需要顯式地調(diào)用
end_headers()
。
- send_header(keyword, value)?
將 HTTP 標(biāo)頭添加到內(nèi)部緩沖區(qū),它將在
end_headers()
或flush_headers()
被發(fā)起調(diào)用時(shí)寫入輸出流。 keyword 應(yīng)當(dāng)指定標(biāo)頭關(guān)鍵字,并以 value 指定其值。 請注意,在 send_header 調(diào)用結(jié)束之后,必須調(diào)用end_headers()
以便完成操作。在 3.2 版更改: 標(biāo)頭將被存入內(nèi)部緩沖區(qū)。
- send_response_only(code, message=None)?
只發(fā)送響應(yīng)標(biāo)頭,用于當(dāng)
100 Continue
響應(yīng)被服務(wù)器發(fā)送給客戶端的場合。 標(biāo)頭不會(huì)被緩沖而是直接發(fā)送到輸出流。 如果未指定 message,則會(huì)發(fā)送與響應(yīng) code 相對應(yīng)的 HTTP 消息。3.2 新版功能.
- end_headers()?
將一個(gè)空行(指明響應(yīng)中 HTTP 標(biāo)頭的結(jié)束)添加到標(biāo)頭緩沖區(qū)并調(diào)用
flush_headers()
。在 3.2 版更改: 已緩沖的標(biāo)頭會(huì)被寫入到輸出流。
- flush_headers()?
最終將標(biāo)頭發(fā)送到輸出流并清空內(nèi)部標(biāo)頭緩沖區(qū)。
3.3 新版功能.
- log_request(code='-', size='-')?
記錄一次被接受(成功)的請求。 code 應(yīng)當(dāng)指定與請求相關(guān)聯(lián)的 HTTP 代碼。 如果請求的大小可用,則它應(yīng)當(dāng)作為 size 形參傳入。
- log_error(...)?
當(dāng)請求無法完成時(shí)記錄一次錯(cuò)誤。 默認(rèn)情況下,它會(huì)將消息傳給
log_message()
,因此它接受同樣的參數(shù) (format 和一些額外的值)。
- log_message(format, ...)?
將任意一條消息記錄到
sys.stderr
。 此方法通常會(huì)被重載以創(chuàng)建自定義的錯(cuò)誤日志記錄機(jī)制。 format 參數(shù)是標(biāo)準(zhǔn) printf 風(fēng)格的格式字符串,其中會(huì)將傳給log_message()
的額外參數(shù)用作格式化操作的輸入。 每條消息日志記錄的開頭都會(huì)加上客戶端 IP 地址和當(dāng)前日期時(shí)間。
- version_string()?
返回服務(wù)器軟件的版本字符串。 該值為
server_version
與sys_version
屬性的組合。
- date_time_string(timestamp=None)?
返回由 timestamp 所給定的日期和時(shí)間(參數(shù)應(yīng)為
None
或?yàn)?time.time()
所返回的格式),格式化為一個(gè)消息標(biāo)頭。 如果省略 timestamp,則會(huì)使用當(dāng)前日期和時(shí)間。結(jié)果看起來像
'Sun, 06 Nov 1994 08:49:37 GMT'
。
- log_date_time_string()?
返回當(dāng)前的日期和時(shí)間,為日志格式化
- address_string()?
返回客戶端的地址
在 3.3 版更改: 在之前版本中,會(huì)執(zhí)行一次名稱查找。 為了避免名稱解析的時(shí)延,現(xiàn)在將總是返回 IP 地址。
- class http.server.SimpleHTTPRequestHandler(request, client_address, server, directory=None)?
這個(gè)類會(huì)為目錄 directory 及以下的文件提供發(fā)布服務(wù),或者如果未提供 directory 則為當(dāng)前目錄,直接將目錄結(jié)構(gòu)映射到 HTTP 請求。
3.7 新版功能: directory 形參。
在 3.9 版更改: directory 形參接受一個(gè) path-like object。
諸如解析請求之類的大量工作都是由基類
BaseHTTPRequestHandler
完成的。本類實(shí)現(xiàn)了do_GET()
和do_HEAD()
函數(shù)。以下是
SimpleHTTPRequestHandler
的類屬性。- server_version?
這會(huì)是
"SimpleHTTP/" + __version__
,其中__version__
定義于模塊級別。
- extensions_map?
將后綴映射為 MIME 類型的字典,其中包含了覆蓋系統(tǒng)默認(rèn)值的自定義映射關(guān)系。不區(qū)分大小寫,因此字典鍵只應(yīng)為小寫值。
在 3.9 版更改: 此字典不再填充默認(rèn)的系統(tǒng)映射,而只包含覆蓋值。
SimpleHTTPRequestHandler
類定義了以下方法:- do_GET()?
通過將請求解釋為相對于當(dāng)前工作目錄的路徑,將請求映射到某個(gè)本地文件。
如果請求被映射到目錄,則會(huì)依次檢查該目錄是否存在
index.html
或index.htm
文件。若存在則返回文件內(nèi)容;否則會(huì)調(diào)用list_directory()
方法生成目錄列表。本方法將利用os.listdir()
掃描目錄,如果listdir()
失敗,則返回404
出錯(cuò)應(yīng)答。如果請求被映射到文件,則會(huì)打開該文件。 打開文件時(shí)的任何
OSError
異常都會(huì)被映射為404
,'File not found'
錯(cuò)誤。 如果請求中帶有'If-Modified-Since'
標(biāo)頭,而在此時(shí)間點(diǎn)之后文件未作修改,則會(huì)發(fā)送304
,'Not Modified'
的響應(yīng)。 否則會(huì)調(diào)用guess_type()
方法猜測內(nèi)容的類型,該方法會(huì)反過來用到 extensions_map 變量,并返回文件內(nèi)容。將會(huì)輸出
'Content-type:'
頭部信息,帶上猜出的內(nèi)容類型,然后是'Content-Length:'
頭部信息,帶有文件的大小,以及'Last-Modified:'
頭部信息,帶有文件的修改時(shí)間。后面是一個(gè)空行,標(biāo)志著頭部信息的結(jié)束,然后輸出文件的內(nèi)容。如果文件的 MIME 類型以
text/
開頭,文件將以文本模式打開;否則將使用二進(jìn)制模式。用法示例請參閱
http.server
模塊中的test()
函數(shù)的實(shí)現(xiàn)。在 3.7 版更改: 為
'If-Modified-Since'
頭部信息提供支持。
SimpleHTTPRequestHandler
類的用法可如下所示,以便創(chuàng)建一個(gè)非常簡單的 Web 服務(wù),為相對于當(dāng)前目錄的文件提供服務(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
參數(shù)。
3.8 新版功能: 為了支持 IPv6 改進(jìn)了 --bind
參數(shù)。
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)?
該類可為當(dāng)前及以下目錄中的文件或輸出 CGI 腳本提供服務(wù)。注意,把 HTTP 分層結(jié)構(gòu)映射到本地目錄結(jié)構(gòu),這與
SimpleHTTPRequestHandler
完全一樣。備注
由
CGIHTTPRequestHandler
類運(yùn)行的 CGI 腳本不能進(jìn)行重定向操作(HTTP 代碼302),因?yàn)樵趫?zhí)行 CGI 腳本之前會(huì)發(fā)送代碼 200(接下來就輸出腳本)。這樣狀態(tài)碼就沖突了。然而,如果這個(gè)類猜測它是一個(gè) CGI 腳本,那么就會(huì)運(yùn)行該 CGI 腳本,而不是作為文件提供出去。 只會(huì)識別基于目錄的 CGI —— 另有一種常用的服務(wù)器設(shè)置,即標(biāo)識 CGI 腳本是通過特殊的擴(kuò)展名。
如果請求指向
cgi_directories
以下的路徑,do_GET()
和do_HEAD()
函數(shù)已作修改,不是給出文件,而是運(yùn)行 CGI 腳本并輸出結(jié)果。CGIHTTPRequestHandler
定義了以下數(shù)據(jù)成員:- cgi_directories?
默認(rèn)為
['/cgi-bin', '/htbin']
,視作 CGI 腳本所在目錄。
CGIHTTPRequestHandler
定義了以下方法:- do_POST()?
本方法服務(wù)于
'POST'
請求,僅用于 CGI 腳本。如果試圖向非 CGI 網(wǎng)址發(fā)送 POST 請求,則會(huì)輸出錯(cuò)誤 501:Can only POST to CGI scripts"。
請注意,為了保證安全性,CGI 腳本將以用戶 nobody 的 UID 運(yùn)行。CGI 腳本運(yùn)行錯(cuò)誤將被轉(zhuǎn)換為錯(cuò)誤 403。
通過在命令行傳入 --cgi
參數(shù),可以啟用 CGIHTTPRequestHandler
:
python -m http.server --cgi