Skip to content

Instantly share code, notes, and snippets.

@exosgenesis

exosgenesis/magicproxy.py

Last active Aug 29, 2015
Embed
What would you like to do?
# coding=utf-8
# magicproxy.py — это простейший http-прокси-сервер, запускаемый локально
# (порт на ваше усмотрение), который показывает содержимое страниц Хабра. С
# одним исключением: после каждого слова из шести букв должен стоять
# значок «™». Примерно так:
#
# http://habrahabr.ru/company/yandex/blog/258673/
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Сейчас на фоне уязвимости Logjam все в индустрии в очередной раз обсуждают
# проблемы и особенности TLS. Я хочу воспользоваться этой возможностью, чтобы
# поговорить об одной из них, а именно — о настройке ciphersiutes.
#
# http://127.0.0.1:8232/company/yandex/blog/258673/
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Сейчас™ на фоне уязвимости Logjam™ все в индустрии в очередной раз обсуждают
# проблемы и особенности TLS. Я хочу воспользоваться этой возможностью, чтобы
# поговорить об одной из них, а именно™ — о настройке ciphersiutes.
#
# Условия:
# * Python 2.x
# * можно использовать любые общедоступные библиотеки, которые сочтёте
# нужным
# * чем меньше кода, тем лучше. PEP8 — обязательно
# * в случае, если не хватает каких-то данных, следует опираться на здравый
# смысл
#
# Если задача кажется слишом простой, можно добавить следующее:
# * параметры командной строки (порт, хост, сайт, отличный от хабра и т.п.)
# * после старта локального сервера автоматически запускается браузер с
# открытой обработанной™ главной страницей
import re
import requests
import webbrowser
import sys
from flask import Flask, Response
from bs4 import BeautifulSoup, NavigableString, Tag
app = Flask(__name__)
url_root = 'http://habrahabr.ru'
local_host = '127.0.0.1'
local_port = '5000'
launch_browser = False
show_help = False
def apply_changes(changes):
for nav_str, new_value in changes:
nav_str.replace_with(new_value)
def add_change(change_list, changer, nav_string):
origin = unicode(nav_string)
changed = changer.sub(ur"\g<start>\g<word>™\g<end>", origin)
if changed is not origin:
change_list.append((nav_string, changed))
def pass_childs(func, el, unresolved_tags):
for child in el.contents:
if isinstance(child, Tag) and child.name not in unresolved_tags:
func(child)
pass_childs(func, child, unresolved_tags)
elif not isinstance(child, Tag):
func(child)
def processed_content(html_content):
soup = BeautifulSoup(html_content, 'html.parser')
changer = re.compile(ur'(?P<start>\A|[^\w]|\b)'
ur'(?P<word>\w{6})'
ur'(?P<end>\Z|[^\w]|\b)', re.U)
change_list = []
def process_el(el):
if isinstance(el, Tag) and 'href' in el.attrs:
url_proxy = 'http://%s:%s' % (local_host, local_port)
el['href'] = el['href'].replace(url_root, url_proxy)
elif isinstance(el, NavigableString):
add_change(change_list, changer, el)
pass_childs(process_el, soup, 'script,style,head'.split(','))
apply_changes(change_list)
return str(soup)
@app.route('/', defaults={'path': ''})
@app.route("/<path:path>")
def catch_all(path):
url = url_root + '/' + path
response = requests.get(url)
if 'text/html' in response.headers['Content-Type']:
content = processed_content(response.content)
else:
content = response.content
return Response(content, content_type=response.headers['Content-Type'])
def print_help():
print """
usage: magicproxy.py [parameter:value] [option]
Parameters:
/port - port to use [default %s]
/target - target site [default %s]
/host - localhost [default %s]
Options:
--browser - launch browser on startup [default %s]
--help - see this help
""" % (local_port, url_root, local_host, launch_browser)
if __name__ == "__main__":
for arg in sys.argv[1:]:
if arg == '--browser':
launch_browser = True
elif arg == '--help':
show_help = True
elif arg.startswith('/port:'):
local_port = arg[6:]
elif arg.startswith('/host:'):
local_host = arg[6:]
elif arg.startswith('/target:'):
url_root = arg[8:]
else:
print "Error! Unknown parameter or option ", arg
exit()
if show_help:
print_help()
exit()
if launch_browser:
webbrowser.open('http://%s:%s' % (local_host, local_port), new=2)
app.run(host=local_host, port=int(local_port))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.