• 请求之前~HttpHandler实现媒体文件和图像文件的盗链


    小知识:

    一个WEB的请求从客户端发到到服务端接收,处理并返回给客户端,它的流程是这样的(以aspx页面为例):

       HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

           inetinfo.exe进程:是www服务的进程,IIS服务和ASPNET_ISAPI.DLL都寄存在此进程中。

      ASPNET_ISAPI.DLL:是处理.aspx文件的win32组件。其实IIS服务器是只能识别.html文件的,当IIS服务器发现被请求的文件是.aspx文件时,IIS服务器将其交给aspnet_isapi.dll来处理

      aspnet_wp.exe进程:ASP.NET框架进程,提供.net运行的托管环境,.net的CLR(公共语言运行时)就是寄存在此进程中。

     1     // 摘要:
     2     //     定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
     3     public interface IHttpHandler
     4     {
     5         // 摘要:
     6         //     获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
     7         //
     8         // 返回结果:
     9         //     如果 System.Web.IHttpHandler 实例可再次使用,则为 true;否则为 false。
    10         bool IsReusable { get; }
    11 
    12         // 摘要:
    13         //     通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
    14         //
    15         // 参数:
    16         //   context:
    17         //     System.Web.HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session
    18         //     和 Server)的引用。
    19         void ProcessRequest(HttpContext context);
    20     }
    ProcessRequest方法是我们要写的逻辑,它的参数是当前请求的上下文,例如,你要访问http://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             // 获取文件服务器端物理路径
    10             string FileName = context.Server.MapPath(context.Request.FilePath);
    11             // 如果UrlReferrer为空,则显示一张默认的禁止盗链的图片
    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网站的web.config中的<system.web>节点去调用它

       <!-- HttpHandlers对请求的扩展名进行处理 -->
        <httpHandlers>
          <add path="*.jpg,*.jpeg,*.gif,*.png,*.bmp" verb="*" type="HttpHandler.ImgHandler,HttpHandler" />
        </httpHandlers>

    而流媒体的防盗链也是一样的方法,当然如果希望你的流媒体需要满足某种条件的用户才能看到的话,也可以这样去干:

     1   /// <summary>
     2     /// 流媒体防盗链
     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             //验证符合访问媒体的用户权限
    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是它的入口,呵呵

       <!-- HttpHandlers对请求的扩展名进行处理 -->
        <httpHandlers>
             <add path="*.avi,*.mp4,*.3gp,*.flv" verb="*" type="HttpHandler.VideoHandler,HttpHandler" />
        </httpHandlers>

    OK,这时,你的流媒体在访问和下载之前,也会进行验证,不满足,就会下载默认的了,呵呵!

    看来在页面“请求之前”,发生的事确实不少呀!



  • 相关阅读:
    VS Code 使用笔记
    Haskell语言开发工具
    Haskell语言学习笔记(81)Data.Typeable
    Haskell语言学习笔记(80)req
    Haskell语言学习笔记(79)lambda演算
    Haskell语言学习笔记(78)fix
    2733: [HNOI2012]永无乡
    牛课练习赛17
    bzoj3758. 数数
    【BZOJ1786】[Ahoi2008]Pair 配对
  • 原文地址:https://www.cnblogs.com/lori/p/2825225.html
Copyright © 2020-2023  润新知