http協議之詳解(點我)
http協議之https(點我)
http協議之libcurl(點我)
一、http協議的特性
http協議是建立在TCP/IP協議之上應用層協議,默認端口為80,8080
http協議的的特點是無狀態,無連接
二、http協議的請求
利用抓包工具httpwatch可以獲取報文
http協議的報文傳輸的是ASCII碼,在TCP/IP協議之上,主要主要分為三部分
請求行、請求頭、請求體
請求行
第一行,包含三個信息:請求方式,url,http協議版本
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
區別:
1、url可見性:
get,參數url可見;
post,url參數不可見
2、數據傳輸上:
get,通過拼接url進行傳遞參數;
post,通過body體傳輸參數
3、緩存性:
get請求是可以緩存的
post請求不可以緩存
4、后退頁面的反應
get請求頁面后退時,不產生影響
post請求頁面后退時,會重新提交請求
5、傳輸數據的大小
get一般傳輸數據大小不超過2k-4k(根據瀏覽器不同,限制不一樣,但相差不大)
post請求傳輸數據的大小根據php.ini 配置文件設定,也可以無限大。
6、安全性
這個也是最不好分析的,原則上post肯定要比get安全,畢竟傳輸參數時url不可見,但也擋不住部分人閑的沒事在那抓包玩。安全性個人覺得是沒多大區別的,防君子不防小人就是這個道理。對傳遞的參數進行加密,其實都一樣。
本質區別:
GET產生一個TCP數據包;POST產生兩個TCP數據包。
對於GET方式的請求,瀏覽器會把http header和data一並發送出去,服務器響應200(返回數據);
而對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。
請求頭
瀏覽器向服務器發送一些狀態數據,標識數據等等
一個信息一行,包括信息名:信息值 按行分隔
User-Agent: firefox//表示發送請求的瀏覽器(請求代理端)是firefox Host: shop.100.com//表示請求的主機域名(基於域名的虛擬主機就是靠這個頭判斷的) Cookie:name=itcast//瀏覽器攜帶的cookie數據。 Content-Type: application/x-www-form-urlencoded Content-Length: 40 Connection: Keep-Alive
注意,請求頭信息,需要使用一個空行結束!
請求主體
請求代理端項服務器端,發送的請求數據!
典型的就是POST形式發送的表單數據!
get請求,沒有請求主體部分!get數據是在請求行中的url上進行傳遞的!
三、http協議的響應
響應包括:響應行、響應頭、響應體
HTTP/1.1 200 0K Date: Tue,19 Nov 2013 03:08:55 GMT Server: Apache/2. 2.22 (Win32) PHP/5.3. 13 X- -Powered -By: PHP/5. 3.13 Content-Length: 16 Content- Type: text/html
響應行
響應行包括:協議版本、狀態碼、狀態消息
典型的:
1xx:消息
2xx:成功
3xx:請求被重定向
4xx:瀏覽器端錯誤
5xx:服務器端錯誤
典型:
500 服務器內部錯誤
404 請求的頁面沒有找到
403 沒有權限
200 請求成功
響應頭
Content-Type: text/html 內容類型,告知瀏覽器接下來發送的響應主體數據是什么格式!
Content-Length: 響應主體數據的長度!
Date: 響應的時間。GMT時間!
響應主體
主要的響應數據,在瀏覽器的主體區域顯示的數據都是相應主體!
注意,每行,包括相應行和響應頭,都需要一個 \r\n結尾
四、持久連接
HTTP 協議采用“請求-應答”模式,當使用普通模式,即非 Keep-Alive 模式時,每個請求/應答客戶和服務器都要新建一個連接,完成之后立即斷開連接(HTTP 協議為無連接的協議);當使用 Keep-Alive 模式(又稱持久連接、連接重用)時,Keep-Alive 功能使客戶端到服務器端的連接持續有效,當出現對服務器的后繼請求時,Keep-Alive 功能避免了建立或者重新建立連接。
在 HTTP 1.0 版本中,並沒有官方的標准來規定 Keep-Alive 如何工作,因此實際上它是被附加到 HTTP 1.0協議上,如果客戶端瀏覽器支持 Keep-Alive ,那么就在HTTP請求頭中添加一個字段 Connection: Keep-Alive,當服務器收到附帶有 Connection: Keep-Alive 的請求時,它也會在響應頭中添加一個同樣的字段來使用 Keep-Alive 。這樣一來,客戶端和服務器之間的HTTP連接就會被保持,不會斷開(超過 Keep-Alive 規定的時間,意外斷電等情況除外),當客戶端發送另外一個請求時,就使用這條已經建立的連接。
在 HTTP 1.1 版本中,默認情況下所有連接都被保持,如果加入 "Connection: close" 才關閉。目前大部分瀏覽器都使用 HTTP 1.1 協議,也就是說默認都會發起 Keep-Alive 的連接請求了,所以是否能完成一個完整的 Keep-Alive 連接就看服務器設置情況。
由於 HTTP 1.0 沒有官方的 Keep-Alive 規范,並且也已經基本被淘汰,以下討論均是針對 HTTP 1.1 標准中的 Keep-Alive 展開的。
注意:
-
HTTP Keep-Alive 簡單說就是保持當前的TCP連接,避免了重新建立連接。
-
HTTP 長連接不可能一直保持,例如
Keep-Alive: timeout=5, max=100
,表示這個TCP通道可以保持5秒,max=100,表示這個長連接最多接收100次請求就斷開。 -
HTTP 是一個無狀態協議,這意味着每個請求都是獨立的,Keep-Alive 沒能改變這個結果。另外,Keep-Alive也不能保證客戶端和服務器之間的連接一定是活躍的,在 HTTP1.1 版本中也如此。唯一能保證的就是當連接被關閉時你能得到一個通知,所以不應該讓程序依賴於 Keep-Alive 的保持連接特性,否則會有意想不到的后果。
-
使用長連接之后,客戶端、服務端怎么知道本次傳輸結束呢?兩部分:1. 判斷傳輸數據是否達到了Content-Length 指示的大小;2. 動態生成的文件沒有 Content-Length ,它是分塊傳輸(chunked),這時候就要根據 chunked 編碼來判斷,chunked 編碼的數據在最后有一個空 chunked 塊,表明本次傳輸數據結束。
五、分塊傳輸
Transfer-Encoding
Transfer-Encoding 是一個用來標示 HTTP 報文傳輸格式的頭部值。盡管這個取值理論上可以有很多,但是當前的 HTTP 規范里實際上只定義了一種傳輸取值——chunked。
如果一個HTTP消息(請求消息或應答消息)的Transfer-Encoding消息頭的值為chunked,那么,消息體由數量未定的塊組成,並以最后一個大小為0的塊為結束。
每一個非空的塊都以該塊包含數據的字節數(字節數以十六進制表示)開始,跟隨一個CRLF (回車及換行),然后是數據本身,最后塊CRLF結束。在一些實現中,塊大小和CRLF之間填充有白空格(0x20)。
最后一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最后一塊不再包含任何數據,但是可以發送可選的尾部,包括消息頭字段。消息最后以CRLF結尾。
HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 25 This is the data in the first chunk 1A and this is the second one 0
六、HTTP Pipelining(HTTP 管線化)
默認情況下 HTTP 協議中每個傳輸層連接只能承載一個 HTTP 請求和響應,瀏覽器會在收到上一個請求的響應之后,再發送下一個請求。在使用持久連接的情況下,某個連接上消息的傳遞類似於請求1 -> 響應1 -> 請求2 -> 響應2 -> 請求3 -> 響應3
。
HTTP Pipelining(管線化)是將多個 HTTP 請求整批提交的技術,在傳送過程中不需等待服務端的回應。使用 HTTP Pipelining 技術之后,某個連接上的消息變成了類似這樣請求1 -> 請求2 -> 請求3 -> 響應1 -> 響應2 -> 響應3
。
注意下面幾點:
- 管線化機制通過持久連接(persistent connection)完成,僅 HTTP/1.1 支持此技術(HTTP/1.0不支持)
- 只有 GET 和 HEAD 請求可以進行管線化,而 POST 則有所限制
- 初次創建連接時不應啟動管線機制,因為對方(服務器)不一定支持 HTTP/1.1 版本的協議
- 管線化不會影響響應到來的順序,如上面的例子所示,響應返回的順序並未改變
- HTTP /1.1 要求服務器端支持管線化,但並不要求服務器端也對響應進行管線化處理,只是要求對於管線化的請求不失敗即可
- 由於上面提到的服務器端問題,開啟管線化很可能並不會帶來大幅度的性能提升,而且很多服務器端和代理程序對管線化的支持並不好,因此現代瀏覽器如 Chrome 和 Firefox 默認並未開啟管線化支持
七、http協議的安全性
跨站請求偽造(CSRF篡改本地信息)
跨站腳本攻擊(XSS,就是在html總嵌入js腳本)
HTTP頭部攻擊
OS命令攻擊
SQL注入攻擊
目錄攻擊
Dos攻擊
Dos攻擊主要是有兩種
1)是集中利用訪問請求,或者攻擊者刻意制造訪問請求,造成資源過載,資源耗盡,服務停止
2)通過攻擊安全漏洞使服務停止
八、會話跟蹤
-
什么是會話?
客戶端打開與服務器的連接發出請求到服務器響應客戶端請求的全過程稱之為會話。
-
什么是會話跟蹤?
會話跟蹤指的是對同一個用戶對服務器的連續的請求和接受響應的監視。
-
為什么需要會話跟蹤?
瀏覽器與服務器之間的通信是通過HTTP協議進行通信的,而HTTP協議是”無狀態”的協議,它不能保存客戶的信息,即一次響應完成之后連接就斷開了,下一次的請求需要重新連接,這樣就需要判斷是否是同一個用戶,所以才有會話跟蹤技術來實現這種要求。
-
會話跟蹤常用的方法:
-
URL 重寫
URL(統一資源定位符)是Web上特定頁面的地址,URL重寫的技術就是在URL結尾添加一個附加數據以標識該會話,把會話ID通過URL的信息傳遞過去,以便在服務器端進行識別不同的用戶。
-
隱藏表單域
將會話ID添加到HTML表單元素中提交到服務器,此表單元素並不在客戶端顯示
-
Cookie
Cookie 是Web 服務器發送給客戶端的一小段信息,客戶端請求時可以讀取該信息發送到服務器端,進而進行用戶的識別。對於客戶端的每次請求,服務器都會將 Cookie 發送到客戶端,在客戶端可以進行保存,以便下次使用。
客戶端可以采用兩種方式來保存這個 Cookie 對象,一種方式是保存在客戶端內存中,稱為臨時 Cookie,瀏覽器關閉后這個 Cookie 對象將消失。另外一種方式是保存在客戶機的磁盤上,稱為永久 Cookie。以后客戶端只要訪問該網站,就會將這個 Cookie 再次發送到服務器上,前提是這個 Cookie 在有效期內,這樣就實現了對客戶的跟蹤。
Cookie 是可以被客戶端禁用的。
-
Session:
每一個用戶都有一個不同的 session,各個用戶之間是不能共享的,是每個用戶所獨享的,在 session 中可以存放信息。
在服務器端會創建一個 session 對象,產生一個 sessionID 來標識這個 session 對象,然后將這個 sessionID 放入到 Cookie 中發送到客戶端,下一次訪問時,sessionID 會發送到服務器,在服務器端進行識別不同的用戶。
Session 的實現依賴於 Cookie,如果 Cookie 被禁用,那么 session 也將失效。
-
九、cookie的傳遞
HTTP 頭中
Cookie: Cookie變量名=cookie值;expire=到期時間;path=作用路徑;domain=作用域