探究Python的Tornado框架對子域名和泛域名的支持
其實(shí)Tornado對子域名和泛域名(除了特別說明外,以下子域名和泛域名均簡稱為泛域名)的支持并不是什么新鮮事,兩年多前我用Tornado寫的開源網(wǎng)站 http://poweredsites.org 就有了對泛域名的支持,但是Tornado的官方文檔里并沒有明確對此功能進(jìn)行說明,雖然源代碼里是有注釋的,終是有點(diǎn)隱晦,這不,近日mywaiting同學(xué)就遇到了這個(gè)問題,我應(yīng)邀特撰此博文,分享下我對此的一點(diǎn)點(diǎn)經(jīng)驗(yàn)。
通常,用Tornado添加url映射路由表是直接傳handlers給Application這種方式的,比如官方的chatdemo:
class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler), (r"/auth/login", AuthLoginHandler), (r"/auth/logout", AuthLogoutHandler), (r"/a/message/new", MessageNewHandler), (r"/a/message/updates", MessageUpdatesHandler), ] settings = dict( cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", login_url="/auth/login", template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), xsrf_cookies=True, autoescape="xhtml_escape", ) tornado.web.Application.__init__(self, handlers, **settings)
這種方式其實(shí)添加的是一個(gè)域名通配的url映射表,即域名&子域名不限,只要訪問能夠解析到這個(gè)chatdemo上,“/auth/login” “/auth/login”這些url就都能夠正常運(yùn)行。假設(shè)www.feilong.me、abc.feilong.me、feilong2.me這個(gè)三個(gè)(子)域名均配置為可由這個(gè)chatdemo程序來host,那么訪問這三個(gè)(子)域名均可以正常使用這個(gè)chatdemo,總之域名是無關(guān)的。
實(shí)際上,這種方式它的內(nèi)部是通過Application里的這個(gè)add_handlers來實(shí)現(xiàn)的(原碼注釋如下):
def add_handlers(self, host_pattern, host_handlers): """Appends the given handlers to our handler list. Note that host patterns are processed sequentially in the order they were added, and only the first matching pattern is used. This means that all handlers for a given host must be added in a single add_handlers call. """
只不過它是隱式的調(diào)用這個(gè)add_handlers而已,其關(guān)鍵點(diǎn)就在于第一個(gè)參數(shù)host_pattern(匹配域名的)上,上面那種方式,默認(rèn)添加的host_pattern是”.*$”,即域名通配,若要支持泛域名,只需要顯式的調(diào)用add_handlers來添加相應(yīng)的host_pattern和handlers即可。
接下來就以poweredsites的源碼來介紹Tornado對泛域名的支持,app.py里的Application里面有這么幾句:
super(Application, self).__init__(handlers, **settings) # add handlers for sub domains for sub_handler in sub_handlers: # host pattern and handlers self.add_handlers(sub_handler[0], sub_handler[1])
常見的方式super(Application, self).__init__(handlers, **settings)添加的是根域名poweredsites的handlers,接著用for循環(huán)顯式添加的是子域名和泛域名的handlers。這里的sub_handlers依次放有各子域名的handlers,其最后一個(gè)是泛域名的handlers:
sub_handlers.append(site.sub_handlers) sub_handlers.append(blog.sub_handlers) sub_handlers.append(admin.sub_handlers) # wildcard subdomain handler for project should be the last one. sub_handlers.append(project.sub_handlers)
指定的子域名的sub_handlers(site.sub_handlers)是這個(gè)樣子的,這里的第一個(gè)元素就是host_pattern:
sub_handlers = ["^sites.poweredsites.org$", [ (r"/", _WebsiteIndexHandler), (r"/feeds", _WebsitesFeedsHandler), (r"/([a-z0-9]{32})", _WebsiteHandler), (r"/([^/]+)", WebsiteHandler), ] ]
泛域名(project.sub_handlers)的區(qū)別也就在于這第一個(gè)元素,即用來做host_pattern的是通配一些子域名的:
sub_handlers = ["^[a-zA-Z_\-0-9]*\.poweredsites.org$", [(r"/", ProjectIndexHandler), (r"/top", ProjectTopHandler), (r"/opensource", ProjectOpensourceHandler), ] ]
在用到了泛域名的ProjectIndexHandler里,運(yùn)行時(shí)具體的子域名就可以通過下面這樣的方式獲得:
class ProjectIndexHandler(ProjectBaseHandler): def get(self): subdomain = self.request.host.split(".")[0]
需要說明的是,Tornado里面的url映射表和Django一樣是有順序的,即url依次序由上到下匹配,只要匹配到就立即結(jié)束,不再往下匹配,而帶子域名和泛域名的url路由其匹配優(yōu)先級是要高于通配域名”.*$”的(這個(gè)不用你操心,add_handlers會自動為你做到這一點(diǎn))。同樣的,對于泛域名,因?yàn)槠渥佑蛎峭ㄅ涞模虼酥付ㄗ佑蛎膆andlers需要放到泛域名前添加,如admin、blog這類子域名的handlers要放在泛域名之前,這就是poweredsites里sub_handlers.append(project.sub_handlers)放到最后一條的原因,project這條是對應(yīng)泛域名的,http://tornado.poweredsites.org 就是靠這一條來實(shí)現(xiàn)的。
備注:需要支持泛域名,首先要你的域名解析支持泛域名。
轉(zhuǎn)載請注明出處:http://feilong.me/2012/08/wildcard-subdomain-support-in-tornado
相關(guān)文章
Python實(shí)現(xiàn)的NN神經(jīng)網(wǎng)絡(luò)算法完整示例
這篇文章主要介紹了Python實(shí)現(xiàn)的NN神經(jīng)網(wǎng)絡(luò)算法,結(jié)合完整實(shí)例形式分析了Python使用numpy、matplotlib及sklearn模塊實(shí)現(xiàn)NN神經(jīng)網(wǎng)絡(luò)相關(guān)算法實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2018-06-06利用Python實(shí)現(xiàn)斐波那契數(shù)列的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于如何利用Python實(shí)現(xiàn)斐波那契數(shù)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Python封裝成可帶參數(shù)的EXE安裝包實(shí)例
今天小編就為大家分享一篇Python封裝成可帶參數(shù)的EXE安裝包實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python機(jī)器學(xué)習(xí)應(yīng)用之支持向量機(jī)的分類預(yù)測篇
最近完成的一個(gè)項(xiàng)目用到了SVM,之前也一直有聽說支持向量機(jī),知道它是機(jī)器學(xué)習(xí)中一種非常厲害的算法。利用將近一個(gè)星期的時(shí)間學(xué)習(xí)了一下支持向量機(jī),把原理推了一遍,感覺支持向量機(jī)確實(shí)挺厲害的,這篇文章帶你了解它2022-01-01