C#编写的一个反向代理工具,可以缓存网页到本地的代码

下边代码内容是关于 C#编写的一个反向代理工具,可以缓存网页到本地的代码。

<%@ WebHandler Language="C#" Class="proxy" %>

using System;

using System.Web;

using System.Net;

using System.Text;

using System.IO;

using System.Collections.Generic;

using System.Configuration;

public class proxy : IHttpHandler

{

    HttpResponse Response;

    HttpRequest Request;

    HttpApplicationState Application;

    HttpServerUtility Server;

    static string proxyCacheFolder = ConfigurationManager.AppSettings["proxyCacheFolder"];

    static string proxyDomain = ConfigurationManager.AppSettings["proxyDomain"];

    static string proxyReferer = ConfigurationManager.AppSettings["proxyReferer"];

    bool proxyCacheDirectAccess = ConfigurationManager.AppSettings["proxyCacheDirectAccess"] == "true";

    int proxyCacheSeconds = int.Parse(ConfigurationManager.AppSettings["proxyCacheSeconds"]);

    public void ProcessRequest(HttpContext context)

    {

        Response = context.Response;

        Request = context.Request;

        Application = context.Application;

        Server = context.Server;

        string path = context.Request.RawUrl;

        bool delCache = path.IndexOf("?del") > 0;

        if (delCache)

        {

            path = path.Replace("?del", string.Empty);

            DeleteCacheFile(path);

            return;

        }

        bool allowCache = Request.QueryString["cache"] == "true";

        string seconds = Request.QueryString["seconds"] ?? string.Empty;

        if (!int.TryParse(seconds, out proxyCacheSeconds))

        {

            proxyCacheSeconds = 3600;

        }

        if (allowCache)

        {

            EchoData(path);

        }

        else

        {

            WebClient wc = new WebClient();

            wc.Headers.Set("Referer", proxyReferer);

            byte[] buffer = wc.DownloadData(proxyDomain + path);

            Response.ContentType = wc.ResponseHeaders["Content-Type"];

            foreach (string key in wc.ResponseHeaders.AllKeys)

            {

                Response.Headers.Set(key, wc.ResponseHeaders[key]);

            }

            wc.Dispose();

            Response.OutputStream.Write(buffer, 0, buffer.Length);

        }

    }

    void ClearTimeoutCache(DirectoryInfo d)

    {

        if (d.Exists)

        {

            FileInfo[] files = d.GetFiles();

            foreach (FileInfo file in files)

            {

                TimeSpan timeSpan = DateTime.Now - file.LastAccessTime;

                if (timeSpan.TotalSeconds > proxyCacheSeconds)

                {

                    file.Delete();

                }

            }

        }

    }

    string GetCacheFolderPath(string hash)

    {

        string s = string.Empty;

        for (int i = 0; i <= 2; i++)

        {

            s += hash[i] + "/";

        }

        return s;

    }

    void EchoCacheHeader(string cacheHeaderPath)

    {

        string[] headers = File.ReadAllLines(cacheHeaderPath);

        for (int i = 0; i < headers.Length; i++)

        {

            string[] headerKeyValue = headers[i].Split(':');

            if (headerKeyValue.Length == 2)

            {

                if (headerKeyValue[0] == "Content-Type")

                {

                    Response.ContentType = headerKeyValue[1];

                }

                Response.Headers.Set(headerKeyValue[0], headerKeyValue[1]);

            }

        }

    }

    void DeleteCacheFile(string path)

    {

        string absFolder = Server.MapPath(proxyCacheFolder);

        string hash = GetHashString(path);

        string folder = GetCacheFolderPath(hash);

        string cacheBodyPath = absFolder + "/body/" + folder + hash;

        string cacheHeaderPath = absFolder + "/header/" + folder + hash;

        FileInfo cacheBody = new FileInfo(cacheBodyPath);

        FileInfo cacheHeader = new FileInfo(cacheHeaderPath);

        if (cacheBody.Exists)

        {

            cacheBody.Delete();

        }

        if (cacheHeader.Exists)

        {

            cacheHeader.Delete();

        }

        Response.Write("delete cache file Success!rn" + path);

    }

    bool EchoCacheFile(string cacheHeaderPath, string cacheBodyPath, bool ifTimeout)

    {

        FileInfo cacheBody = new FileInfo(cacheBodyPath);

        FileInfo cacheHeader = new FileInfo(cacheHeaderPath);

        ClearTimeoutCache(cacheBody.Directory);

        ClearTimeoutCache(cacheHeader.Directory);

        if (cacheBody.Exists && cacheHeader.Exists)

        {

            if (ifTimeout)

            {

                TimeSpan timeSpan = DateTime.Now - cacheBody.LastWriteTime;

                if (timeSpan.TotalSeconds < proxyCacheSeconds)

                {

                    EchoCacheHeader(cacheHeaderPath);

                    Response.TransmitFile(cacheBodyPath);

                    return true;

                }

            }

            else

            {

                EchoCacheHeader(cacheHeaderPath);

                Response.TransmitFile(cacheBodyPath);

                return true;

            }

        }

        return false;

    }

    void EchoData(string path)

    {

        string absFolder = Server.MapPath(proxyCacheFolder);

        string hash = GetHashString(path);

        string folder = GetCacheFolderPath(hash);

        string cacheBodyPath = absFolder + "/body/" + folder + hash;

        string cacheHeaderPath = absFolder + "/header/" + folder + hash;

        bool success;

        if (proxyCacheDirectAccess)

        {

            success = EchoCacheFile(cacheHeaderPath, cacheBodyPath, false);

            if (!success)

            {

                Response.Write("直接从缓存读取失败!");

            }

            return;

        }

        success = EchoCacheFile(cacheHeaderPath, cacheBodyPath, true);

        if (success)

        {

            return;

        }

        string ApplicationKey = "CacheList";

        List List = null;

        if (Application[ApplicationKey] == null)

        {           

            Application.Lock();

            Application[ApplicationKey] = List = new List(1000);

            Application.UnLock();

        }

        else

        {

            List = (List)Application[ApplicationKey];

        }

        if (List.Contains(hash))

        {

            success = EchoCacheFile(cacheHeaderPath, cacheBodyPath, false);

            if (success)

            {

                return;

            }

            else

            {

                WebClient wc = new WebClient();

                wc.Headers.Set("Referer", proxyReferer);

                byte[] data = wc.DownloadData(proxyDomain + path);

                Response.ContentType = wc.ResponseHeaders["Content-Type"];

                foreach (string key in wc.ResponseHeaders.AllKeys)

                {

                    Response.Headers.Set(key, wc.ResponseHeaders[key]);

                }

                wc.Dispose();

                Response.BinaryWrite(data);


            }

        }

        else

        {


            WebClient wc = new WebClient();

            wc.Headers.Set("Referer", proxyReferer);

            StringBuilder headersb = new StringBuilder();

            List.Add(hash);

            byte[] data = wc.DownloadData(proxyDomain + path);

            Response.ContentType = wc.ResponseHeaders["Content-Type"];

            foreach (string key in wc.ResponseHeaders.AllKeys)

            {

                headersb.Append(key);

                headersb.Append(":");

                headersb.Append(wc.ResponseHeaders[key]);

                headersb.Append("rn");

                Response.Headers.Set(key, wc.ResponseHeaders[key]);

            }

            wc.Dispose();

            string headers = headersb.ToString().Trim();

            if (!Directory.Exists(absFolder + "/header/" + folder))

            {

                Directory.CreateDirectory(absFolder + "/header/" + folder);

            }

            StreamWriter sw = File.CreateText(absFolder + "/header/" + folder + hash);

            sw.Write(headers);

            sw.Close();

            sw.Dispose();

            if (!Directory.Exists(absFolder + "/body/" + folder))

            {

                Directory.CreateDirectory(absFolder + "/body/" + folder);

            }

            FileStream fs = File.Create(absFolder + "/body/" + folder + hash);

            fs.Write(data, 0, data.Length);

            fs.Close();

            fs.Dispose();

            List.Remove(hash);



            Response.BinaryWrite(data);

        }

    }

    string GetHashString(string path)

    {

        string md5 = GetMd5Str(path);

        return md5;

    }

    static string GetMd5Str(string ConvertString)

    {

        System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

        string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);

        t2 = t2.Replace("-", "");

        return t2;

    }

    public bool IsReusable

    {

        get

        {

            return false;

        }

    }

}




web.config




 

   

   

 

 

   


     

       

         

       

     

     

       

         

       

     


   

 

 


   

   

   

   

   

   

   

   

   

   



 


 

   

     

   

 

 

   

 


你可能感兴趣的:(C#编写的一个反向代理工具,可以缓存网页到本地的代码)