当前位置: 主页 > 日志 > ISAPI/ADSI >

ISAPI Filter实现网站资源防盗链

//ISAPI Filter实现网站资源防盗链
//by redice 2008.12.25 redice@163.com


原理很简单,就一句话:检查HTTP请求报头中的Referer字段是否为服务器网站的主机头,如果不是则决绝该请求。


完整的代码如下:


//filter.cpp
#include <windows.h>
// 包含了ISAPI过滤器所需的定义和原型
#include <httpfilt.h>
#include <stdio.h>


// 过滤器描述信息
#define FILTER_DESCRIPTION "Isapi Filter v1.0"


//SF_NOTIFY_READ_RAW_DATA通知处理
/*DWORD HandleEvent_ReadRawData(HTTP_FILTER_CONTEXT *pfc,
            HTTP_FILTER_RAW_DATA *pReadData);*/


//SF_NOTIFY_URL_MAP通知处理


DWORD HandleEvent_OnUrlMap(HTTP_FILTER_CONTEXT *pfc,
             HTTP_FILTER_URL_MAP *pUrlData);
// 获取文件的后缀名并转换为小写
char * GetFileExtensionLCase(char * filepath,char * extension,DWORD  *dwSize);


// DLL入口
BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD dvReason,LPVOID lpv)
{
    OutputDebugString("DllMain ");
    return TRUE;
}


//GetFilterVersion
BOOL WINAPI GetFilterVersion(HTTP_FILTER_VERSION *pVersion)
{
    //设置过滤器版本号
    pVersion->dwFilterVersion=HTTP_FILTER_REVISION;

    //设置过滤器描述信息
    strncpy(pVersion->lpszFilterDesc,FILTER_DESCRIPTION,SF_MAX_FILTER_DESC_LEN);

    // 注册感兴趣的通知,设置过滤器的优先级
    pVersion->dwFlags=(SF_NOTIFY_ORDER_HIGH|
        SF_NOTIFY_SECURE_PORT|    //Server在安全端口上收到一个客户连接
        SF_NOTIFY_NONSECURE_PORT//Server在非安全端口上收到一个客户连接
        //SF_NOTIFY_READ_RAW_DATA | //Server从Client读取了数据
        SF_NOTIFY_URL_MAP);       //Server准备简化逻辑URL映射为实际路径


    return TRUE;
}


// HttpFilterProc
DWORD WINAPI HttpFilterProc(HTTP_FILTER_CONTEXT *pfc,
        DWORD dwNotificationType,VOID *pvData)
{
    DWORD dwRet=SF_STATUS_REQ_NEXT_NOTIFICATION;
    switch(dwNotificationType)
    {
    /*case SF_NOTIFY_READ_RAW_DATA:
        dwRet=HandleEvent_ReadRawData(pfc,
            (HTTP_FILTER_RAW_DATA *)pvData);
        break;*/
    
    case SF_NOTIFY_URL_MAP:
        dwRet=HandleEvent_OnUrlMap(pfc,
            (HTTP_FILTER_URL_MAP *)pvData);
     break;
    }
    return dwRet;
}
/*
//SF_NOTIFY_READ_RAW_DATA通知处理
DWORD HandleEvent_ReadRawData(HTTP_FILTER_CONTEXT *pfc,
            HTTP_FILTER_RAW_DATA *pReadData)
{
    DWORD dwRet=SF_STATUS_REQ_NEXT_NOTIFICATION;


    


    return dwRet;
}
*/
//SF_NOTIFY_URL_MAP通知处理
DWORD HandleEvent_OnUrlMap(HTTP_FILTER_CONTEXT *pfc,
                             HTTP_FILTER_URL_MAP *pUrlData)
{
    DWORD dwRet=SF_STATUS_REQ_NEXT_NOTIFICATION;
    char fileext[10]={0}; //文件后缀名
    DWORD dwSize=0;


    // 获取文件的后缀名,并转换为小写
    dwSize=10;
    GetFileExtensionLCase(pUrlData->pszPhysicalPath,fileext, &dwSize);
    if(dwSize)
    {
        //如果文件后缀名为gif,jpg,png中的一种
        if(!strcmp(fileext,"gif") || !strcmp(fileext,"jpg") || !strcmp(fileext,"png") )
        {
            //检查HTTP报头中Referer
            char Referer[256]={0};
            char Host[256]={0};
            dwSize=256;
            pfc->GetServerVariable(pfc,"HTTP_REFERER",Referer,&dwSize);
            OutputDebugString(Referer);
            dwSize=256;
            if(pfc->GetServerVariable(pfc,"HTTP_HOST",Host,&dwSize));
            OutputDebugString(Host);
            if(!strstr(Referer,Host)) //如果Referer中不含有Host
            {
                //我们决绝这次请求,或者修改pUrlData->pszPhysicalPath的值
                pfc->ServerSupportFunction(pfc,SF_REQ_SEND_RESPONSE_HEADER,
                    "403 Forbidden  ",0,(DWORD)NULL);
                return SF_STATUS_REQ_FINISHED;
            }
        }
    }




    return dwRet;
}




// 获取文件的后缀名并转换为小写
char * GetFileExtensionLCase(char * filepath,char * extension,DWORD  *dwSize)
{
    unsigned int i=0,j=0;
    for(;i<strlen(filepath);i++)
    {
        if(filepath[i]!=\ && filepath[i]!=.)
        {
            if(j>*dwSize-2)
            {
                memset(extension,0,*dwSize);
                j=0;
            }
            extension[j++]=filepath[i];
        }
        else
        {
            memset(extension,0,*dwSize);
            j=0;
        }
        
    }
    *dwSize=j+1;
    return _strlwr(extension);
}


//Moudle.def
EXPORTS
GetFilterVersion
HttpFilterProc
DllMain

[日志信息]

该日志于 2009-02-26 21:47 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “ISAPI Filter实现网站资源防盗链” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部