您好,欢迎访问一九零五行业门户网

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

c#编写的一个反向代理工具,可以缓存网页到本地
proxy.ashx 主文件
using system; using system.web; using system.net; using system.text; using system.io; using system.collections.generic; using system.configuration; /// /// 把http headers 和 http 响应的内容 分别存储在 /proxy/header/ 和 /proxy/body/ 中 /// 分层次创建目录 /// 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; } /// /// 读取缓存的header 并输出 /// /// 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!\r\n + path); } /// /// 输出缓存 /// /// 缓存header 的文件路径 /// 缓存 body 的文件路径 /// 是否进行判断文件过期 /// 是否输出成功 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; } //更新cache file 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]; } //判断是否已有另一个进程正在更新cache file 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); //处理header 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); //处理header 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(\r\n); 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
~/.*$ ~/ajax/.*$
其它类似信息

推荐信息