請(qing)求之前~HttpHandler實現媒體文件和圖像文件的盜(dao)鏈
小知識:
一個WEB的請求從(cong)客戶端(duan)發到到服務端(duan)接收,處(chu)理并返回給客戶端(duan),它的流程是這樣的(以aspx頁(ye)面(mian)為例):
HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()
inetinfo.exe進(jin)程:是www服(fu)務(wu)的進(jin)程,IIS服(fu)務(wu)和ASPNET_ISAPI.DLL都(dou)寄(ji)存在此進(jin)程中。
ASPNET_ISAPI.DLL:是處理.aspx文件的win32組件。其(qi)實IIS服(fu)務器(qi)是(shi)只能識別.html文件的,當IIS服(fu)務器(qi)發現被請求的文件是(shi).aspx文件時,IIS服(fu)務器(qi)將其(qi)交給aspnet_isapi.dll來(lai)處(chu)理(li)。
aspnet_wp.exe進(jin)程:ASP.NET框架進(jin)程,提供.net運(yun)行(xing)的托管環(huan)境(jing),.net的CLR(公共(gong)語言(yan)運(yun)行(xing)時)就(jiu)是(shi)寄存在此(ci)進(jin)程中。
1 // 摘要(yao): 2 // 定(ding)義(yi) ASP.NET 為使用自定(ding)義(yi) HTTP 處理(li)(li)程序同步處理(li)(li) HTTP Web 請求而實現的協定(ding)。 3 public interface IHttpHandler 4 { 5 // 摘要: 6 // 獲(huo)取一個值,該值指(zhi)示其(qi)他(ta)請求是否可以使用 System.Web.IHttpHandler 實例。 7 // 8 // 返回結果: 9 // 如果 System.Web.IHttpHandler 實例(li)可再次使用,則為 true;否則為 false。 10 bool IsReusable { get; } 11 12 // 摘要(yao): 13 // 通過實現 System.Web.IHttpHandler 接口的自(zi)定義 HttpHandler 啟用 HTTP Web 請(qing)求的處理。 14 // 15 // 參數: 16 // context: 17 // System.Web.HttpContext 對象(xiang),它提供對用于為 HTTP 請(qing)求提供服(fu)務的內部服(fu)務器對象(xiang)(如 Request、Response、Session 18 // 和 Server)的引用。 19 void ProcessRequest(HttpContext context); 20 }
ProcessRequest方法是我們要寫的邏輯,它的參數是當前請求的上下文,例如,你要訪問//localhost:3333/home/index,它的context就是當前
Request的上下文,而如果我們在httphandler里針對一個擴展名進行策略,如jpg,gif,那么,當WEB去渲染這些文件這前,將會首先處理httphandler中的
ProcessRequest方法,然后,如果不符合條件,你可以在頁面上渲染你自己規定的信息,如果沒有問題,再顯示真實的圖片!
這其實就是一個圖片的防盜鏈技術,呵呵!效果如圖:
而在頁面上顯示的圖像路徑還真實的:
這說明,httphandler是在處理這個物理文件之前,重新把另一個文件渲染上去了,呵呵
代碼如下:
1 /// <summary> 2 /// 圖片防盜鏈 3 /// </summary> 4 public class ImgHandler : IHttpHandler 5 { 6 const string errImg = "/Content/daolian.jpg"; 7 public void ProcessRequest(HttpContext context) 8 { 9 // 獲取文(wen)件服務器(qi)端物理(li)路徑(jing) 10 string FileName = context.Server.MapPath(context.Request.FilePath); 11 // 如果UrlReferrer為空,則顯(xian)示一(yi)張默認的禁(jin)止盜鏈的圖片 12 if (context.Request.UrlReferrer == null || context.Request.UrlReferrer.Host == null) 13 { 14 context.Response.ContentType = "image/JPEG"; 15 context.Response.WriteFile(errImg); 16 } 17 else 18 { 19 if (context.Request.UrlReferrer.Host.IndexOf("eee114.com") > 0) 20 { 21 context.Response.ContentType = "image/JPEG"; 22 context.Response.WriteFile(FileName); 23 } 24 else 25 { 26 context.Response.ContentType = "image/JPEG"; 27 context.Response.WriteFile(errImg); 28 } 29 } 30 } 31 32 public bool IsReusable 33 { 34 get { return true; } 35 } 36 }
在WWW網(wang)站的web.config中的<system.web>節點去調用(yong)它(ta)
<!-- HttpHandlers對請求的擴展名進行處理 -->
<httpHandlers>
<add path="*.jpg,*.jpeg,*.gif,*.png,*.bmp" verb="*" type="HttpHandler.ImgHandler,HttpHandler" />
</httpHandlers>
而流媒(mei)體的(de)防盜(dao)鏈也(ye)是(shi)一(yi)樣(yang)的(de)方法,當(dang)然如果(guo)希(xi)望你的(de)流媒(mei)體需要滿足某種條件(jian)的(de)用戶才能看到的(de)話,也(ye)可以這樣(yang)去干(gan):
1 /// <summary> 2 /// 流媒體防(fang)盜(dao)鏈 3 /// </summary> 4 public class VideoHandler : IHttpHandler 5 { 6 const string errVideo = "/Content/daolian.jpg"; 7 #region IHttpHandler 成員 8 9 public bool IsReusable 10 { 11 get { return true; } 12 } 13 14 public void ProcessRequest(HttpContext context) 15 { 16 //驗證(zheng)符(fu)合(he)訪(fang)問媒體的(de)用(yong)戶(hu)權限(xian) 17 if (context.Session == null 18 || context.Session["UserID"] == null 19 || Convert.ToInt32(context.Session["UserID"]) <= 0) 20 { 21 context.Response.ContentType = "mpg4 video/mp4"; 22 context.Response.WriteFile(errVideo); 23 } 24 } 25 26 #endregion 27 }
web.config是它的(de)入口,呵呵
<!-- HttpHandlers對請求的擴展名進行處理 -->
<httpHandlers>
<add path="*.avi,*.mp4,*.3gp,*.flv" verb="*" type="HttpHandler.VideoHandler,HttpHandler" />
</httpHandlers>
OK,這時,你的(de)(de)流(liu)媒體在訪問(wen)和下載(zai)之前,也會進行驗證(zheng),不滿足,就會下載(zai)默認的(de)(de)了,呵呵!
看來在頁面(mian)“請求(qiu)之前”,發生(sheng)的(de)事確實不少呀!