WSGIã§ä½ãç°¡åãã¼ã«ã«HTTP Proxyãµã¼ã
åæã¨ãã¦ã¯ã
- 社å ã®Wiki(ä»®ã«intra.example.comã¨ãã)ã«ã¯å¤é¨ããç´æ¥ã¢ã¯ã»ã¹ã§ããªã
- ã²ã¼ãã¦ã§ã¤(ä»®ã«gw.example.comã¨ãã)ã«ã¯sshæ¥ç¶ã§ãã
- ãã¼ãPCã使ã£ã¦ãã¦ãé »ç¹ã«LANã®å é¨ã¨å¤é¨ãè¡ãæ¥ãã
ã¨ããç¶æ³ã§ãã©ãããã§ã社å ã®Wikiãè¦ãããããã«ãããã
SSHã®ãã¼ããã©ã¯ã¼ãã£ã³ã°ã ãã ã¨ãhttp://localhost:8088/ã¿ãããªURLã§ã¢ã¯ã»ã¹ãããã¨ã«ãªãã®ã§ããªã³ã¯ã辿ããªãã£ãããVirtualHostã使ã£ã¦ããå ´åã¯hostsãæ¸ãæããå¿ è¦ããã£ãããã¦é¢åã
SOCKSã¨ãDynamicDNSã¨ã調ã¹ããã©ãããããããæ¢åã®HTTP Proxyãµã¼ãã§ã¯ã¡ããã©è¯ããã®ããªãã£ãã®ã§ãèªåã§ä½ããã¨ã«ããã
幸ãWSGIã«ã¯å¿
è¦ãªé¨åã¯æã£ã¦ããã®ã§ããã¨ã¯ãããçµã¿åãããã ãã
virtualenvç°å¢ã®æ§ç¯ã¨ããã¸ã§ã¯ãã®ã²ãªå½¢çæ
$ python virtualenv.py --no-site-packages TinyWSGIProxy $ cd TinyWSGIProxy $ . bin/activate (TinyWSGIProxy)$ easy_install Paste (TinyWSGIProxy)$ easy_install PasteScript (TinyWSGIProxy)$ paster create -t paste_deploy TinyWSGIProxy Selected and implied templates: PasteScript#basic_package A basic setuptools-enabled package PasteDeploy#paste_deploy A web application deployed through paste.deploy Variables: egg: TinyWSGIProxy package: tinywsgiproxy project: TinyWSGIProxy Enter version (Version (like 0.1)) ['']: Enter description (One-line description of the package) ['']: Enter long_description (Multi-line description (in reST)) ['']: Enter keywords (Space-separated keywords/tags) ['']: Enter author (Author name) ['']: Enter author_email (Author email) ['']: Enter url (URL of homepage) ['']: Enter license_name (License name) ['']: Enter zip_safe (True/False: if the package can be distributed as a .zip file) [False]: Creating template basic_package Creating directory ./TinyWSGIProxy Recursing into +package+ Creating ./TinyWSGIProxy/tinywsgiproxy/ Copying __init__.py to ./TinyWSGIProxy/tinywsgiproxy/__init__.py Copying setup.cfg to ./TinyWSGIProxy/setup.cfg Copying setup.py_tmpl to ./TinyWSGIProxy/setup.py Creating template paste_deploy Recursing into +package+ Copying sampleapp.py_tmpl to ./TinyWSGIProxy/tinywsgiproxy/sampleapp.py Copying wsgiapp.py_tmpl to ./TinyWSGIProxy/tinywsgiproxy/wsgiapp.py Recursing into docs Creating ./TinyWSGIProxy/docs/ Copying devel_config.ini_tmpl to ./TinyWSGIProxy/docs/devel_config.ini Updating ./TinyWSGIProxy/setup.py Updating ./TinyWSGIProxy/setup.py ************************************************************************ * Run "paster serve docs/devel_config.ini" to run the sample application * on http://localhost:8080 ************************************************************************ Running /Users/nozom/work/TinyWSGIProxy/bin/python setup.py egg_info Adding PasteDeploy to paster_plugins.txt (TinyWSGIProxy)$ cd TinyWSGIProxy
tinywsgiproxy/wsgiapp.py
from paste.proxy import TransparentProxy from sqlalchemy import engine_from_config import model class ProxyAdmin(object): def __call__(self, environ, start_response): query = model.HostNameMapping.query.filter_by(enabled=True) mapping = query.filter_by(hostname=environ["HTTP_HOST"]).first() if mapping: proxy = TransparentProxy(force_host=mapping.mapped) else: proxy = TransparentProxy() return proxy(environ, start_response) def make_app(global_conf, **kw): # Here we merge all the keys into one configuration # dictionary; you don't have to do this, but this # can be convenient later to add ad hoc configuration: conf = global_conf.copy() conf.update(kw) # Setup model model.metadata.bind = engine_from_config(conf, 'sqlalchemy.') model.setup_all() # model.create_all() # This is a WSGI application: app = ProxyAdmin() return app
tinywsgiproxy/model.py
from elixir import * __all__ = ["HostNameMapping"] class HostNameMapping(Entity): using_options(shortnames=True) hostname = Field(String(255), unique=True) mapped = Field(String(255)) enabled = Field(Boolean)
development.ini
[DEFAULT] [filter-app:main] # This puts the interactive debugger in place: use = egg:Paste#evalerror next = devel [app:devel] # This application is meant for interactive development use = egg:TinyWSGIProxy sqlalchemy.url = sqlite:////%(here)s/data.db filter-with = log [filter:log] use = egg:Paste#translogger [app:test] # While this version of the configuration is for non-iteractive # tests (unit tests) use = devel [server:main] use = egg:Paste#http # Change to 0.0.0.0 to make public: host = 127.0.0.1 port = 8088
- DBã®ã»ããã¢ãã
(TinyWSGIProxy)$ easy_install Elixir (TinyWSGIProxy)$ easy_install pysqlite (TinyWSGIProxy)$ python >>> from sqlalchemy import create_engine >>> import tinywsgiproxy.model >>> tinywsgiproxy.model.metadata.bind = create_engine('sqlite:///data.db') >>> tinywsgiproxy.model.setup_all() >>> tinywsgiproxy.model.create_all()
CRUDæ©è½ã¯ãªãã®ã§ã³ãã³ãã©ã¤ã³ãããã¼ã¿ãå ¥åããã
$ sqlite3 sqlite> insert into hostnamemapping (id, hostname, mapped, enabled) values (1, "intra.example.com", "localhost:40080", 1); sqlite> .quit
å®è¡
(TinyWSGIProxy)$ paster serve --reload development.ini
å¥ã®ã¿ã¼ããã«ã§
$ ssh -L 40080:intra.example.com:80 gw.example.com
ãå®è¡ãã¦ããã¦ããã©ã¦ã¶ã®ãããã·è¨å®ãlocalhost:8088ã«å¤æ´ããã
http://intra.example.com/ã«ã¢ã¯ã»ã¹ããã¨ããããã·çµç±ã§ãã¼ã¸ã表示ãããããã«ãªãã¾ãã