MITMProxy:智能URL替换

时间:2014-07-22 11:37:35

标签: python mitmproxy

我们使用自定义刮刀,必须为某种语言设置一个单独的网站(这是一种架构限制)。像site1.co.uk,site1.es,site1.de等

但我们需要解析一个网站,其中包含多个语言,分隔为url,例如site2.com / site2,de,2,web2等。

我想到了MITMProxy:我可以用这种方式重定向所有请求:

en.site2.com/* --> site2.com/en
de.site2.com/* --> site2.com/de
...

我编写了一个小脚本,它只需要URL并重写它们:

class MyMaster(flow.FlowMaster):

  def handle_request(self, r):
    url = r.get_url()

    # replace URLs
    if 'blabla' in url:
      r.set_url(url.replace('something', 'another'))

但目标主机使用来自网络服务器的响应生成301重定向 - '页面已移至此处'以及指向site2.com/en的链接

当我使用URL重写时,它起了作用,即site2.com/en - > site2.com/de。 但对于不同的主机(子域和根域,确切地说),它不起作用。

我尝试从上面替换handle_request方法中的Host头:

for key in r.headers.keys():
        if key.lower() == 'host':
            r.headers[key] = ['site2.com']

我也尝试更换推荐人 - 所有这些都无济于事。

我怎样才能最终将子域中的请求欺骗到主域?如果它生成HTTP(s)客户端警告它没关系,因为我们需要刮板(并且警告可以关闭),而不是真正的浏览器。

谢谢!

1 个答案:

答案 0 :(得分:0)

您需要替换响应的内容并使用几个字段制作标题。 打开与重定向网址的新连接并制作响应:

def handle_request(self, flow):
  newUrl = <new-url>
  retryCount = 3
  newResponse = None
  while True:
    try:
      newResponse = requests.get(newUrl) # import requests
    except: 
      if retryCount == 0:
        print 'Cannot reach new url ' + newUrl
        traceback.print_exc() # import traceback
        return

      retryCount -= 1
      continue
    break

  responseHeaders = Headers() # from netlib.http import Headers

  if 'Date' in newResponse.headers:
    responseHeaders['Date'] = str(newResponse.headers['Date'])
  if 'Connection' in newResponse.headers:
    responseHeaders['Connection'] = str(newResponse.headers['Connection'])
  if 'Content-Type' in newResponse.headers:
    responseHeaders['Content-Type'] = str(newResponse.headers['Content-Type'])
  if 'Content-Length' in newResponse.headers:
    responseHeaders['Content-Length'] = str(newResponse.headers['Content-Length'])
  if 'Content-Encoding' in newResponse.headers:
    responseHeaders['Content-Encoding'] = str(inetResponse.headers['Content-Encoding'])

  response = HTTPResponse(   # from libmproxy.models import HTTPResponse
    http_version='HTTP/1.1',
    status_code=200,
    reason='OK',
    headers=responseHeaders,
    content=newResponse.content)

  flow.reply(response)