用Python實現簡單的HTTP服務器(1)--使用Firebug簡單分析HTTP協議

HTTP協議是超文本傳輸協議, 天天瀏覽網頁, 看新聞都在接觸HTTP, 能夠在地址欄看到最前面大可能是http.javascript

HTTP協議, 實質上就是使用了網絡編程, 使用TCP/IP鏈接, 來傳輸文本和圖片等數據, 再經過瀏覽器進行解析和顯示的.html

(圖來自參考1)java

上述的圖片就能夠幫咱們理解http協議的過程, 上述的結構是一個典型的BS模型.python

首先, 瀏覽器發送http請求, 服務器接收請求後進行處理, 以後返回一個http響應. 瀏覽器接收到響應以後, 會對響應進行處理, 其中的html會被解析和渲染成爲咱們平時看到的網頁.編程

分析http協議瀏覽器

分析http協議有不少方法, 我這裏使用火狐插件Firebug. 這個插件被普遍地用於網頁調試, 功能強大, 使用簡便, 網頁開發利器之一.緩存

Firebug的安裝服務器

方法有兩種: (前提是你先安裝了火狐)網絡

1.在火狐左上角的菜單中單擊附加組件, 在右上角的搜索框中輸入firebug, 回車便可搜索到.app

2.也能夠在Firefox中打開http://getfirebug.com/這個網頁, 上面有個Install Firebug的按鈕.

HTTP headers

咱們先打開firebug, 在地址欄中輸入百度的主頁(注意: 必須先打開firebug, 不然firebug捕獲不到數據).

你會看到一個firebug面板, 選擇其中的網絡面板(初次安裝, 可能須要先啓用), 以下圖.

咱們能夠看到, 這裏的百度主頁有多個請求, 第一個是主頁html代碼的請求, 剩下的都是在html解析中發出的新請求, 好比說加載js, 加載圖片等. 你能夠在這個面板中試試, 操做仍是很簡單的.

點開第一項: GET www.baidu.com. 咱們能夠看到頭信息響應緩存HTML等選項.

對應最開始的那個圖, 這裏麪包含了咱們在前面說過的, HTTP headers頭信息, 包含了請求頭信息和響應頭信息.

使用Firebug工具, 得到這些頭信息, 咱們就能夠大概理解HTTP協議的工做流程了.

獲取百度頁面, 首先是發送請求, 這個請求是瀏覽器幫咱們發出的, 咱們只負責了一個網址的輸入. 瀏覽器自動發送一個請求頭信息(有刪減).

複製代碼
GET / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Connection: keep-aliveCache-Control: max-age=0
複製代碼
 
第一行:GET / HTTP/1.1 分爲三個部分, GET是說明使用的HTTP方法, 經常使用的HTTP方法有GET和POST, 表示拿取一個資源
後面是/, 這個表示拿取根目錄的資源, 默認是index.html或default.html等, 根據各服務器的配置不一樣而不一樣, 反正就是要拿到默認的頁面.
HTTP/1.1表示了HTTP的版本, 通常是固定不變的.
後面的都是Key-Value的形式, Host代表了請求的主機域名或ip, 經過host和第一行的信息, 就能夠知道地址欄中請求的資源, 這個例子請求的是http://www.baidu.com/主頁.
若是是http://www.baidu.com/logo.png(注:示例連接不可用), 那麼這個頭信息確定會包含這樣的內容.
 
GET /logo.png HTTP/1.1
Host: www.baidu.com
 

在這個例子中, 整個響應以下:

複製代碼
HTTP/1.1 200 OKDate: Sat, 31 Dec 2011 08:23:40 GMT
Server: BWS/1.0
Content-Length: 3350
Content-Type: text/html;charset=gb2312Cache-Control: private
Expires: Sat, 31 Dec 2011 08:23:40 GMT
Content-Encoding: gzip
Connection: Keep-Alive

<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html;charset=gb2312"><title>百度一下,你就知道 
(省略...) 
</html> <script type="text/javascript" src="http://www.baidu.com/cache/hps/js/hps-1.4.js"></script> <!--ade6dd8ede8ff3ea-->
複製代碼
 
 
 最前面的就是響應頭信息, 後面空一行, 跟着就是html代碼, 通過渲染後就是咱們看到的網頁.
 響應頭信息主要說下第一行: HTTP/1.1 200 OK , 也是三個部分, 第一個和以前同樣, 是個HTTP版本信息, 後面200叫作狀態碼, 根據這個能夠知道相應的狀態(具體看參考2), 主要是如下幾個大類:
1xx:信息,請求收到,繼續處理
2xx:成功,行爲被成功地接受、理解和採納
3xx:重定向,爲了完成請求,必須進一步執行的動做
4xx:客戶端錯誤,請求包含語法錯誤或者請求沒法實現
5xx:服務器錯誤,服務器不能實現一種明顯無效的請求
一個最簡單的HTTP服務器 一個HelloWorld的http服務器做爲第一個服務器, 這個服務器不處理請求頭信息, 只是返回一個固定的內容, 能夠在頁面顯示HelloWorld.
?
# -.- coding:utf-8 -.-
'''
Created on 2011-11-19
 
@author : icejoywoo
'''
import  socket
import  datetime
# 初始化socket
s =  socket.socket()
# 獲取主機名, 也可使用localhost
#host = socket.gethostname()
host =  "localhost"
# 默認的http協議端口號
port =  80
 
# 綁定服務器socket的ip和端口號
s.bind((host, port))
 
# 服務器名字/版本號
server_name =  "MyServerDemo/0.1"
 
# 緩存時間, 緩存一天
expires =  datetime.timedelta(days = 1 )
# GMT時間格式
GMT_FORMAT =  '%a, %d %b %Y %H:%M:%S GMT'
# 相應網頁的內容
content =  '''
<html>
<head><title>MyServerDemo/0.1</title></head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
'''
 
# 可同時鏈接五個客戶端
s.listen( 5 )
 
# 提示信息
print  "You can see a HelloWorld from this server in ur browser, type in" , host, "\r\n"
 
# 服務器循環
while  True :
     # 等待客戶端鏈接
     c, addr =  s.accept()
     print  "Got connection from" , addr, "\r\n"
     
     # 顯示請求信息
     print  "--Request Header:"
     # 接收瀏覽器的請求, 不做處理
     data =  c.recv( 1024 )
     print  data
     
     # 得到請求的時間
     now =  datetime.datetime.utcnow()
 
     # 相應頭文件和內容
     response =  '''HTTP/1.1 200 OK
Server: %s
Date: %s
Expires: %s
Content-Type: text/html;charset=utf8
Content-Length: %s
Connection: keep-alive
 
%s'''  %  (
server_name,
now.strftime(GMT_FORMAT),
(now +  expires).strftime(GMT_FORMAT),
len (content),
content
)
     # 發送迴應
     c.send(response)
     print  "--Response:\r\n" , response
     c.close()
相關文章
相關標籤/搜索