Python中的plisttext和HTTP的Content-Type
這段時間本人在學習Android Service相關的內容,臨時需要一個可以提供文件上傳和下載功能的服務器,于是上網查找了一個簡單服務器的python實現代碼,本著溫顧一下HTTP協議的想法,于是深入研究了一下其中的代碼,發現大家對SimpleHTTPRequestsHandler中的self.headers.plisttext.split("=")[1]語句的含義不是很理解,于是自己查閱了一下python源碼定義和相關HTTP協議文檔,理解了這段代碼的含義。
源碼定義
我們先來看一下關于plisttext的源碼定義。
#https://svn.python.org/projects/python/branches/alpha100/Lib/mimetools.py class Message(rfc822.Message): def __init__(self, fp): .... self.typeheader = \ self.getheader('content-type') .... def parsetype(self): str = self.typeheader if str == None: str = 'text/plain' if ';' in str: i = string.index(str, ';') self.plisttext = str[i:] str = str[:i] else: self.plisttext = '' ....
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
從源碼中可以得出,plisttext與HTTP頭部content-type有關,這里我們就要回想一下content-type的有關定義了。
在w3c的文檔給出了content-type的格式定義,我們可以發現,content-type對的值有可選的內容,使用;隔開,所以plisttext的值就是parameter的內容。
Content-Type := type "/" subtype *[";" parameter] type := "application" / "audio" / "image" / "message" / "multipart" / "text" / "video" / x-token x-token :=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
使用原理
知道了plisttext代表的含義,我們再來看一下它在文件上傳過程中的作用吧。我們先來看一下它在處理文件上傳的post請求時的作用吧。
boundary = self.headers.plisttext.split("=")[1] remainbytes = int(self.headers['content-length']) line = self.rfile.readline() remainbytes -= len(line) if not boundary in line: return (False,"Content NOT begin with boundary") line = self.rfile.readline() remainbytes -= len(line) filename = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"',line) if not fn: return (False,"Can't find out file name")
1
2
3
4
5
6
7
8
9
10
11
我們都知道當通過html的form來進行文件提交時,瀏覽器會發送POST請求,并且content-type為multipart/form-data; boundary=----WebKitFormBoundaryqdHXHkzdBEGWWZka,所以,plisttext的值為boundary=----WebKitFormBoundaryqdHXHkzdBEGWWZka。boundary在HTTP的body中會使用到,因為post請求提交了很多類型的數據,所以必須使用boundary進行間隔,也就是所謂的Multipart Content-Type時的body格式。詳細的body的格式在w3c的文檔中有詳細的介紹。
這里貼一張wireShark截獲的tcp包的信息,來幫助大家理解一下這段python代碼的原理。通過form提交一份文件和一個名為other的字符串。
POST / HTTP/1.1 Host: localhost:8080 Connection: keep-alive Content-Length: 269353 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://localhost:8080 User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/43.0.2357.81 Chrome/43.0.2357.81 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqdHXHkzdBEGWWZka Referer: http://localhost:8080/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4 ------WebKitFormBoundaryqdHXHkzdBEGWWZka Content-Disposition: form-data; name="file"; filename="AndroidStudy.png" Content-Type: image/png ..... //圖片內容 ------WebKitFormBoundaryqdHXHkzdBEGWWZka Content-Disposition: form-data; name="other" ddd ------WebKitFormBoundaryqdHXHkzdBEGWWZka--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HTTP Python
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。