從零開始學寫HTTP伺服器(一)http協議簡介

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

HTTP協議簡介

unp兩本已經看完一陣時間,對網路程式設計有了一定的瞭解,於是想開始試著寫一個簡單的HTTP伺服器。

http是應用層協議建立在傳輸層之上,因此,我想實現的http伺服器,應該起碼是一個TCP server,而在UNP中,所有示例幾乎都是簡單的echo服務,如何實現HTTP服務,首先就要了解在客戶端和服務端建立起連線之後通訊的內容。

http的預設埠是80,而一些伺服器例如tomcat常用8080作為預設埠。

客戶端通過傳送請求向服務端請求資源,服務端收到客戶請求之後,對其內容進行解析並向客戶端回送一個響應,這就是一個http協議用於客戶端和伺服器端通訊的一般過程。

(一)http請求

HTTP定義了與伺服器互動的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE。URL全稱是資源描述符,我們可以這樣認為:一個URL地址,它用於描述一個網路上的資源,而 HTTP 中的GET,POST,PUT,DELETE就對應著對這個資源的查,改,增,刪4個操作。

GET用於資訊獲取,而且應該是安全的 和 冪等的。

所謂安全的意味著該操作用於獲取資訊而非修改資訊。換句話說,GET 請求一般不應產生副作用。就是說,它僅僅是獲取資源資訊,就像資料庫查詢一樣,不會修改,增加資料,不會影響資源的狀態。

冪等的意味著對同一URL的多個請求應該返回同樣的結果。

GET請求報文示例:

GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

POST表示可能修改變伺服器上的資源的請求。

 POST / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
sex=man&name=Professional  

注意:
GET可提交的資料量受到URL長度的限制,HTTP協議規範沒有對URL長度進行限制。這個限制是特定的瀏覽器及伺服器對它的限制。理論上講,POST是沒有大小限制的,HTTP協議規範也沒有進行大小限制,出於安全考慮,伺服器軟體在實現時會做一定限制。參考上面的報文示例,可以發現GET和POST資料內容是一模一樣的,只是位置不同,一個在URL裡,一個在HTTP包的包體裡

對於一個http請求來說,一般由如下部分組成:

1.請求行
2.HTTP首部欄位
3.\r\n (CR LF)
4.報文主體

(二)http響應

HTTP 響應與 HTTP 請求相似,HTTP響應也由3個部分構成,分別是:

狀態行
響應頭(Response Header)
響應正文
狀態行由協議版本、數字形式的狀態程式碼、及相應的狀態描述,各元素之間以空格分隔。

常見的狀態碼有如下幾種:

200 OK 客戶端請求成功
301 Moved Permanently 請求永久重定向
302 Moved Temporarily 請求臨時重定向
304 Not Modified 檔案未修改,可以直接使用快取的檔案。
400 Bad Request 由於客戶端請求有語法錯誤,不能被伺服器所理解。
401 Unauthorized 請求未經授權。這個狀態程式碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden 伺服器收到請求,但是拒絕提供服務。伺服器通常會在響應正文中給出不提供服務的原因
404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
500 Internal Server Error 伺服器發生不可預期的錯誤,導致無法完成客戶端的請求。
503 Service Unavailable 伺服器當前不能夠處理客戶端的請求,在一段時間之後,伺服器可能會恢復正常。

下面是一個HTTP響應的例子:

< HTTP/1.1 200 OK
< Server: bfe/1.0.8.18
< Date: Sun, 11 Dec 2016 10:51:49 GMT
< Content-Type: text/html
< Content-Length: 2381
< Last-Modified: Mon, 25 Jul 2016 11:11:39 GMT
< Connection: Keep-Alive
< ETag: "5795f3eb-94d"
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Pragma: no-cache
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
< Accept-Ranges: bytes
<!DOCTYPE html>...

(三) HTTP首部欄位

首部欄位根據用途被分為:
通用首部欄位:請求和響應報文都會用到。
請求首部欄位:客戶端向服務端傳送請求報文時使用的首部。
響應首部欄位:從服務端向客戶端返回響應時使用的首部。
實體首部欄位:針對請求報文和響應報文的實體部分使用的首部。

3.1 Content-Type欄位

伺服器迴應的時候,必須告訴客戶端,資料是什麼格式,這就是Content-Type欄位的作用。

text/plain
text/html
text/css
image/jpeg
image/png
image/svg xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom xml

這些資料型別總稱為MIME type,每個值包括一級型別和二級型別,之間用斜槓分隔。
除了預定義的型別,廠商也可以自定義型別。

application/vnd.debian.binary-package

上面的型別表明,傳送的是Debian系統的二進位制資料包。
MIME type還可以在尾部使用分號,新增引數。

Content-Type: text/html; charset=utf-8

上面的型別表明,傳送的是網頁,而且編碼是UTF-8。
客戶端請求的時候,可以使用Accept欄位宣告自己可以接受哪些資料格式。

Accept: */*

上面程式碼中,客戶端宣告自己可以接受任何格式的資料。

3.2 Connection欄位

該欄位一般兩個值keep-aliveclose
HTTP是無狀態的 。
也就是說,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束就中斷連線。如果客戶端瀏覽器訪問的某個HTML或其他型別的Web頁中包含有其他的Web資源,如JavaScript檔案、影象檔案、CSS檔案等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話
HTTP1.1和HTTP1.0相比較而言,最大的區別就是增加了持久連線支援(貌似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態的,或者說是不可以信任的。
如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼

Connection:keep-alive

TCP連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了頻寬。

(四) 總結

本文學習了http協議的基本概念,這是編寫http server的基礎,尤其是http報文頭部的內容,是服務端解析請求並回送響應的基礎。

(五) 參考

1.圖解HTTP
2.http://www.ruanyifeng.com/blog/2016/08/http.html
3.https://hit-alibaba.github.io/interview/basic/network/HTTP.html#響應報文

相關文章

程式語言 最新文章