http進階
前言:
上一篇博文已經說到了,apache2.4簡單的配置,端口,持久連接,MPM,DSO,路徑下基於來源控制,頁面特性,日誌設置
安全域,虛擬主機等等。
一:URL
URL是互聯中獲取標記資源的方式,URL的組成由URL方案(scheme),服務器地址(ip+port)和資源路徑構成。例如http://www.xxyy.com/bbs/index.index
語法:<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
- scheme:資源的訪問方法,例如http,ftp
- user:password:訪問網站的賬號密碼,一般只用於http協議本身的Basic認
- host:主機地址
- port:端口號,http協議默認使用80
- path:(/)下相對http主頁下的相對資源路徑
- params:參數,url能提供多個參數中間使用&隔開
- query:查詢語句,問號(?)之後調用查詢語句,多個語句使用&隔開
- frag:片斷,類似書簽,能夠標識網絡資源中的具體地址
這裏重點介紹query和frag:
query是簡單的調用查詢語句,在搜索引擎中通常將其鍵值輸出給其引擎,例如:http://www.baidu.com/baidu?&ie=utf-8&word=1
frag類似於書簽的功能,能夠準確標明資源中的片段,例如:http://baike.baidu.com/item/黃蓉?fr=aladdin#2_5
二、協議
http協議是一種無狀態(stateless)協議,自身不能辨認客戶端,無法追蹤訪問者來源。雖然tcp/ip協議在一定程度上輔助http確認客戶端來源,但是在某些特定情況下,比如keepalive的時候,不會第一時間斷開tcp連接能夠在未達到訪問限制之前的無限請求資源,這種情況下tcp/ip協議並不能發揮作用。
如果這時候刷新一下頁面,購物車裏的物體全部消失(這樣的世界真美好),連買買買的自由都沒有,何談用戶體驗。
所以嘛,需要一種機制能夠準確的追蹤客戶端來源,標識客戶端,此方式表示cookie機制。
當客戶端第一次訪問某站點時,站點響應客戶端資源,同時會發送一串唯一的隨即數據,也就是cookie,以便標記客戶端。cookie會記錄客戶端所有的訪問行為,且有著屬於自己的的作用範圍,換言之,只要訪問同一站點,皆會被服務器辨識。
不過,由於所有的訪問行為都由cookie記錄,同時也就註定自身安全性不足。
任何人,只要能夠獲取到某用戶的cookie,便能完全訪問過去該用戶所進行的所有資源。
顯然,存在缺陷的cookie,並不能讓用戶完全的放心使用。這就需要另一種全新的機制,即輕cookie+session
輕cookie同樣保存用戶信息,但卻不記錄用戶的訪問行為,訪問行為由服務器通過session機制進行保存。(session保存著客戶端的精簡數據結構)
當用戶第一次訪問站點時,站點同樣是響應資源和發送cookie,只是此後所有的訪問行為都是存儲在服務器的RAM中,每次訪問都會跟新其值。
服務器通過cookie和session二者結合的數據結構便能辨別客戶端。
當然,這僅僅只是精簡的說明。
三、事務:
http事務:
請求:request
響應:response
報文語法:
request:
<method><request:URL><version>
<headers>
<request>
response:
<version><status><reason-phrase>
<headers>
<entity-body>
method:請求方法:標明客戶端希望服務器對資源執行的操作
GET:從服務器上獲取資源
HEAD:只從服務器上獲取響應首部
POST:向服務器發送要處理的數據
PUT:將請求的主體部分存儲在服務器上
DELETE:刪除服務器上的文檔
TRACE:追蹤請求到服務器過程中經過的代理服務器
OPTIONS:請求服務器放回對指定資源使用的請求方法
這裏主要討論POST和PUT區別,POST方法作用於一個資源集(bbs/)上,PUT方法作用於一個具體資源(bbs/index.html)上,換句話說POST相當於創建一個資源會生成全新的URL,且每次使用POST都是創建全新資源,(通常而言,服務器不允許過多的創建文件),而PUT相當於更新資源,即無論操作多少次都不會出現不同URL,且PUT方法本身是冪等的。
version:HTTP的版本號
status:狀態碼,如201,304,403
常見狀態碼:
200:成功,請求的所有數據通過響應報文的entity-body發送;ok
301:請求的URL指向的資源已經被刪除,但響應報文通過首部Location指向現在的新位置;Moved Permanently
302:與301相似,但在響應報文中透過首部Location指明資源臨時新位置;Found
304:客戶端發起條件式請求,但服務器端資源沒有發生改變,則通過響應此狀態碼回應客戶端;Not Modifed
401:需要輸入賬號密碼才能訪問;Unauthorized
403:請求被拒絕;Forbidden
404:服務器無法找到客戶端請求的資源;Not Found
505:服務器內部錯誤;internal Server Error
502:代理服務器從後端服務器收到了一條偽響應;bad Gateway
reason-phrase:
狀態碼的簡易描述
headers:
每個請求或響應報文可包含任意首部;每個首部都有首部名稱,後面跟一個冒號,而後跟上一個空格,接著一個值
格式:
Name: value
首部分類:
通用首部
請求首部
響應首部
實體首部
擴展首部
通用首部:
Date:報文響應日期
connecttion:連接方式,如keepalive
Via:顯示報文經過的中間節點
cache-Control:緩存控制
pragma:HTTP1.0緩存
請求首部:
Accept:告訴服務器端自己可接受的的MIME類型
Accept-Charset 可接受的字符集
Accept-Encoding 可接受的編碼格式,如gzip
Accept-Language 可接受的語言
Host:請求服務器的名稱和端口號
Referer:告訴服務器自己是從哪個頁面跳轉過來的
User-Agent:客戶端代理
條件是請求首部:
Expect:希望服務器發送的
If-Modifed-since:自從某個時間點後資源是否有發生變化
If-Unmodifed-since:自從某個時間點後資源是否沒有發生變化
If-None-Match:本地緩存中的文檔的ETag標簽是否與服務器端ETag的不匹配
if-Match:本地緩存中的文檔的ETag標簽是否與服務器端ETag的匹配
安全請求首部:
Authorization:向服務器提供認證信息,如帳號密碼
cookie:向服務器端發送cookie
代理請求首部:
Proxy-Authorization:相代理服務器認證
響應首部:
Age:響應持續時長
Server:服務器程序名稱和版本
協商響應首部:
Accept-Ranges:服務器可接受的請求範圍
Vary:服務器查看的其他首部列表(之中包含都是可變化的值)
安全響應首部:
Set-Cookie:向客戶端設置cookie
www-Authenticate 服務器端對客戶端的咨詢認證表單
實體首部:
Allow:列出對資源可請求的方法
Location:告訴客戶端真正實體位於何處
Content-Ecoding:主體編碼格式
Content-Language:主體語言
Content-Lengh:主體長度
Content-Location:主體真正所在位置
Content-type:主體類型
緩存相關:
ETag:實體擴展的標簽
Expires:實體過期的時間
Last-Modifed:主體最後一次修改的時間
這裏主要討論Vary、Location、Content-Location的區別,放入Vary的首部信息的內容皆是不確定的可變化的值,當需要獲取一個不確定值時,便可將其放入。
比如Vary:Accept-Ecoding能夠使得服務器端獲取各式各樣的編碼格式。
如此在緩存服務器下,不同資源便是采取不同的緩存編碼,css,jpg的靜態資源啟動gzip;php則不采取緩存。
再比如,Vary:User-agent能夠使得緩存服務器根據不同的瀏覽器類型緩存不同的內容。
Location和Content-Location皆是指明主體資源真正的所在位置,前者指的是重定向的地址,後者指的時能夠直接訪問資源的地址,不需要進一步內容協商。
entity-body:
文檔主體,使用PUT和POST方法才有主體,一般而言使用GET方法沒有主體信息
一次完整http事務由http請求和http響應構成,請求報文和響應報文包含大量的headers來描述資源之間的交換。通過了解首部信息,能夠判斷資源是否能夠完成的基本標準。
更重要的是,能夠通過首部進行負載均衡。
四、https
http是明文協議,註定了信息的不安全性。
https協議便是http的通信加密方式。
https協議先進行tcp/443三次握手,之後進行ssl回話握手,隨後再進行http協議。http和http除卻tcp連接之外,還多進行了一次ssl握手,進行ssl握手之後所有進出的信息皆會被加密。
ssl位於傳輸層和應用層之間的半層,所以進行傳輸前必須要後tcp建立ssl連接,先tcp斷開ssl連接。
註:https進行加密傳輸,必定會有額外消耗,在高負載的情況下會給CPU極大的壓力,所以一般需要能夠緩存ssl回話的硬件緩存,以便減少服務器壓力。
以下是SSL簡易會話過程:
(1)客戶端發送可供選擇的加密方法發送給服務器端
(2)服務器端發送證書及選定的加密方法給客戶端
(3)驗證證書:
如果信任發證書的CA:
(a)驗證證書來源合法性,用CA的公鑰解密證書上數字簽名
(b)驗證證書的內容合法性,完整性驗證
(c)檢查證書的有效期限
(d)檢查證書是否被吊銷
(e)證書中擁有者的姓名,與訪問的目標主機要一致
(4)客戶端生成臨時會話密鑰(對稱密鑰),並使用服務器端側的公鑰加密發送給服務器端,完成密鑰交換
(5)服務器用此密鑰加密用戶請求的資源,響應給客戶端
註:ssl是基於IP地址創建的,所以單IP主機上,僅可以使用一個https虛擬主機(一般而言)
以下,內部網絡的私有CA建立過程及ssl回話過程。
#cd /etc/pki/CA #建立私有CA,在另一條主機上完成 #(umask 077;openssl genrsa -out private/cakey.pem 2048) #密鑰 #touch index.txt #echo 01> serial
#openssl req -new x509 -key private/cakey.pem -out cacert.pem -days 7200 #私有證書
#cd /etc/httpd/ #客戶端 #mkdir ssl #cd ssl #(umask 077;openssl genrsa -out httpd.key 1024) #生成密鑰 #openssl req -new -key httpd.key -out httpd.csr -days 3600 #證書簽署請求 #scp httpd.csr [email protected]:/tmp #發送給服務器
#openssl ca -in /tmp/httpd.csr -out certs/httpd.crt -days 3600 #CA服務器簽署證書 #ls certs/ #scp certs/httpd.crt [email protected]:/etc/httpd/ssl/ #發還給客戶端
#yum -y install mod_ssl #客戶端 #cd /etc/httpd/conf.d #cp ssl.conf{,.bak} #vim ssl.conf DocumentRoot “/vhosts/web2htdocs” ServerName web1.xxyy.com SSLCertificateFile /etc/httpd/ssl/httpd.crt #證書文件,簽署過的證書 SSLCertificateKeyFile /etc/httpd/ssl/httpd.key #密鑰
<VirtualHost *:80> #在虛擬主機設置中打開SSL引擎 SSLengine on SSLCertificateFile /etc/httpd/ssl/httpd.crt SSLCertificateKeyFile /etc/httpd/ssl/httpd.key
以上,便是SSL的簡易配置。
http進階