[四星]写一个小代理软件,充分利用adblock-cn的规制

除了美化之外,还可以来尝试挑战一下任务
回复
头像
oneleaf
论坛管理员
帖子: 10441
注册时间: 2005-03-27 0:06
系统: Ubuntu 12.04

[四星]写一个小代理软件,充分利用adblock-cn的规制

#1

帖子 oneleaf » 2009-09-23 14:43

1 任务内容: 写一个小代理软件,充分利用adblock-cn的规制来过滤网址。

2 任务的难度: 四星

3 任务的目的: 掌握http及http代理协议,以及socket编程

4 任务所涉及的软件: python/perl

5 任务将大致消耗的时间: 1~2周

6 任务涉及参考: HTTP协议(RFC中文版) http://www.360doc.com/content/080501/13 ... 27765.html
规则位于: http://adblock-chinalist.googlecode.com ... dblock.txt
规则语法: http://adblockplus.org/en/filters

程序先建立一个多线程监听端口,接收到代理请求,解析出目标地址,如果规制匹配直接放弃,连接目标地址,转发请求。

--原来的下视频的觉得意义不大放弃,更换为这个可以给IE使用--
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: [三星]写一个小代理软件,只要发现是在线视频,就保存下来

#2

帖子 eexpress » 2009-09-23 14:44

● type find-opera-1M
find-opera-1M is aliased to `find ~/.opera/cache*/ -cmin -15 -size +1000k -exec echo "----------" \; -exec ls -l {} \; -exec file {} \;'

我经常用,swf而已。基本够用。
● 鸣学
头像
yaoms
帖子: 4952
注册时间: 2007-10-19 14:51
来自: 深圳

Re: [四星]写一个小代理软件,只要发现是在线视频,就保存下来

#3

帖子 yaoms » 2009-09-23 15:30

ee这个不是代理。作弊 :em05
Nothing 有事请发邮件到 yms541 AT gmail.com
alias 爱慕颇雷尔='mplayer'
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: [四星]写一个小代理软件,只要发现是在线视频,就保存下来

#4

帖子 eexpress » 2009-09-23 15:33

我提供思维而已嘛。对大家有用就行。

相关,相关
● 鸣学
头像
oneleaf
论坛管理员
帖子: 10441
注册时间: 2005-03-27 0:06
系统: Ubuntu 12.04

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#5

帖子 oneleaf » 2009-09-25 20:57

ok,全部给出代码,本来有一个 thirdrequst 和 domin 的选项,不过本着临错杀不放过的原则,没有理会。默认在端口8080监听,有兴趣的朋友可以试试,运行后,设置代理服务器为 127.0.0.1 8080 ,支持https/http代理。这个程序应该可用于生产环境的。

代码: 全选

#!/usr/bin/env python
# -*- coding: utf-8; -*-
# (c) UbuntuChina, http://www.ubuntu.org.cn
# (c) free software, GPLv3
# Connect: oneleaf@gmail.com

import BaseHTTPServer, select, socket, SocketServer, urllib2, re, hashlib, urlparse, os, struct, time

def exeTime(func):  
    def newFunc(*args, **args2):  
        t0 = time.time()  
        back = func(*args, **args2)  
        t1 = time.time() - t0
        if t1 > 10:
           f=open('slow.txt','a')
           f.write("@%.3fs %s\n" % (t1, args[0].url))
           f.close() 
        return back  
    return newFunc  

class Adblock():
    def addcustomrules(self,customfile='adblock.txt'):
        if not os.path.exists(customfile): 
            print 'not find',customfile,'ignore'
            return
        print 'loading',customfile
        lines=open(customfile).readlines()        
        self.addruletext(lines)

    def addrules(self,adblockurl):
        print 'loading',adblockurl
        html = urllib2.urlopen(adblockurl).readlines()
        self.addruletext(html)

    def addruletext(self,lines):
        for line in lines:
            rule=line.strip()
            if rule=='' or rule[0]=='!' or rule[0]=='[' : continue
            if rule.find('##')>=0: continue
            if rule.find('@@')==0:
                exception=True
                rule=rule[2:]
            else: exception=False
            rule=rule.replace('.','\\.')
            rule=rule.replace('?','\\?')
            rule=rule.replace('*','.*')
            rule=rule.replace('^','.')
            if rule.find('||')==0: rule='!!'+rule[2:]
            if rule[0]=='|': rule='^'+rule[1:]
            if rule[-1]=='|': rule=rule[:-1]+'$'
            rule=rule.replace('|','\\|')           
            if rule.find('!!')==0: rule='^http://(.*?\\.|)'+rule[2:]
            thirdrequst=False
            domain='.*'
            c=rule.find('$')
            if c>0:
               part=rule[c:]
               r=''
               if part.find('image')>=0:r=r+'|jpg|png|bmp|gif'
               if part.find('object')>=0:r=r+'|swf|jar'
               if part.find('script')>=0:r=r+'|js|vbs'
               if part.find('subdocment')>=0:r=r+'|.*'
               if part.find('subrequest')>=0:r=r+'|.*'
               if part.find('third-party')>=0:thirdrequst=True
               if part.find('domain=')>=0:
                  domain=part[part.find('domain=')+7:]
                  if domain.find(',')>=0: domain=domain[:domain.find(',')]
                  if domain.find('~')>=0: domain=domain.replace('~','.*\\.')
                  if domain.find('\\|')>=0: domain='('+domain.replace('\\|','|')+')'
               if r:r='.*('+r[1:]+')'
               rule=rule[:c]+r             
            if rule[-1]=='^': rule=rule[:-1]
            try:
               rule=re.compile(rule)
               domain=re.compile(domain)
            except:
               continue
#            print 'add:',rule.pattern,'domain:',domain.pattern,'from',line.strip()
            self.rules.append((rule,exception,thirdrequst,domain))

    def __init__(self):
        self.rules=[]
        self.addcustomrules("adblock.txt")
        self.addrules("http://easylist.adblockplus.org/easylist.txt")
        self.addrules("http://adblock-chinalist.googlecode.com/svn/trunk/adblock.txt")
        self.checkedurls={}

    def allowurl(self,url,referer,host):
        md5=hashlib.md5()
        md5.update(url)
        m=md5.hexdigest()
        if self.checkedurls.has_key(m): return self.checkedurls[m]
        for (rule,exception,thirdrequst,domain) in self.rules:
            if rule.search(url):
                self.checkedurls[m]=exception
                if domain.pattern <> '.*':
                   currdomain = urlparse.urlparse(url)[1]
                   if not domain.search(currdomain): continue
#                if not exception: print url,"block by",rule.pattern
                return exception
        if referer.find('forumdisplay.php') >=0 or referer.find('viewthread.php') >=0:
            if url.find('.js') or url.find('?') or url.find('.html'):
                if referer.find(host)==-1:
                    self.checkedurls[m]=False
                    return False
        self.checkedurls[m]=True
        return True   

adblock = Adblock()

class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    rbufsize = 0
    def do_CONNECT(self):
        try:
            if self.connect(self.path):
                self.log_request(200)
                self.wfile.write("HTTP/1.0 200 Connection established\r\n\r\n")
                self.read_write(100)
        finally:
            self.connection.close()
            self.soc.close()

    @exeTime  
    def do_GET(self):
        global adblock       
        try: referer=self.headers['Referer']
        except: referer=''
        if self.path[0:7]!='http://':
           self.url='http://'+self.headers['Host']+self.path
        else:
           self.url=self.path
           self.path=self.path[self.path.find('/',8):]
        
        if not adblock.allowurl(self.url,referer,self.headers['Host']):
            self.send_response(403, "ADBLOCK")
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            return

        try:
            if self.connect(self.headers['Host']):
#            if self.connect_socks5_proxy('127.0.0.1',1080,self.headers['Host']):
                self.log_request(200)
                firstline="%s %s %s\r\n" % (self.command,self.path,self.request_version)
                self.headers['Connection'] = 'close'
                del self.headers['Proxy-Connection']
                header=firstline+str(self.headers).strip()
                #print header
                self.soc.send(header)                
                self.soc.send("\r\n\r\n")
                if self.command!='GET' and self.headers.has_key('Content-Length'):
                   length=int(self.headers['Content-Length'])
                   while length>0:
                       data = self.connection.recv(8192)
                       self.soc.send(data)
                       length=length-len(data)
                self.read()
        finally:
            self.connection.close()
            self.soc.close()

    def connect_socks5_proxy(self,proxy_host,proxy_port,host):
        self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.soc.settimeout(10)
        self.soc.connect((proxy_host,proxy_port))
        self.soc.send("\x05\x01\x00")
        r = self.soc.recv(3)
        if r[0] != "\x05" or r[1] != "\x00":
           print "Socks Proxy Need Auth Connection failed!"
           return False
        i = host.find(':')
        if i >= 0:
           destaddr,destport = host[:i], int(host[i+1:])
        else:
           destaddr,destport = host, 80
        try:
           req = "\x05\x01\x00\x01"+ socket.inet_aton(destaddr)
        except:
           req = "\x05\x01\x00\x03" + chr(len(destaddr)) + destaddr 
        req = req + struct.pack(">H",destport)
        self.soc.send(req)
        r = self.soc.recv(4) 
        if r[0] != "\x05" or r[1] != "\x00":
           print "Socks Proxy Connection failed!"
           return False
        elif r[3] == "\x01":
           boundaddr=self.soc.recv(4)
        elif r[3] == "\x03":
           r=r+self.soc.recv(1)
           boundaddr=self.soc.recv(r[4])
        else: 
           return False
        boundport = struct.unpack(">H",self.soc.recv(2))[0]
        return True

    def connect(self, host):
        self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.soc.settimeout(10)
        i = host.find(':')
        try:
            if i >= 0:
                host_address = host[:i], int(host[i+1:])
            else:
                host_address = host, 80
            self.soc.connect(host_address)
            return True
        except:
            return False
    
    def read(self,maxcount=300):
        count = 0
        try:
            while count<=maxcount:
                count = count + 1
                (ins, _, exs) = select.select([self.soc], [], [], 30)
                if exs: break
                if len(ins)!=0:
                    for i in ins:
                        data = i.recv(8192)
                        if data:
                            self.connection.send(data)
                            count = 0
        except: pass

    def read_write(self, maxcount=300):
        iw = [self.connection, self.soc]
        count = 0
        try:
            while count<=maxcount:
                count = count + 1
                (ins, _, exs) = select.select(iw, [], iw, 30)
                if exs: break
                if len(ins)!=0:
                    for i in ins:
                        if i is self.soc:
                            out = self.connection
                        else:
                            out = self.soc
                        data = i.recv(8192)
                        if data:
                            out.send(data)
                            count = 0               
        except: pass

    do_HEAD=do_POST=do_PUT=do_OPTIONS=do_PROPFIND=do_REPORT=do_MKACTIVITY=do_PROPPATCH=do_CHECKOUT=do_MKCOL=do_MOVE=do_MOVE=do_COPY=do_DELETE=do_LOCK=do_UNLOCK=do_MERGE=do_GET
    

class ThreadingHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): pass

if __name__ == '__main__':
    server_address = ('0.0.0.0', 8080)
    httpd = ThreadingHTTPServer(server_address, ProxyHandler)
    print "ADBlock Proxy Server On %s:%d" % server_address
    httpd.serve_forever()
头像
hellojinjie
帖子: 1150
注册时间: 2007-09-14 21:03
来自: 浙江

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#6

帖子 hellojinjie » 2009-11-16 18:08

do_post没实现阿
Say hello to everyday!
头像
oneleaf
论坛管理员
帖子: 10441
注册时间: 2005-03-27 0:06
系统: Ubuntu 12.04

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#7

帖子 oneleaf » 2009-11-22 17:15

有实现啊,do_post=do_get
头像
hellojinjie
帖子: 1150
注册时间: 2007-09-14 21:03
来自: 浙江

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#8

帖子 hellojinjie » 2009-11-22 23:04

oneleaf 写了:有实现啊,do_post=do_get
我有看到这行代码的,,可是这样的话,,我记得在php中是用 $_POST["var"]来得到post的数据的,,这样可能在服务器端的php脚本可能就不会得到客户发过来的数据了,,,,,文件上传也是个问题阿 ...
Say hello to everyday!
头像
oneleaf
论坛管理员
帖子: 10441
注册时间: 2005-03-27 0:06
系统: Ubuntu 12.04

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#9

帖子 oneleaf » 2009-11-22 23:08

不会的,我是直接转发了head,然后再双向连接传数据,不会有这个问题,不信你试试就知了。
头像
hellojinjie
帖子: 1150
注册时间: 2007-09-14 21:03
来自: 浙江

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#10

帖子 hellojinjie » 2009-11-23 19:17

OK,设置好代理了...,发张图片上来试试,,,,
您没有权限查看这个主题的附件。
Say hello to everyday!
头像
hellojinjie
帖子: 1150
注册时间: 2007-09-14 21:03
来自: 浙江

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#11

帖子 hellojinjie » 2009-11-23 20:39

顺便了解了下 python 的 Mix-in ,,不过还是有点迷糊.. :em06
Say hello to everyday!
头像
jarryson
帖子: 4002
注册时间: 2005-08-14 19:53

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#12

帖子 jarryson » 2009-11-24 9:21

挖,这样什么浏览器都可以过滤广告了。。
xsunset
帖子: 7
注册时间: 2010-09-12 12:44

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#13

帖子 xsunset » 2010-09-12 17:46

python这么强大啊,不太懂那代码
头像
lainme
论坛版主
帖子: 7805
注册时间: 2008-09-13 19:17
系统: Arch Linux (x86_64)
联系:

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#14

帖子 lainme » 2010-09-14 10:23

还没看懂……或许可以用来代替foxyproxy,再加个代理切换功能的话
头像
hcym
帖子: 15634
注册时间: 2007-05-06 2:46

Re: [四星]写一个小代理软件,充分利用adblock-cn的规制

#15

帖子 hcym » 2010-09-14 10:40

cn的规制过滤

非常喜欢
:em04
وإذا كان هذا لا يحصل أكثر من 100 ملاحظات ، انا ذاهب الى غضب
回复