园林空气净化器永久测试版
2010-09-01 12:32 Ivony... 阅读(2546) 评论(18) 编辑 收藏 举报首先这是一个用Jumony技术驱动的好玩的东西,需要先下载Jumony M1然后添加引用。
其次只提供源代码,不负责任何技术支持,遇到任何问题请自己去修改。
这款净化器的主要功能就是降糖降脂,促进新陈代谢,有益身心健康,但有造成页面崩溃等严重副作用,大家慎重选择。
如何使用?
首先编译成一个控制台程序,运行。然后修改host文件,加入127.0.0.1 www.cnblogs.com。最后关掉浏览器,重新打开www.cnblogs.com就可以了。
该程序在有UAC控制的系统中,需要以管理员身份运行。
源代码如下:
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using Ivony.Fluent;
using Ivony.Web.Html;
using Ivony.Web.Html.HtmlAgilityPackAdaptor;
using HtmlAgilityPack;
using System.Threading;
namespace CnblogsCleaner
{
class Program
{
static void Main( string[] args )
{
var listener = new HttpListener();
listener.Prefixes.Add( "http://*/" );
listener.Start();
while ( true )
{
var context = listener.GetContext();
//ProcessContext( context );
((Action) delegate { ProcessContext( context ); }).BeginInvoke( null, null );
}
}
private static void ProcessContext( HttpListenerContext context )
{
try
{
if ( !context.Request.Url.Host.EndsWith( "cnblogs.com" ) )
return;
var builder = new UriBuilder( context.Request.Url );
builder.Host = "222.92.117.56";
Console.WriteLine( context.Request.Url );
var match = userBlogUrlRegex.Match( context.Request.Url.AbsoluteUri );
if ( blockedUsers.Contains( match.Groups["username"].Value ) )
{
context.Response.StatusCode = 200;
context.Response.ContentEncoding = Encoding.UTF8;
using ( var writer = new StreamWriter( context.Response.OutputStream, Encoding.UTF8 ) )
{
writer.WriteLine( "此页面有害身心健康,已被园林空气净化器净化,如需查看,请关闭净化器。" );
}
}
var request = (HttpWebRequest) HttpWebRequest.Create( builder.Uri );
request.Method = context.Request.HttpMethod;
request.ProtocolVersion = context.Request.ProtocolVersion;
request.AllowAutoRedirect = false;
request.Timeout = (int) new TimeSpan( 0, 0, 10 ).TotalMilliseconds;
request.Host = context.Request.Url.Host;
foreach ( var key in context.Request.Headers.AllKeys )
{
SetHeader( request, key, context.Request.Headers.Get( key ) );
}
if ( context.Request.ContentLength64 > 0 )
{
using ( var stream = request.GetRequestStream() )
{
var buffer = new byte[context.Request.ContentLength64];
context.Request.InputStream.Read( buffer, 0, buffer.Length );
stream.Write( buffer, 0, buffer.Length );
}
}
HttpWebResponse response;
try
{
response = (HttpWebResponse) request.GetResponse();
}
catch ( WebException e )
{
response = (HttpWebResponse) e.Response;
if ( e.Status != WebExceptionStatus.Success )
{
Console.WriteLine( "{0} {1}...", context.Request.Url, e.Status.ToString() );
context.Response.Close();
if ( response != null )
response.Close();
return;
}
//return;
}
using ( response )
{
Console.WriteLine( "{0} response...", context.Request.Url );
context.Response.StatusCode = (int) response.StatusCode;
context.Response.StatusDescription = response.StatusDescription;
foreach ( var key in response.Headers.AllKeys )
{
if ( key.Equals( "Content-Length", StringComparison.InvariantCultureIgnoreCase ) )
continue;
if ( key.Equals( "Location", StringComparison.InvariantCultureIgnoreCase ) )
{
context.Response.Redirect( response.Headers.Get( key ) );
continue;
}
context.Response.Headers.Add( key, response.Headers.Get( key ) );
}
MemoryStream memoryBuffer = new MemoryStream();
if ( response.ContentLength > 0 )
{
using ( var stream = response.GetResponseStream() )
{
byte[] buffer = new byte[1024];
while ( true )
{
int length = stream.Read( buffer, 0, buffer.Length );
if ( length == 0 )
break;
memoryBuffer.Write( buffer, 0, length );
}
}
memoryBuffer.Seek( 0, SeekOrigin.Begin );
try
{
if ( response.ContentType.StartsWith( "text/" ) )
{
var encoding = Encoding.GetEncoding( response.CharacterSet );
var content = new StreamReader( memoryBuffer, encoding ).ReadToEnd();
Console.WriteLine( content );
if ( response.ContentType.Split( ';' )[0] == "text/html" )
{
content = Cleanup( context.Request.Url, content );
memoryBuffer = new MemoryStream( encoding.GetBytes( content ) );
}
}
if ( context.Request.Url.Equals( new Uri( "http://www.cnblogs.com/ws/BlogPost.asmx/GetSiteHomePosts" ) ) || context.Request.Url.Equals( new Uri( "http://www.cnblogs.com/ws/BlogPost.asmx/GetHeadline" ) ) )
{
var serializer = new DataContractJsonSerializer( typeof( CnblogsJsonType ) );
var data = (CnblogsJsonType) serializer.ReadObject( memoryBuffer );
data.d = Cleanup( context.Request.Url, data.d );
memoryBuffer = new MemoryStream();
serializer.WriteObject( memoryBuffer, data );
}
}
catch ( Exception e )
{
Console.WriteLine( e );
}
memoryBuffer.WriteTo( context.Response.OutputStream );
}
}
}
catch ( Exception e )
{
Console.WriteLine( e );
}
context.Response.Close();
}
[DataContract]
private class CnblogsJsonType
{
[DataMember]
public string d { get; set; }
}
private static void SetHeader( HttpWebRequest request, string key, string value )
{
switch ( key )
{
case "Accept":
request.Accept = value;
break;
case "Connection":
if ( value.Equals( "Keep-Alive", StringComparison.InvariantCultureIgnoreCase ) )
{
request.KeepAlive = true;
break;
}
if ( value.Equals( "Closed", StringComparison.InvariantCultureIgnoreCase ) )
break;
request.Connection = value;
break;
case "Content-Length":
//request.ContentLength = long.Parse( value );
break;
case "Content-Type":
request.ContentType = value;
break;
case "Date":
request.Date = DateTime.Parse( value );
break;
case "Expect":
request.Expect = value;
break;
case "Host":
//request.Host = value;
break;
case "If-Modified-Since":
request.IfModifiedSince = DateTime.Parse( value );
break;
case "Range":
throw new NotSupportedException();
case "Referer":
request.Referer = value;
break;
case "Transfer-Encoding":
request.TransferEncoding = value;
break;
case "User-Agent":
request.UserAgent = value;
break;
case "Proxy-Connection":
throw new NotSupportedException();
case "Accept-Encoding":
break;
default:
request.Headers.Set( key, value );
break;
}
}
private static readonly Regex userBlogUrlRegex = new Regex( @"(^http://www.cnblogs.com/(?<username>\w+)/(?<resource>.*)$)|(^http://(?<username>\w+).cnblogs.com/(?<resource>.*)$)", RegexOptions.Compiled );
private static readonly string[] blockedUsers = new[] { "firelong", "huasheng" };
private static string Cleanup( Uri url, string content )
{
var rawDocument = new HtmlDocument();
rawDocument.LoadHtml( content );
var document = rawDocument.AsDocument();
document.Find( "A" ).Select( element => element.Attribute( "href" ) ).Where( attribute => attribute.Value() != null ).ToArray()
.ForAll( attribute =>
{
var href = new Uri( url, attribute.Value() ).AbsoluteUri;
var match = userBlogUrlRegex.Match( href );
if ( blockedUsers.Contains( match.Groups["username"].Value ) )
{
if ( match.Groups["resource"].Value != "" )
{
var element = FindContainer( attribute.Element );
element.Remove();
}
else
attribute.Element.Remove();
}
} );
return document.OuterHtml();
}
private static IHtmlElement FindContainer( IHtmlElement element )
{
var container = element;
while ( true )
{
var parent = container.Parent;
if ( parent == null )
break;
if ( parent.Find( "A" ).Select( e => e.Attribute( "href" ).Value() ).ToArray().NotNull().Count( href => userBlogUrlRegex.IsMatch( href ) ) > 1 )
return container;
container = parent as IHtmlElement;
if ( container == null )
break;
}
return element;