gzip源碼
『壹』 寫C++程序的時候,怎麼編寫可以讀取gzip壓縮的文件請具體回答,最好有具體源代碼。
下載並使用libz和libz2的api,就可以讀取gzip文件。http://blog.csdn.net/yui/article/details/5707842
『貳』 怎麼讓頁面自動解析Gzip字元串
java過濾器實現Gzip壓縮實例源碼教程。Gzip是若干種文件壓縮程序的簡稱,我們這里來實現通過javaee中的filter實現對響應數據的壓縮,高效的傳到客戶端,那麼是怎麼通過Gzip壓縮實現的將數據壓縮後客戶端的,對步驟進行分析:
1.我們把客戶端要對用戶響應的數據先放在緩存中,
2.然後,通過Gzip將緩存中的數據壓縮,
3.在過濾器中通過response的寫方法,將數據響應到客戶端。
為了模擬:
首先寫一個請求的servlet:
package com.zsq.gzip;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(「text/html;charset=utf-8″);
String s=」」 +
「」 +
「」 +
「不是吧」;
//response.getOutputStream().write(s.getBytes(「utf-8″));
response.getWriter().write(s);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是一個過濾器:
package com.zsq.gzip;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipFilter implements Filter{
public void destroy() {
System.out.println(「壓縮過濾開始了」);
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) www.hbbz08.com throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)res;
MyResponse mresponse=new MyResponse(response);
chain.doFilter(request, mresponse);
byte[] b=mresponse.getBytes();
System.out.println(「壓縮前:」+b.length);
ByteArrayOutputStream out=new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream=new GZIPOutputStream(out);
gzipOutputStream.write(b);
gzipOutputStream.close();//將數據刷出,如果沒有則不顯示
byte[]bu=out.toByteArray();
System.out.println(「壓縮後:」+bu.length);
response.setHeader(「Content-Encoding」,」gzip」);
response.getOutputStream().write(bu);
}
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(「壓縮過濾結束了。」);
}
}
其中有一個自定義類MyResponse,這個類是對Response的增強類,具體增強的是getOutputStream()和getWriter()這兩個方法,通過對這兩個方法將數據寫到ByteArrayOutputStream中,而不是列印到頁面,然後向外提供一個介面得到這個ByteArrayOutputStream對象,通過Gzip壓縮,然後響應到客戶端;該類的代碼:
package com.zsq.gzip;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream bytes=new ByteArrayOutputStream();//用bytes保存數據
private HttpServletResponse response;
private PrintWriter pw;
public MyResponse(HttpServletResponse response) {
super(response);
// TODO Auto-generated constructor stub
this.response=response;
}
@Override
public ServletOutputStream getOutputStream(){
return new MyServletOutputStream(bytes);//調用自定義類將數據寫到bytes中
}
@Override
public PrintWriter getWriter(){
try {
pw=new PrintWriter(new OutputStreamWriter(bytes,」utf-8″));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return pw;
}
public byte[] getBytes(){//向外提供一個介面得到bytes數據。
if(pw!=null){
pw.close();
return bytes.toByteArray();
}
if(bytes!=null){
try {
bytes.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
return bytes.toByteArray();
}
『叄』 如何利用gzip壓縮網頁來提升網站瀏覽速度
純Tomcat 伺服器
如果您的 WEB 應用程序是跑在 Tomcat
伺服器下的,而且直接使用 Tomcat 所提供的 HTTP 服務,那建議你馬上動手,因為實在是太簡單了,你只需要在 server.xml
配置文件中給 HTTP Connector 增加一個 compression 的參數值為 on 並重啟 Tomcat
伺服器就立刻生效,配置如下:
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" compression="on"/>
Tomcat
採用的是 HTTP/1.1 的 GZIP 壓縮協議,它會根據瀏覽器送過來的請求中的 accept-encoding 值是否包含 gzip
來判斷瀏覽器是否支持 gzip 壓縮協議,如果瀏覽器支持就啟用 gzip 壓縮,否則就不進行任何壓縮處理。Tomcat 中還有另外一個參數
compressableMimeType,這個參數可以用來指定壓縮哪種類型的內容,例如可以指定該配置值為:text/html,text
/plain ,則只壓縮 contentType 為 text/html 和 text/plain 的頁面,不過您最好也將 css 和
javascript 文件也算在壓縮的文件類型中,因為這兩者的壓縮效果也十分的明顯。
Apache 伺服器
在
apache 1.3 版本,大家常用 mod_gzip 對輸出內容進行壓縮,現在主流的瀏覽器都支持 gzip 解壓縮。在 apache2
下,這個模塊換名為 mod_deflate,對應的模塊文件名是 mod_deflate.so。mod_gzip 本文不做介紹,下面描述一下在
Apache 2 下如何啟用並配置 mod_deflate 模塊。默認安裝的 Apache 不管是 Windows 還是
linux/Unix,都是不啟用該模塊的, Linux/Unix 下甚至不帶該模塊,你需要手工編譯這個模塊。
下面我們分別介紹在 Windows 和 Linux 操作系統下如何啟用並配置 mod_deflate 模塊。
在 Windows 下採用安裝程序安裝的 Apache 伺服器已經帶有 deflate 所需要的模塊 mod_deflate.so 和 mod_headers.so,我們只需要在 httpd.conf 配置文件中啟用並進行相關的配置即可,配置如下:
LoadMole deflate_mole moles/mod_deflate.so
LoadMole headers_mole moles/mod_headers.so
<Location />
# Insert filter
SetOutputFilter DEFLATE
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>
而
如果是 Linux/Unix 操作系統,如果你沒有在編譯安裝的過程中將所需要的兩個模塊 mod_deflate 和 mod_headers
編譯進去的話,那就稍微有點麻煩,首先我們先看如何在編譯安裝 Apache 過程中也同時編譯這兩個模塊,請在執行 configure
程序時增加兩個參數分別是:
# ./configure --enable-deflate --enable-headers
這樣在編譯完 Apache 後就可以直接在 httpd.conf 中啟用並配置 deflate 模塊了,配置的方法跟 Windows 平台下是相同的。
如
果說您的 Apache 已經在運行了,不想再重新編譯一次,那也可以選擇只編譯 deflate 模塊所需的文件 mod_deflate.c
和mod_headers.c。這兩個文件位於 {apache-src}/moles/filters/ 目錄下(其中 {apache-src}
為 apache 源文件所在的目錄)。使用如下命令來單獨編譯這兩個源文件。
# {apache-bin}/apxs -i -a -c {apache-src}/moles/filters/mod_deflate.c
# {apache-bin}/apxs –i –a –c {apache-src}/moles/filters/mod_headers.c
其中 {apache-bin} 為 Apache 安裝目錄下的 bin 目錄,接下來在 httpd.conf 直接配置該模塊即可。
很多時候你在單獨編譯 deflate 模塊的時候可能會碰到編譯錯誤,提示是:
Cannot load /opt/apache/moles/mod_deflate.so into server: /opt/apache/moles/mod_deflate.so: undefined symbol: deflate
解決的方法如下:
編輯 /usr/local/apache2/bin/apr-config 文件修改其中的 LDFLAGS 值為 "-lz",然後再重新編譯 mod_deflate 模塊,apxs -ica mod_deflate.c 即可。
為了省卻不必要的麻煩,請盡量在編譯安裝時直接加上 --enable-deflate --enable-headers 參數。
IIS 伺服器
微
軟的 IIS 伺服器同樣也是目前用得最多的 WEB 伺服器之一,而且用來運行 ASP 頁面也是必不可少的。IIS6,iis本身支持 gzip
壓縮,IIS5就比較費勁了,你可以找一些第三方的組件來處理,例如 httpzip,接下來我們介紹如何在 IIS6 中啟用壓縮功能。
打開 Internet 信息服務(IIS)管理器,右擊"網站"->"屬性",選擇"服務"。在 "HTTP壓縮" 框中選中 "壓縮應用程序文件" 和 "壓縮靜態文件",按需要設置 "臨時目錄" 和 "臨時目錄的最大限制",
設置網站屬性
接
下來配置 gzip 組件,在 Internet 信息服務(IIS)管理器,點擊 "Web 服務擴展"->"增加一個新的 Web
服務擴展...",在 "新建 Web 服務擴展" 框中輸入擴展名 "HTTP Compression",添加 "要求的文件" 為
C:\WINDOWS\system32\inetsrv\gzip.dll,選中 "設置擴展狀態為允許",如下圖所示:
設置 Web 服務擴展,新建 Web 服務擴展
還沒完呢,我們還需要修改一個配置文件,修改之前請先停止 IIS 服務,打開 C:\Windows\System32\inetsrv\MetaBase.xml,這個文件很大,找到下面一段信息:
<IIsCompressionScheme Location ="/LM/W3SVC/Filters/Compression/gzip"
HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
HcCreateFlags="1"
HcDoDynamicCompression="TRUE"
HcDoOnDemandCompression="TRUE"
HcDoStaticCompression="TRUE"
HcDynamicCompressionLevel="0"
HcFileExtensions="htm
html
txt"
HcOnDemandCompLevel="10"
HcPriority="1"
HcScriptFileExtensions="asp
dll
exe"
>
</IIsCompressionScheme>
增加一些要進行壓縮的文件後綴,其中 HcFileExtensions 是靜態文件的擴展名,增加 js 和 css 等;HcScriptFileExtensions 為動態文件的擴展名,增加 aspx,保存後啟動 IIS 即可生效。
最
後我們介紹如何來測試前面所做的工作是否起效,你可能會覺得很奇怪,配置好了,用瀏覽器打開頁面正常,查看頁面源碼,內容並沒有變化,大小也跟原來一樣,
怎麼回事呢?這是因為瀏覽器已經把內容解壓了的結果,有兩個方法來判斷壓縮是否生效:第一,查看 WEB 伺服器的日誌,不管是 Apache 或者是
IIS,二者的訪問日誌格式都差不多是下面這種格式:
127.0.0.1 - - [14/May/2006:08:44:28 +0800] "GET /manual/style/css/manual.css HTTP/1.1" 200 19351
最
後兩個數字分別是 HTTP 的結果碼(200 表示 OK),19351
表示的是響應內容的大小,把這個大小跟你在瀏覽器上查看源碼的大小比較一下就可以知道是否生效。另外一種方法就是自己寫一個 HTTP
客戶端的小程序並設置 Accept-Encoding 的值為 gzip,deflate,由這個程序去請求伺服器端的某個 URL
地址,然後列印出響應的內容,如果是一堆亂碼,恭喜你,配置成功。下面是一段 Java 寫的測試客戶端代碼(需要用到
commons-httpclient 包):
HttpClient http = new HttpClient();
String url = http://www.softbar.com;
GetMethod get = new GetMethod(url);
try{
System.out.println("fetching url : "+ url);
get.addRequestHeader("accept-encoding", "gzip,deflate");
int er = http.executeMethod(get);
if(er==200){
System.out.println(get.getResponseContentLength());
String html = get.getResponseBodyAsString();
System.out.println(html);
System.out.println(html.getBytes().length);
}
}finally{
get.releaseConnection();
}
結論
以
上是目前比較流行的兩個 WEB 伺服器軟體以及 Tomcat 伺服器對於頁面壓縮的配置方法;其他的一些 J2EE
應用伺服器如果不支持這個功能的話可以考慮利用過濾器(Servlet Filter)來進行處理,具體的代碼以及配置方法可以參考 Resin
伺服器所提供的文檔。但是有一點需要提醒各位讀者的是,本文介紹的訪問只是在伺服器本身的響應速度已經足夠優化的情況下進行,也就是說在帶寬成為系統瓶頸
的時候才來考慮該方案。
『肆』 如何編譯TrueCrypt源碼
TrueCrypt是一款開源的虛擬加密磁碟工具,目前最新版本是7.0a,本文以該版本源代碼為基礎,介紹了如何在VC2008下進行編譯。
環境配置
1. Microsoft Visual Studio 2008 SP1 (VC++ 2008)
2. Microsoft Visual Studio VC++ 1.52
3. NASM version 2.07 compiled on Jul 19 2009
4. gzip 1.2.4 Win32 (02 Dec 97)
5. PKCS11頭文件
6. Windows Driver Develop Kit 7600.16385.1
7. TrueCrypt 7.0a Source.zip
准備步驟
1. Microsoft Visual Studio 2008 SP1 (VC++ 2008) ,這個是必需的了
2. 安裝Microsoft Visual Studio VC++ 1.52,(這里為了方便管理編譯TrueCrypt所需要的lib,我們可以在c盤建立一個目錄,就命名為TrueCrypt)把MSVC++ 1.52安裝在C:\TrueCrypt\MSVC\
3. 下載NASM,解壓縮到C:\TrueCrypt\ NASM\
4. 下載gzip,解壓縮到C:\TrueCrypt\ gzip\
5. 下載PKCS11頭文件,解壓縮到C:\TrueCrypt\PKCS11_INC\
6. 下載WDK7600.16385.1(這個是目前最新的,更新消息參考微軟官網),安裝到E:\WinDDK\7600.16385.1\(這個目錄是我這邊這么設置的,在下面環境變數設置需要注意)
7. 下載TrueCrypt 7.0a源代碼(http://www.truecrypt.org/downloads2)
環境變數設置
右鍵我的電腦——屬性——高級——環境變數,添加下面幾個系統變數:
1. 變數名MSVC16_ROOT,變數值C:\TrueCrypt\MSVC
2. 變數名PKCS11_INC,變數值C:\TrueCrypt\PKCS11_INC
3. 變數名WINDDK_ROOT,變數值E:\WinDDK\7600.16385.1
4. 修改系統Path,在末尾增加C:\TrueCrypt\NASM;C:\TrueCrypt\gzip
環境變數設置完畢後需要重啟電腦
源代碼修改
1. 修改C:\TrueCrypt\PKCS11_INC\ pkcs11.h,添加
#define CKR_NEW_PIN_MODE 0x000001B0
#define CKR_NEXT_OTP 0x000001B1
可以直接添加在#define __PASTE(x,y) x##y後面一行
2. 修改TrueCrypt 7.0a Source其中的Setup項目中的Setup.h文件,添加
/*---region add by gc---*/
#include "wtypes.h"
const PROPERTYKEY PKEY_AppUserModel_ID = {
{
(unsigned long)2009,/*unsigned long Data1;*/
(unsigned short)12,/*unsigned short Data2;*/
(unsigned short)23,/*unsigned short Data3;*/
0x44,0x55,0x55,0x55,0x55,0x55,0x55,0x55
},/*GUID fmtid;*/
(DWORD)PID_FIRST_USABLE /*DWORD pid;*/
};
/*---endregion---*/
添加在文件的開始處,即
#ifdef __cplusplus
extern "C" {
#endif
後面一行即可。
到此為止,所有配置均設置完畢,打開TrueCrypt.sln解決方案,Build Solution就可以在Debug目錄生成Setup Files目錄,其下至少可以看到TrueCrypt.exe,truecrypt.sys,truecrypt-x64.sys這個三個文件了。
『伍』 如何解決http封包中gzip編碼的html
如何解決http封包中gzip編碼的html
大家都知道,在默認模式下,http協議中發送的網頁的Html代碼是經過gzip編碼後傳送的。那麼我們怎麼才能回復這段編碼後的html呢?
大家可能都知道linux下有一個gzip命令。可以把文件壓縮成gzip編碼的格式,即*.gz
而對於文件的壓縮和解壓縮,可以採用zlib庫中提供的各種介面來進行操作。但是這里問題來了。關於gzip編碼的那些函數都帶有gz開頭的標示。而這些介面維護了一個名叫gz_stream的結構體。並且是針對文件FILE*操作的。
而我們要解決的問題是,我們把截取的封包中的gzip編碼的內容拿出來,放到一個buffer中。那麼怎麼才能針對這個buffer中的數據應用這些介面呢?
我本來的想法是能不能在這些介面中找到專門對內存中的數據進行解碼?
考慮這個問題,我看了這個庫的源代碼。後來放棄了。至於放棄的原因,可能是我意志力不夠,或者不想看那些源代碼了。總之,我看了一天,看的我頭疼。
後來我就想個辦法繞開這一思路,走個彎路。問題豁然開朗。
思路如下:
1. 把獲取到的經過編碼的數據保存到一個文件中。注意寫文件的時候一定要以二進制方式。否則是不能解碼的。
2. 應用zlib中的介面,gzopen(),gzread(),gzclose()即可完成解碼的任務了。
『陸』 linux命令的源代碼怎麼獲取
1. 以搜索ls命令源碼為例,先搜索命令所在包,命令如下: lpj@lpj-linux:~$ which ls /bin/ls 2. 用命令搜索該軟體所在包,代碼如下: lpj@lpj-linux:~$ dpkg -S /bin/ls coreutils: /bin/ls 3. 從上一步中可以知道ls命令的實現在包coreutils中,用apt安裝(說安裝有些歧義,主要是區分apt-get -d)該包的源代碼然後解壓,代碼如下: sudo apt-get source coreutils cd /usr/src/coreutils-XXX #XXX表示版本號 sudo tar zxvf coreutils-XXX.tar.gz 或者只下載源碼,然後手動打補丁再解壓,代碼如下: sudo apt-get -d source coreutils cd /usr/src tar zxvf coreutils-XXX.tar.gz gzip -d coreutils-XXX.diff.gz #這一步會生成coreutils-XXX.diff文件 patch -p0 < coreutils-XXX.diff cd coreutils-XXX tar zxvf coreutils-XXX.tar.gz OK,這幾步執行完後,就可以進入/usr/src/coreutils-XXX/coreutils-XXX/src中查看各命令對應的源代碼了
『柒』 如何查看linux命令源代碼和函數源代碼
1. 以搜索ls命令源碼為例,先搜索命令所在包,命令如下:
lpj@lpj-linux:~$ which ls
/bin/ls
2. 用命令搜索該軟體所在包,代碼如下:
lpj@lpj-linux:~$ dpkg -S /bin/ls
coreutils: /bin/ls
3. 從上一步中可以知道ls命令的實現在包coreutils中,用apt安裝(說安裝有些歧義,主要是區分apt-get -d)該包的源代碼然後解壓,代碼如下:
sudo apt-get source coreutils
cd /usr/src/coreutils-XXX #XXX表示版本號
sudo tar zxvf coreutils-XXX.tar.gz
或者只下載源碼,然後手動打補丁再解壓,代碼如下:
sudo apt-get -d source coreutils
cd /usr/src
tar zxvf coreutils-XXX.tar.gz
gzip -d coreutils-XXX.diff.gz #這一步會生成coreutils-XXX.diff文件
patch -p0 < coreutils-XXX.diff
cd coreutils-XXX
tar zxvf coreutils-XXX.tar.gz
OK,這幾步執行完後,就可以進入/usr/src/coreutils-XXX/coreutils-XXX/src中查看各命令對應的源代碼了
『捌』 這個gzip文件怎麼打開
建議去下載個,好壓軟體,在網路輸入好壓,就有了,基本現在所有的壓縮格式都支持,速度很快,比winrar要好用很多!全免費的軟體吆!
『玖』 php獲取網頁源碼內容有哪些辦法
可以參考以下幾種方法:
方法一: file_get_contents獲取
<span style="white-space:pre"></span>$url="http://www..com/";
<span style="white-space:pre"></span>$fh= file_get_contents
('http://www.hxfzzx.com/news/fzfj/');<span style="white-space:pre"></span>echo $fh;
拓展資料
PHP(外文名:PHP: Hypertext Preprocessor,中文名:「超文本預處理器」)是一種通用開源腳本語言。語法吸收了C語言、Java和Perl的特點,利於學習,使用廣泛,主要適用於Web開發領域。PHP 獨特的語法混合了C、Java、Perl以及PHP自創的語法。它可以比CGI或者Perl更快速地執行動態網頁。
用PHP做出的動態頁面與其他的編程語言相比,PHP是將程序嵌入到HTML(標准通用標記語言下的一個應用)文檔中去執行,執行效率比完全生成HTML標記的CGI要高許多;PHP還可以執行編譯後代碼,編譯可以達到加密和優化代碼運行,使代碼運行更快。
『拾』 OkHttp源碼分析:五大攔截器詳解
主要完成兩件事: 重試與重定向
重試與重定向攔截器主要處理Response,可以看到RouteException和IOException都是調用了recover,返回true表示允許重試。允許重試—>continue—> while (true)—>realChain.proceed,這就完成了重試的過程。
接著看重定向
重定向總結
另附HTTP響應狀態碼分類:
小結: RetryAndFollowUpInterceptor是整個責任鏈中的第一個,首次接觸到Request和最後接收Response的角色,它的主要功能是判斷是否需要重試與重定向。
重試的前提是出現了RouteException或IOException,會通過recover方法進行判斷是否進行重試。
重定向是發生在重試判定後,不滿足重試的條件,會進一步調用followUpRequest根據Response的響應碼進行重定向操作。
補全請求頭:
小結: BridgeInterceptor是連接應用程序和伺服器的橋梁,它為我們補全請求頭,將請求轉化為符合網路規范的Request。得到響應後:1.保存Cookie,在下次請求會讀取對應的cookie數據設置進請求頭,默認cookieJar不提供的實現 2.如果使用gzip返回的數據,則使用 GzipSource 包裝便於解析。
緩存攔截器顧名思義處理緩存的,但是要建立在get請求的基礎上,我們可以去通過okHttpClient.cache(cache)去設置。緩存攔截器的處理流程:
1.從緩存中取出對應請求的響應緩存
2.通過CacheStrategy判斷使用緩存或發起網路請求,此對象中的networkRequest代表需要發起網路請求,cacheResponse表示直接使用緩存。
即: networkRequest存在則優先發起網路請求,否則使用cacheResponse緩存,若都不存在則請求失敗。
如果最終判定不能使用緩存,需要發起網路請求,則來到下一個攔截器ConnectInterceptor
StreamAllocation對象是在第一個攔截器RetryAndFollowUpInterceptor中初始化完成的(設置了連接池、url路徑等),當一個請求發出,需要建立連接,建立連接之後需要使用流來讀取數據,這個StreamAllocation就是協調請求、連接與數據流三者之前的關系,它負責為一次請求尋找連接,然後獲得流來實現網路通信。
StreamAllocation對象有兩個關鍵角色:
真正的連接是在RealConnection中實現的,連接由ConnectionPool管理。
接著我們看下RealConnection的創建和連接的建立:
streamAllocation.newStream—>findHealthyConnection—>findConnection
findConnection:
①StreamAllocation的connection如果可以復用則復用
②如果connection不能復用,則從連接池中獲取RealConnection對象,獲取成功則返回
③如果連接池裡沒有,則new一個RealConnection對象
④調用RealConnection的connect()方法發起請求
⑤將RealConnection對象存進連接池中,以便下次復用
⑥返回RealConnection對象
小結:
ConnectInterceptor攔截器從攔截器鏈中獲取StreamAllocation對象,這個對象在第一個攔截器中創建,在ConnectInterceptor中才用到。
執行StreamAllocation對象的newStream方法創建HttpCodec對象,用來編碼HTTP request和解碼HTTP response。
newStream方法裡面通過findConnection方法返回了一個RealConnection對象。
StreamAllocation對象的connect方法拿到上面返回的RealConnection對象,這個RealConnection對象是用來進行實際的網路IO傳輸的。
writeRequestHeaders和readResponseHeaders(以Http2Codec為例)
小結: CallServerInterceptor完成HTTP協議報文的封裝和解析。
①獲取攔截器鏈中的HttpCodec、StreamAllocation、RealConnection對象
②調用httpCodec.writeRequestHeaders(request)將請求頭寫入緩存
③判斷是否有請求體,如果有,請求頭通過攜帶特殊欄位 Expect:100-continue來詢問伺服器是否願意接受請求體。(一般用於上傳大容量請求體或者需要驗證)
④通過httpCodec.finishRequest()結束請求
⑤通過responseBuilder構建Response
⑥返回Response