引言
http(超文字傳輸通訊協定 (HTTP))是一個基於請求與響應模式的、無狀態的、應用程式層的協議,常基於TCP的串連方式。HTTP協議的主要特點是:
1.支援客戶/伺服器模式。
2.簡單快速:客戶向伺服器請求服務時,只需傳送要求方法和路徑。由於HTTP協議簡單,通訊速度很快。
3.靈活:HTTP允許傳輸任意類型的資料對象。類型由Content-Type加以標記。
4.無串連:即每次串連只處理一個請求,處理完客戶的請求,並收到客戶的應答後,即中斷連線。採用這種方式可以節省傳輸時間。
5.無狀態:無狀態是指協議對於交易處理沒有記憶能力。
http1.0協議預設的是非持久串連, HTTP1.1預設的串連方式為持久串連。
非持久串連:每次伺服器發出一個對象後,相應的TCP串連就被關閉,也就是說每個串連都沒有持續到可用於傳送其他對象。每個TCP串連只用於傳輸一個請求訊息和一個響應訊息。
持久串連:伺服器在發出響應後讓TCP串連繼續開啟著。同一對客戶/伺服器之間的後續請求和響應可以通過這個串連發送。HTTP/1.1的預設模式使用帶流水線的持久串連。
一、HTTP協議詳解之請求
//請求行
POST /reg.jsp HTTP/ (CRLF)
//訊息前序
Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/* (CRLF)
Accept-Language:zh-cn (CRLF)
Accept-Encoding:gzip,deflate (CRLF)
If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)
If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)
User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)
Host:www.guet.edu.cn (CRLF)
Connection:Keep-Alive (CRLF)
(CRLF)
//請求本文
user=jeffrey&pwd=1234
以上是http請求的三部:請求行、訊息前序、請求本文。
請求行以一個方法符號開頭,以空格分開,後面跟著請求的URI和協議的版本,格式如下:
Method Request-URI HTTP-Version CRLF
其中 Method表示要求方法(如POST、GET、PUT、DELETE等);Request-URI是一個統一資源識別項;HTTP-Version表示請求的HTTP協議版本;CRLF表示斷行符號和換行。
二、HTTP協議詳解之響應篇
//狀態行
HTTP/1.1 200 OK (CRLF)
//訊息前序
Cache-Control: private, max-age=30
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Mon, 25 May 2009 03:20:33 GMT
Last-Modified: Mon, 25 May 2009 03:20:03 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/7.0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Mon, 25 May 2009 03:20:02 GMT
Content-Length: 12173
//響應本文
略
HTTP響應也是由三個部分組成,分別是:狀態行、訊息前序、響應本文
狀態行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示伺服器HTTP協議的版本;Status-Code表示伺服器發回的響應狀態碼;Reason-Phrase表示狀態碼的文本描述。
常見狀態碼、狀態原因、說明:
200 OK //用戶端請求成功
400 Bad Request //用戶端請求有語法錯誤,不能被伺服器所理解
401 Unauthorized //請求未經授權,這個狀態碼必須和WWW-Authenticate前序域一起使用
403 Forbidden //伺服器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //伺服器發生不可預期的錯誤
503 Server Unavailable //伺服器當前不能處理用戶端的請求,一段時間後可能恢複正常
三、HTTP協議詳解之訊息前序
HTTP訊息由用戶端到伺服器的請求和伺服器到用戶端的回應群組成。請求訊息和響應訊息都是由開始行(對於請求訊息,開始行就是請求行;對於響應訊息,開始行就是狀態行),訊息前序(可選),空行(只有CRLF的行),訊息本文(可選)組成。
HTTP訊息前序包括普通前序、請求前序、響應前序、實體前序。每一個前序域都是由名字+“:”+空格+值 組成,訊息前序域的名字是大小寫無關的。
1、請求前序
請求前序允許用戶端向伺服器端傳遞請求的附加資訊以及用戶端自身的資訊。
常用的請求前序
Accept請求前序域用於指定用戶端接受哪些類型的資訊。
Accept-Charset請求前序域用於指定用戶端接受的字元集。
Accept-Encoding請求前序域類似於Accept,但是它是用於指定可接受的內容編碼。
Accept-Language請求前序域類似於Accept,但是它是用於指定一種自然語言。
Authorization請求前序域主要用於證明用戶端有權查看某個資源。
Host請求前序域主要用於指定被請求資源的Internet主機和連接埠號碼,它通常從HTTP URL中提取出來的。User-Agent請求前序域允許用戶端將它的作業系統、瀏覽器和其它屬性告訴伺服器。
2、響應前序
響應前序允許伺服器傳遞不能放在狀態行中的附加響應資訊,以及關於伺服器的資訊和對Request-URI所標識的資源進行下一步訪問的資訊。
常用的響應前序
Location響應前序域用於重新導向接受者到一個新的位置。Location響應前序域常用在更換網域名稱的時候。
Server響應前序域包含了伺服器用來處理請求的軟體資訊
3. 實體前序
請求和響應訊息都可以傳送一個實體。
常用的實體前序
Content-Encoding指示已經被應用到實體本文的附加內容的編碼。
Content-Language實體前序域描述了資源所用的自然語言。
Content-Length實體前序域用於指明實體本文的長度,以位元組方式儲存的十進位數字來表示。
Content-Type實體前序域用語指明發送給接收者的實體本文的媒體類型。
Last-Modified實體前序域用於指示資源的最後修改日期和時間。
Expires實體前序域給出響應到期的日期和時間。
四、補充
1、HTTP協議Content Lenth限制漏洞導致拒絕服務的攻擊
使用POST方法時,可以設定ContentLenth來定義需要傳送的資料長度,例如ContentLenth:999999999,在傳送完成前,內 存不會釋放,攻擊者可以利用這個缺陷,連續向WEB伺服器發送垃圾資料直至WEB伺服器記憶體耗盡。這種攻擊方法基本不會留下痕迹。
2、為了提高使用者使用瀏覽器時的效能,現代瀏覽器還支援並發的訪問方式,瀏覽一個網頁時同時建立多個串連,以迅速獲得一個網頁上的多個表徵圖,這樣能更快速完成整個網頁的傳輸。HTTP1.1中提供了這種持續串連的方式,而下一代HTTP協議:HTTP-NG更增加了有關會話控制、豐富的內容協商等方式的支援,來提供更高效率的串連。
五.Java利用HTTP協議實現連網和下載
Url的請求串連(Get方式)
String currentUrl=“http://www.myWeb.com/login.jsp?userName='Devin'&passWord='mypassword'”; //URL ?後面的內容為HTTP請求的本文
URL url = new URL(currentUrl);
HttpURLConnection httpurlconnection = url.openConnection();
//下面的設定對應HTTP請求中的訊息前序
httpurlconnection.setRequestProperty("User-Agent",CommonValues.User_Agent);
httpurlconnection.setRequestProperty("Accept",CommonValues.Accept);
httpurlconnection.setRequestProperty("Accept-Charset",CommonValues.Accept_Charset);
httpurlconnection.setRequestProperty("Accept-Language",CommonValues.Accept_Language);
httpurlconnection.setRequestProperty("Connection",CommonValues.Connection);
httpurlconnection.setRequestProperty("Keep-Alive",CommonValues.Keep_Alive);
httpurlconnection.setConnectTimeout(CommonValues.ConnectionTimeOut);
httpurlconnection.setReadTimeout(CommonValues.ReadTimeOut);
httpurlconnection.connect();
int responsecode = httpurlconnection.getResponseCode();
if(responsecode == HttpURLConnection.HTTP_OK) //對應HTTP響應中狀態行的響應碼
{
//操作請求流,這裡對應HTTP響應中的響應本文
}
if (httpurlconnection != null)
{
httpurlconnection.disconnect();
}
Post方法串連請查看:http://www.cnblogs.com/devinzhang/archive/2012/01/17/2325092.html