Canonical Redirects with Google App Engine

It is currently possible to associate multiple URLs with your App Engine instance. However, the administration interface doesn't permit configuring any redirects.

However, the Administration interface doesn't allow you to configure any redirects, which could lead to major search engines associating your domains with duplicate content.

I'm going to cover how I enabled canonical redirects in Google App Engine as I would have normally done with Apache and mod_rewrite.

This will allow you to redirect the www sub-domain to the non-www domain, or the non-www domain to the www sub-domain -- whichever one you've standardized on.

I solved this by creating two application instances, and then calling wsgiref.handlers.CGIHandler().run(application) on one or the other if the request came in for a domain that contained www or not.

The WSGIApplication method takes two parameters and returns an application instance. The first a list of regular expressions and the Request Handlers they map to, and the second a boolean to set the debug status to on or off. I'm going to exploit this and create one application instance that maps everything to a redirect request handler, and the other "production" application instance which contains the various production mappings such as "/", and "/about"...etc

In your main.py, the main() method should contain the following. First import required modules, then pluck out the host name from the environment, then do a simple regex on it.

import os
import re
host_name = os.environ['HTTP_HOST']
m = re.match('www', hostname)
if m:
  application = webapp.WSGIApplication(
                         [('(.*)', CanonicalRedirectHandler),], 
                           False)
else:
  application = webapp.WSGIApplication(_PRODUCTION_URLS, False)

wsgiref.handlers.CGIHandler().run(application)

The redirect method (webapp.RequestHandler.redirect() ) takes two parameters, the URI to redirect to, and a boolean to indicate whether or not the redirect is permanent (HTTP 301) or temporary (HTTP 302).

class CanonicalRedirectHandler(webapp.RequestHandler):
  def get(self,path):
    self.redirect("http://yourdomain.com%s" % (path), True)

That's that. A fairly workable solution. Something is nagging at me, and I wonder if there is a more elegant solution to this within the App Engine framework. If so please let me know in the comments section.