原文:https://blog.csdn.net/zhang116868/article/details/49406599
大名鼎鼎的Fiddler大家都知道,或者用過,Fiddler 開放了他的FiddlerCoreAPI 提供給開發者調用,來處理所有的http請求,功能就如Fiddler一樣強大,下面我們來簡單介紹一下。
程序類庫官網下載地址:http://fiddler.wikidot.com/fiddlercore-api
官網上下的是exe安裝文件,比較麻煩,因此筆者上傳了一個安裝后提取出來的庫,包括.net 2.0、4.0兩個運行環境版本和一個簡單的實例。
下載地址:http://download.csdn.net/detail/zhang116868/9211923
接下來我們根據官方提供的SampleApp實例來進行講解。
啟動方法:
- //設置別名
- Fiddler.FiddlerApplication.SetAppDisplayName("FiddlerCoreDemoApp");
- //啟動方式
- FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
- //定義http代理端口
- int iPort = 8877;
- //啟動代理程序,開始監聽http請求
- //端口,是否使用windows系統代理(如果為true,系統所有的http訪問都會使用該代理)
- Fiddler.FiddlerApplication.Startup(iPort, true, false, true);
- // 我們還將創建一個HTTPS監聽器,當FiddlerCore被偽裝成HTTPS服務器有用
- // 而不是作為一個正常的CERN樣式代理服務器。
- oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
停止方法:
- if (null != oSecureEndpoint) oSecureEndpoint.Dispose();
- Fiddler.FiddlerApplication.Shutdown();
- Thread.Sleep(500);
如果占用了系統代理,那么一定要記得如此退出,不然系統代理不會被釋放,你將不能再打開網頁。
接下來介紹攔截http請求的處理:
- //定義會話,每一個請求都將封裝成一個會話
- List<Fiddler.Session> oAllSessions = new List<Fiddler.Session>();
- //請求出錯時處理
- Fiddler.FiddlerApplication.BeforeReturningError += FiddlerApplication_BeforeReturningError;
- //在發送請求之前執行的操作
- Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
- {
- //請求的全路徑
- Console.WriteLine("Before request for:\t" + oS.fullUrl);
- // 為了使反應篡改,必須使用緩沖模式
- // 被啟用。這允許FiddlerCore以允許修改
- // 在BeforeResponse處理程序中的反應,而不是流
- // 響應給客戶機作為響應進來。
- Debug.WriteLine(oS.RequestBody);
- oS.bBufferResponse = true;
- Monitor.Enter(oAllSessions);
- oAllSessions.Add(oS);
- Monitor.Exit(oAllSessions);
- oS["X-AutoAuth"] = "(default)";
- /* 如果請求是要我們的安全的端點,我們將回顯應答。
- 注:此BeforeRequest是越來越要求我們兩個主隧道代理和我們的安全的端點,
- 讓我們來看看它的Fiddler端口連接到(pipeClient.LocalPort)客戶端,以確定是否該請求
- 被發送到安全端點,或為了達到**安全端點被僅僅發送到主代理隧道(例如,一個CONNECT)。
- 因此,如果你運行演示和參觀的https://本地主機:7777在瀏覽器中,你會看到
- Session list contains...
- 1 CONNECT http://localhost:7777
- 200 <-- CONNECT tunnel sent to the main proxy tunnel, port 8877
- 2 GET https://localhost:7777/
- 200 text/html <-- GET request decrypted on the main proxy tunnel, port 8877
- 3 GET https://localhost:7777/
- 200 text/html <-- GET request received by the secure endpoint, port 7777
- */
- //oS.utilCreateResponseAndBypassServer();
- //oS.oResponse.headers.SetStatus(200, "Ok");
- //string str = oS.GetResponseBodyAsString();
- //oS.utilSetResponseBody(str + "aaaaaaaaaaaaaaaaaaaaa");
- if ((oS.oRequest.pipeClient.LocalPort == iSecureEndpointPort) && (oS.hostname == sSecureEndpointHostname))
- {
- oS.utilCreateResponseAndBypassServer();
- oS.oResponse.headers.SetStatus(200, "Ok");
- oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
- oS.oResponse["Cache-Control"] = "private, max-age=0";
- oS.utilSetResponseBody("<html><body>Request for httpS://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString());
- }
- //if ((oS.oRequest.pipeClient.LocalPort == 8877) && (oS.hostname == "www.baidu.com"))
- //{
- // string url = oS.fullUrl;
- // oS.utilCreateResponseAndBypassServer();
- // oS.oResponse.headers.SetStatus(200, "Ok");
- // oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
- // oS.oResponse["Cache-Control"] = "private, max-age=0";
- // oS.utilSetResponseBody("<html><body>Request for httpS://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString());
- //}
- };
- /*
- // 下面的事件,您可以檢查由Fiddler閱讀每一響應緩沖區。
- * 請注意,這不是為絕大多數應用非常有用,因為原始緩沖區幾乎是無用的;它沒有解壓,它包括標題和正文字節數等。
- //
- // 本次僅適用於極少數的應用程序這就需要一個原始的,未經處理的字節流獲取有用
- Fiddler.FiddlerApplication.OnReadResponseBuffer += new EventHandler<RawReadEventArgs>(FiddlerApplication_OnReadResponseBuffer);
- */
- Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS) {
- // 取消以下兩條語句解壓縮/ unchunk的
- //HTTP響應,並隨后修改任何HTTP響應,以取代
- //單詞“微軟”和“Bayden”的實例。 你必須如此設置:
- // set bBufferResponse = true inside the beforeREQUEST method above.
- //
- oS.utilDecodeResponse();
- // 內容:{3} , oS.GetResponseBodyEncoding().GetString(oS.responseBodyBytes)
- Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.responseCode, oS.fullUrl);
- Console.WriteLine(oS.GetResponseBodyAsString());
- Debug.WriteLine(oS.GetResponseBodyAsString());
- //bool r = oS.utilReplaceInResponse("1.歡迎使用!", "aaaaaaaaaaaaaaaaaaaaaa");
- //Console.WriteLine(r);
- };
- Fiddler.FiddlerApplication.AfterSessionComplete += delegate(Fiddler.Session oS)
- {
- //Console.WriteLine("Finished session:\t" + oS.fullUrl);
- Console.Title = ("Session list contains: " + oAllSessions.Count.ToString() + " sessions");
- };
作為學習,注釋的代碼也很重要,大家有必要拿出來運行一下,看看結果。