This article mainly introduces the support of the Python Tornado framework for subdomain names and wildcard domain names. Tornado, as a typical asynchronous framework, is very popular among Python developers, for more information, see Tornado's support for subdomain names and wildcard Domain Names (except in particular, the following subdomain names and wildcard domain names are referred to as wildcard domain names, more than two years ago, I used Tornado to write open-source website http://poweredsites.org with support for wildcard domain names, but Tornado's official documentation does not explicitly describe this function, although there are comments in the source code, it is a bit obscure. No, recently mywaiting encountered this problem. I was invited to write this blog and share my experience on it.
Generally, adding a url ing route table using Tornado directly transmits handlers to the Application, such as the official 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)
In this way, a url ing table with wildcard domain names is added, that is, the domain name and subdomain name are not limited, as long as the access can be resolved to this chatdemo, "/auth/login" "/auth/login" URLs can all run normally. Suppose www. feilong. me, abc. feilong. the three subdomains me and feilong2.me are configured as the host of the chatdemo program. Therefore, the chatdemo can be used normally for accessing these three subdomains, in short, the domain name is irrelevant.
In fact, in this way, it is implemented internally through the add_handlers in the Application (the original code comment is as follows ):
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. """
It only implicitly calls this add_handlers. The key point is that the first parameter host_pattern (matching the domain name). In the above method, the default host_pattern is ". * $ ", that is, wildcard domain name configuration. To support wildcard domain names, you only need to explicitly call add_handlers to add the corresponding host_pattern and handlers.
Next we will introduce Tornado's support for wildcard domain names with the source code of poweredsites. The Application in app. py contains the following statements:
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])
The common method is super (Application, self ). _ init _ (handlers, ** settings) adds the handlers of the root domain poweredsites, and then explicitly adds the handlers of the subdomain name and wildcard domain name with the for loop. Here, the sub_handlers contains the handlers of each sub-domain name, and the last one is the handlers of the wildcard Domain Name:
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)
The sub_handlers (site. sub_handlers) of the specified subdomain name is like this. The first element here is host_pattern:
sub_handlers = ["^sites.poweredsites.org$", [ (r"/", _WebsiteIndexHandler), (r"/feeds", _WebsitesFeedsHandler), (r"/([a-z0-9]{32})", _WebsiteHandler), (r"/([^/]+)", WebsiteHandler), ] ]
The difference between a wildcard domain name (project. sub_handlers) is that this first element is used to configure host_pattern with some subdomain names:
sub_handlers = ["^[a-zA-Z_\-0-9]*\.poweredsites.org$", [(r"/", ProjectIndexHandler), (r"/top", ProjectTopHandler), (r"/opensource", ProjectOpensourceHandler), ] ]
In ProjectIndexHandler with a wildcard domain name, the specific subdomain name during runtime can be obtained through the following method:
class ProjectIndexHandler(ProjectBaseHandler): def get(self): subdomain = self.request.host.split(".")[0]
It should be noted that the url ing table in Tornado is in the same order as Django, that is, the url matches from top to bottom in order, and ends immediately as long as it matches, no further matching is performed, the matching priority of the url Routing Between the domain name and the wildcard domain name is higher than that of the wildcard domain name ". * $ "(you don't have to worry about this. add_handlers will automatically do this for you ). Similarly, for wildcard domain names, because their subdomain names are wildcard, handlers of the subdomain names must be added before the wildcard domain names, for example, the handlers of sub-domain names such as admin and blog should be placed before the wildcard domain name, which is sub_handlers.append (project. sub_handlers) put to the last reason, the project is corresponding to the wildcard domain name, http://tornado.poweredsites.org is achieved by this one.
Note: To support wildcard domain names, you must first support wildcard domain name resolution.
Reprinted please indicate the source: http://feilong.me/2012/08/wildcard-subdomain-support-in-tornado