<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
    <channel>
        <title>Silas Sewell - December 2009</title>
        <atom:link href="http://www.silassewell.com/blog/2009/12/rss2.xml" rel="self" type="application/rss+xml" />
        <link>http://www.silassewell.com/blog/2009/12</link>
        <description>Infrastructure Development</description>
        <lastBuildDate>Sat, 21 Aug 2010 00:00:00 GMT</lastBuildDate>
        <generator>http://www.silassewell.com/</generator>
        <language>en</language>
        <sy:updatePeriod>hourly</sy:updatePeriod>
        <sy:updateFrequency>1</sy:updateFrequency>

        <item>
            <title>Google App Engine Middleware (gaem)</title>
            <link>http://www.silassewell.com/blog/2009/12/29/google-app-engine-middleware-gaem/</link>
            <pubDate>Tue, 29 Dec 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Fedora]]></category><category><![CDATA[gaem]]></category><category><![CDATA[Google]]></category><category><![CDATA[Google App Engine]]></category><category><![CDATA[Projects]]></category><category><![CDATA[Python]]></category><category><![CDATA[Reverse Proxy]]></category><category><![CDATA[Software]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/12/29/google-app-engine-middleware-gaem/</guid>
            <description><![CDATA[<p><a href="http://github.com/silas/gaem" title="Google App Engine Middleware">Google App Engine Middleware</a> (gaem) is a collection of utilities for
hosting external sites on Google App Engine.</p>

<p>I created gaem because I wanted to host my blog on an unreliable server and let
Google App Engine serve the content while my server was down or in maintenance
mode.</p>

<p>The basic design is similar to that of <a href="http://docs.djangoproject.com/en/dev/topics/http/middleware/" title="Django's middleware">Django's middleware</a>. A request
travels through a list of components which can either manipulate the request or
provide a response. The response is filtered back through the components and
served to the requester.</p>

<p>A basic implementation looks something like</p>

<pre><code class="prettyprint">import gaem
import gaem.middleware
import gaem.middleware.cache
import gaem.middleware.dos
import gaem.middleware.fetch

URL = 'http://www.example.org'

MIDDLEWARE_CLASSES = (
    gaem.middleware.cache.Memcache(),
    gaem.middleware.cache.Datastore(),
    gaem.middleware.dos.DoS(),
    gaem.middleware.fetch.Fetch(url=URL),
)

application = gaem.Application(MIDDLEWARE_CLASSES)

if __name__ == '__main__':
    application.run()
</code></pre>

<p>When a request first hits this application it is handled by the Memcache
component. This basic caching component checks the Google App Engine Memcache
service to see if the page is in the cache. If so it simply returns the cached
response, otherwise the request proceeds to the Datastore component which does
pretty much the same thing except it uses Google Datastore for persistence. If
both caching components fail the the request goes through a DoS protection
component and is finally retrieved from the backend server by the Fetch
component.</p>

<p>Using a setup like this gaem acts as a rudimentary reverse proxy and while most
of the functionality I've implemented thus far is for this type setup, I plan
on adding features not traditionally found in a reverse proxy.</p>

<h3>Current Features</h3>

<ul>
<li><a href="http://github.com/silas/gaem/blob/a9d187f65229796c1e92b479735f215c4f1e7000/gaem/middleware/cache.py" title="Caching">Caching</a></li>
<li><a href="http://github.com/silas/gaem/blob/a9d187f65229796c1e92b479735f215c4f1e7000/gaem/middleware/fetch.py" title="Backend fetch">Backend fetch</a></li>
<li>Gracefully handle a dead backend</li>
<li><a href="http://github.com/silas/gaem/blob/a9d187f65229796c1e92b479735f215c4f1e7000/gaem/middleware/dos.py" title="DoS protection">DoS protection</a></li>
<li><a href="http://github.com/silas/gaem/blob/a9d187f65229796c1e92b479735f215c4f1e7000/gaem/middleware/api.py" title="API for expiring content">API for expiring content</a></li>
</ul>

<h3>Possible Future Features</h3>

<ul>
<li>Initial and periodic crawler (pre-cache and other hooks)</li>
<li>RESTful API for managing content (put, delete, etc...)</li>
<li>Web interface</li>
<li>XSS protection</li>
<li>Some ESI support</li>
</ul>

<p>But what makes gaem really cool for developers is how easy it is to create
custom components.</p>

<p>A basic component looks like</p>

<pre><code class="prettyprint">from gaem import middleware

class DoesNothing(middleware.Base):

    def process_request(self, request):
        return request

    def process_response(self, response, request):
        return response
</code></pre>

<p>A default gaem component should inherit from <code class="prettyprint">gaem.middleware.Base</code> and
implement <code class="prettyprint">process_request</code> and/or <code class="prettyprint">process_response</code>.</p>

<p>The <code class="prettyprint">process_request</code> function lets you either manipulate the request (ex:
strip the "cookie" header) and pass it along or use the request to create and
return a response (ex: do a fetch to the backend server). The
<code class="prettyprint">process_response</code> function lets you filter the response (ex: translate body
into pig latin) and do side affects (ex: store response in memcache) before the
response is sent to the requester.</p>

<p>The Request/Response objects are borrowed from <a href="http://pythonpaste.org/webob/" title="WebOb">WebOb</a> and can be
manipulated using the interfaces defined in the <a href="http://pythonpaste.org/webob/modules/webob.html" title="WebOb documentation">WebOb documentation</a>.</p>

<p>gaem is currently pretty rough and likely to change over the next couple of
months, but if you're a Python hacker I'd love to hear some feedback
(<a href="http://www.silassewell.com/about/contact/" title="Contact Silas Sewell">contact me</a> or <a href="http://github.com/silas/gaem/issues" title="gaem issues">submit an issue</a>).</p>

<p>P.S. You can see the application I created for this site in the <a href="http://github.com/silas/gaem/tree/master/examples/wordpress/" title="gaem WordPress example">examples directory</a>.</p>]]></description>
        </item>

    </channel>
</rss>