Last active
August 29, 2015 14:24
-
-
Save exosgenesis/dbd3cb410ec73b12611b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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