<?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>Jython Journeys &#187; web technology</title>
	<atom:link href="http://jython.xhaus.com/tag/web-technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://jython.xhaus.com</link>
	<description>Notes about my work with jython and python</description>
	<lastBuildDate>Tue, 01 Dec 2009 19:37:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Transforming with XSLT on Google AppEngine and jython.</title>
		<link>http://jython.xhaus.com/transforming-with-xslt-on-google-appengine-and-jython/</link>
		<comments>http://jython.xhaus.com/transforming-with-xslt-on-google-appengine-and-jython/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 18:42:26 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[google appengine]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[java scripting]]></category>
		<category><![CDATA[web technology]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=171</guid>
		<description><![CDATA[I&#8217;m writing this post in response to a challenge. I wrote a post entitled Jython on Google AppEngine: Why bother?, which was a reply to a statement made by a Google engineer about not seeing the point of running jython on AppEngine. And a similar statement was repeated in a comment on that blog post [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing this post in response to a challenge. I wrote a post entitled <a href="http://jython.xhaus.com/jython-on-google-appengine-why-bother/">Jython on Google AppEngine: Why bother?</a>, which was a reply to a statement made by a Google engineer about not seeing the point of running jython on AppEngine. And a similar statement was repeated in a <a href="http://jython.xhaus.com/jython-on-google-appengine-why-bother/#comments">comment on that blog post</a> (i.e. &#8220;<i>the gist of what I intended to say was that while it was possible to run Jython on App Engine, I couldn’t think why you’d want to</i>.&#8221;)</p>
<p>So rather than get into a back-and-forth of yes-it-is-no-it-isnt-yes-it-is, I thought I&#8217;d reply with some simple code that demonstrates <b>something that cannot (currently) be done in cpython on AppEngine</b>, but is <b>easy with jython on AppEngine</b>: XSLT transforms. </p>
<p><span id="more-171"></span></p>
<p>So, without further ado, here is the jython source code for running an XSLT transform on Google AppEngine. It is implemented as a jython WSGI application, using xhaus.com&#8217;s <a href="http://modjy.xhaus.com">modjy WSGI gateway for java servlets</a> that was <a href="http://jython.xhaus.com/modjy-now-fully-integrated-into-jython/">contributed to the jython project a few months back</a>.</p>
<p>In order to get this code running, I suggest you download the <a href="http://downloads.xhaus.com/modjy_webapp_google_appengine/">modjy on google appengine demo</a> from our <a href="http://downloads.xhaus.com">downloads site</a>. In that download, there is a jython file called &#8220;demo_app.py&#8221;. Simply replace the entire contents of that file with the code below, and you&#8217;re good to go. If you need help with getting the modjy demo application working on Google AppEngine, see the documentation on the modjy wiki: <a href="http://opensource.xhaus.com/projects/modjy/wiki/ModjyGoogleAppEngine">Running jython WSGI applications on Google AppEngine, with modjy</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">__doc__ = <span style="color: #483d8b;">&quot;&quot;&quot;
A demonstration of how to run XSLT transforms on Google AppEngine with jython (not cpython).
Please feel free to use this code in whatever way you wish.
&quot;&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">from</span> java.<span style="color: black;">io</span> <span style="color: #ff7700;font-weight:bold;">import</span> StringReader, StringWriter
<span style="color: #ff7700;font-weight:bold;">from</span> javax.<span style="color: #dc143c;">xml</span>.<span style="color: black;">transform</span> <span style="color: #ff7700;font-weight:bold;">import</span> Transformer, TransformerFactory
<span style="color: #ff7700;font-weight:bold;">from</span> javax.<span style="color: #dc143c;">xml</span>.<span style="color: black;">transform</span>.<span style="color: black;">stream</span> <span style="color: #ff7700;font-weight:bold;">import</span> StreamResult, StreamSource
&nbsp;
xml_data = <span style="color: #483d8b;">&quot;&quot;&quot;
&lt;books&gt;
  &lt;book&gt;
    &lt;title&gt;2001 - A Space Odyssey&lt;/title&gt;
    &lt;author&gt;Arthur C Clarke&lt;/author&gt;
  &lt;/book&gt;
  &lt;book&gt;
    &lt;title&gt;I, Robot&lt;/title&gt;
    &lt;author&gt;Isaac Asimov&lt;/author&gt;
  &lt;/book&gt;
  &lt;book&gt;
    &lt;title&gt;Kil'n people&lt;/title&gt;
    &lt;author&gt;David Brin&lt;/author&gt;
  &lt;/book&gt;
&lt;/books&gt;
&quot;&quot;&quot;</span>
&nbsp;
xslt_source = <span style="color: #483d8b;">&quot;&quot;&quot;
&lt;xsl:stylesheet
  xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
&gt;
&nbsp;
&lt;xsl:template match=&quot;books&quot;&gt;
&lt;html&gt;
  &lt;head&gt;&lt;title&gt;A list of books, transformed into html from xml using xslt and jython.&lt;/title&gt;&lt;/head&gt;
  &lt;body&gt;
    &lt;table border=&quot;1&quot; width=&quot;50%&quot; align=&quot;center&quot;&gt;
      &lt;caption&gt;A list of books, transformed into html from xml using xslt and jython.&lt;/caption&gt;
      &lt;tr&gt;&lt;th&gt;Title&lt;/th&gt;&lt;th&gt;Author&lt;/th&gt;&lt;/tr&gt;
    &lt;xsl:for-each select=&quot;book&quot;&gt;
      &lt;tr&gt;&lt;td&gt;&lt;xsl:value-of select=&quot;title/text()&quot;/&gt;&lt;/td&gt;&lt;td&gt;&lt;xsl:value-of select=&quot;author/text()&quot;/&gt;&lt;/td&gt;&lt;/tr&gt;
    &lt;/xsl:for-each&gt;
    &lt;/table&gt;
  &lt;/body&gt;
&lt;/html&gt;
&lt;/xsl:template&gt;
&nbsp;
&lt;/xsl:stylesheet&gt;
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> generate_html<span style="color: black;">&#40;</span>xml_data, xslt_source<span style="color: black;">&#41;</span>:
  transformer = TransformerFactory.<span style="color: black;">newInstance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">newTransformer</span><span style="color: black;">&#40;</span>StreamSource<span style="color: black;">&#40;</span>StringReader<span style="color: black;">&#40;</span>xslt_source<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  output_buffer = StringWriter<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  transformer.<span style="color: black;">transform</span><span style="color: black;">&#40;</span>StreamSource<span style="color: black;">&#40;</span>StringReader<span style="color: black;">&#40;</span>xml_data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, StreamResult<span style="color: black;">&#40;</span>output_buffer<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> output_buffer.<span style="color: black;">buffer</span>.<span style="color: black;">toString</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> handler<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span>:
  result = generate_html<span style="color: black;">&#40;</span>xml_data, xslt_source<span style="color: black;">&#41;</span>
  start_response<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;200 Hoopy&quot;</span>, <span style="color: black;">&#91;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'content-type'</span>, <span style="color: #483d8b;">'text/html'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span>result<span style="color: black;">&#93;</span></pre></div></div>

<p>Happy Transforming!</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/transforming-with-xslt-on-google-appengine-and-jython/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Jython on Google AppEngine: Why bother?</title>
		<link>http://jython.xhaus.com/jython-on-google-appengine-why-bother/</link>
		<comments>http://jython.xhaus.com/jython-on-google-appengine-why-bother/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 14:40:09 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[google appengine]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[java scripting]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=160</guid>
		<description><![CDATA[Why on earth would you want to run jython applications on Google Appengine?

First off, I must apologise for the flippant nature of the attention grabbing title. I&#8217;m a jython committer, and a jython user, so I believe that there are very good reasons for running jython on Google AppEngine. (You can read how to do [...]]]></description>
			<content:encoded><![CDATA[<p>Why on earth would you want to run <a href="http://www.jython.org">jython</a> applications on <a href="http://appengine.google.com">Google Appengine</a>?</p>
<p><span id="more-160"></span></p>
<p>First off, I must apologise for the flippant nature of the attention grabbing title. I&#8217;m a jython committer, and a jython user, so I believe that there are very good reasons for running jython on Google AppEngine. (You can read how to do so on the modjy wiki: <a href="http://opensource.xhaus.com/projects/modjy/wiki/ModjyGoogleAppEngine">how to run jython applications on Google AppEngine</a>).</p>
<p>The title is essentially a paraphrase of a statement made by a Google AppEngine Evangelist, at a talk about AppEngine that I attended here in Dublin. The speaker was of the opinion that there was no valid reason for running jython on AppEngine, a statement which I couldn&#8217;t let pass.</p>
<p>I think that the core of his reasoning for making that statement was a simple misunderstanding, but a misunderstanding that is common among users who are familiar with python, or users of cpython, but who are not familiar with jython&#8217;s use as a <a href="http://www.javaworld.com/javaworld/jw-11-2007/jw-11-jsr223.html">JVM scripting language</a>. The misunderstanding is that the only reason for running jython is so that one can run python applications on the JVM, using python&#8217;s wealth of &quot;batteries included&quot; APIs. If that is the case, then why bother running jython, when one can simply use the <a href="http://code.google.com/appengine/docs/python/gettingstarted/">cpython support on AppEngine</a> directly?</p>
<p>To explain, when writing a cpython application that processes email, for example, one can make use of the python&#8217;s <a href="http://docs.python.org/library/email.html">email module</a>, which provides a wealth of features for dealing with the many complexities of parsing, processing and generating email messages, MIME, etc. Users of jython can also use the python email modules, since those modules are written in pure python. But since jython runs on the Java Virtual Machine(JVM) and permits seamless integration of java and python code, jython users writing email processing also have the option of using the excellent <a href="http://java.sun.com/products/javamail/">JavaMail APIs</a>, which are just as robust as the pure python modules, and arguably more efficient. So jython users have the best of both worlds: they can use either python APIs or java APIs, with equal ease.</p>
<p>Processing email is perhaps too straightforward an example, in that both python and java have excellent email processing support. But due to the more widespread use of java in the development community in general, java generally has far more support for any given technology need, since there are often multiple options available. A good example of this is cryptography: there is a wealth of <a href="http://www.homeport.org/~adam/crypto/">java cryptography libraries</a> available, including the excellent <a href="bouncycastle.org">Bouncy Castle</a>, <a href="http://www.cryptix.org/">Cryptix</a>, <a href="http://www.flexiprovider.de/">Flexiprovider</a>, etc. The choice of crypto libraries in python is generally narrower, supports less functionality, and is sometimes abandon-ware.</p>
<p>So if one&#8217;s understanding of jython is simply that it is a way to run pure python modules on the JVM, then the above mentioned mis-understanding is forgivable. But it is simply not the case that the primary usage of jython is to run pure python modules: Jython excels as a dynamic/scripting language for the JVM, and permits the use of java APIs, without having to write java code.</p>
<p>In discussion with the Google engineer after the talk, he conceded that there was one possible use case for running jython on AppEngine, namely that of prototyping java applications. In this scenario, applications would</p>
<ol>
<li>Be developed in jython, taking advantage of the enormous productivity increases gained by developing in python</li>
<li>Be translated to java once the functionality of the application is complete</li>
</ol>
<p>My reply to this is: <b>&#8220;Why bother with step 2&#8243;</b>?</p>
<p>If you&#8217;ve got a running application that is fully functional and written in jython, then you don&#8217;t need to translate it to java. You should only consider translating it, or parts of it, into java <b>if you really have to</b>. For example, after profiling your jython application, you may find one or two core pieces that are performance bottlenecks: these are prime candidates for translation to java, to improve performance. But there&#8217;s no reason to translate the rest of the application: maintainability and productivity is best served by simply leaving the jython code exactly as is.</p>
<p>I suppose a part of the reason why this mis-perception of jython has come about is because python is such an excellent language that it is in the unique position of having two completely independent implementations of the language that run on Google AppEngine. But just because both cpython and jython run on AppEngine doesn&#8217;t mean that their usages should be identical. Jython&#8217;s place in the AppEngine ecosystem is primarily as a JVM dynamic language.</p>
<p>So, in summary, jython is more than just a mechanism for running pure python code on the JVM: it is an excellent JVM development platform in it&#8217;s own right.</p>
<p>I hope I&#8217;ve given you some good reasons to consider developing your next Google AppEngine project on jython.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/jython-on-google-appengine-why-bother/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A list of open source HTTP proxies written in Java.</title>
		<link>http://jython.xhaus.com/a-list-of-open-source-http-proxies-written-in-java/</link>
		<comments>http://jython.xhaus.com/a-list-of-open-source-http-proxies-written-in-java/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 15:48:51 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=153</guid>
		<description><![CDATA[A few years ago, as an aide to python web programers, I compiled a database of open source HTTP proxies written in python, which became surprisingly popular.
So I&#8217;ve decided to expand the database to encompass the other language that I regularly use, java, and publish a database of open source HTTP proxies written in java.

While [...]]]></description>
			<content:encoded><![CDATA[<p>A few years ago, as an aide to python web programers, I compiled a <a href="http://proxies.xhaus.com/python/">database of open source HTTP proxies written in python</a>, which became surprisingly popular.</p>
<p>So I&#8217;ve decided to expand the database to encompass the other language that I regularly use, java, and publish a <a href="http://proxies.xhaus.com/java/">database of open source HTTP proxies written in java</a>.</p>
<p><span id="more-153"></span></p>
<p>While carrying out a web development project a few years ago, I needed a HTTP proxy to help with development and debugging. Rather than write my own, I decided to research what open source options were already available.</p>
<p>However, Python is such an easy language to write web servers and proxies in that a lot people had written and puiblished HTTP proxies, so making the decision wasn&#8217;t easy. It required a lot of research, which basically meant a code and architectural review of all of the open source python proxies available.</p>
<p>Since most web programmers use a HTTP proxy at some stage, I thought it would be a useful exercise to compile a complete list of the available options, with a comparison table to enable a feature by feature comparison.</p>
<p>The result of that was this <a href="http://proxies.xhaus.com/python/">comparison table of open source HTTP proxies written in python</a>, which became quite popular, because it saved python programmers going through the same complex comparison and review process I had undertaken.</p>
<p>Since I&#8217;m currently working on another proxy-related project, I needed to review available open source HTTP proxies written in java. And I thought I&#8217;d save someone some research time by publishing a similar <a href="http://proxies.xhaus.com/java/">comparison table of open source HTTP proxies in java</a>.</p>
<p>I hope you find it useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/a-list-of-open-source-http-proxies-written-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to run jython WSGI applications on Google AppEngine with modjy.</title>
		<link>http://jython.xhaus.com/how-to-run-jython-wsgi-applications-on-google-appengine-with-modjy/</link>
		<comments>http://jython.xhaus.com/how-to-run-jython-wsgi-applications-on-google-appengine-with-modjy/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 21:36:01 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[google appengine]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=97</guid>
		<description><![CDATA[As you can see from our last blog post, we were delighted to get jython WSGI applications running on Google AppEngine for java using modjy. We promised in that we&#8217;d write a tutorial on how to do do that.

Well we&#8217;ve done that: you can read the results on the modjy wiki: How to run jython [...]]]></description>
			<content:encoded><![CDATA[<p>As you can see from our last blog post, we were delighted to get jython WSGI applications running on Google AppEngine for java using modjy. We promised in that we&#8217;d write a tutorial on how to do do that.</p>
<p><span id="more-97"></span></p>
<p>Well we&#8217;ve done that: you can read the results on the modjy wiki: <a href="http://opensource.xhaus.com/projects/modjy/wiki/ModjyGoogleAppEngine">How to run jython WSGI applications on Google AppEngine with modjy</a>.</p>
<p>If you successfully upload the mody demo application, you should see results like this: <a href="http://jywsgi.appspot.com">modjy demo application running on AppEngine</a></p>
<p>We&#8217;d be happy to know of any successful reports of jython WSGI applications running on AppEngine: please feel free to leave a comment about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/how-to-run-jython-wsgi-applications-on-google-appengine-with-modjy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modjy running on Google AppEngine.</title>
		<link>http://jython.xhaus.com/modjy-running-on-google-appengine/</link>
		<comments>http://jython.xhaus.com/modjy-running-on-google-appengine/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 08:25:26 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[google appengine]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=92</guid>
		<description><![CDATA[So, after the announcement by Google that their AppEngine could run other JVM languages, including jython, I had to have a go at getting modjy, our jython WSGI to java servlet bridge, running on it.

It wasn&#8217;t a complex job, but did require a number of tweaks to the standard jython deployment. I will write up [...]]]></description>
			<content:encoded><![CDATA[<p>So, after <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html">the announcement by Google that their AppEngine could run other JVM languages</a>, including <a href="http://www.jython.org">jython</a>, I had to have a go at getting <a href="http://jython.xhaus.com/?p=41">modjy</a>, our jython WSGI to java servlet bridge, running on it.</p>
<p><span id="more-92"></span></p>
<p>It wasn&#8217;t a complex job, but did require a number of tweaks to the standard jython deployment. I will write up these instructions and make them available very soon.</p>
<p>You can see the results here: <a href="http://jywsgi.appspot.com">modjy demo application running on Google AppEngine</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/modjy-running-on-google-appengine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jython runs on Google AppEngine!</title>
		<link>http://jython.xhaus.com/jython-runs-on-google-appengine/</link>
		<comments>http://jython.xhaus.com/jython-runs-on-google-appengine/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 13:05:40 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[google appengine]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=88</guid>
		<description><![CDATA[It is now possible to run Jython on Google AppEngine!

If you&#8217;re not yet aware of it, Google AppEngine is one of the foremost Cloud Computing offerings currently available. It is also arguably one of the purest options available, since it truly removes the need for the application administrator to consider physical resources (apart from paying [...]]]></description>
			<content:encoded><![CDATA[<p>It is now possible to run Jython on Google AppEngine!</p>
<p><span id="more-88"></span></p>
<p>If you&#8217;re not yet aware of it, <a href="http://code.google.com/appengine/">Google AppEngine</a> is one of the foremost <a href="http://en.wikipedia.org/wiki/Cloud_computing">Cloud Computing</a> offerings currently available. It is also arguably one of the <b>purest</b> options available, since it truly removes the need for the application administrator to consider physical resources (apart from paying for them that is!). The Google AppEngine cloud will automatically scale up the resources as and when required.</p>
<p>This is in contrast to the <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> offering, where the application architect has to <a href="http://developer.amazonwebservices.com/connect/entry!default.jspa?categoryID=100&#038;externalID=1639">specially design the application to distribute over the Amazon cloud</a>, including allocating and de-allocating machine instances dynamically.</p>
<p>Yesterday, <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html">Google annnounced that they are providing Java on their AppEngine</a>!</p>
<p>And because they&#8217;re supporting java, they also get automatic support for other languages that run on the JVM, with <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">jython 2.2 and jython 2.5 being explicitly supported on AppEngine</a>!</p>
<p>This is fantastic news!</p>
<p>The jython team are currently ramping up for a jython 2.5 Release Candidate, which should appear very soon. It&#8217;s very likely that we&#8217;ll get the <a href="http://google-appengine-java.googlegroups.com/web/jython-r5996-appengine.patch">Google patches</a> included in jython 2.5 before then.</p>
<p>Discussions are ongoing how about <a href="http://www.nabble.com/Jython-on-Google-AppEngine%21-td22949606.html">applying the patch</a>, and the issue of <a href="http://www.nabble.com/Contributor-Agreements-for-Patches---was-Jython-on-Google-AppEngine%21-td22953650.html">contributor agreements</a>.</p>
<p>Watch this space!</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/jython-runs-on-google-appengine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announce: jyson, a pure java JSON codec for jython.</title>
		<link>http://jython.xhaus.com/announce-jyson-a-pure-java-json-codec-for-jython/</link>
		<comments>http://jython.xhaus.com/announce-jyson-a-pure-java-json-codec-for-jython/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 22:19:15 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=83</guid>
		<description><![CDATA[I&#8217;m delighted to announce the publication of jyson, a fast codec for JavaScript Object Notation (JSON), a lightweight and easy-to-use data interchange format.

As you may know, JSON is used extensively in modern web development, particularly to communicate data between servers and clients in Rich Internet Applications, or Web 2.0 applications. JSON is commonly the preferred [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m delighted to announce the publication of <a href="http://jyson.xhaus.com">jyson</a>, a fast codec for <a href="http://json.org">JavaScript Object Notation (JSON)</a>, a lightweight and easy-to-use data interchange format.</p>
<p><span id="more-83"></span></p>
<p>As you may know, JSON is used extensively in modern web development, particularly to communicate data between servers and clients in <a href="http://en.wikipedia.org/wiki/Rich_Internet_application">Rich Internet Applications</a>, or <a href="http://en.wikipedia.org/wiki/Web_2.0">Web 2.0</a> applications. JSON is commonly the preferred choice for data interchange between clients and servers which use a <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Respresentational State Transfer</a> (REST) based architecture.</p>
<p>JSON is often the preferred choice because it is a <a href="http://www.json.org/fatfree.html">fat free alternative to XML</a>. Although we use XML all the time, we fully recognise that it be both complex to work with and inefficient to generate and parse. JSON, on the other hand, is both simple and fast.</p>
<p>Jyson is written in pure java, and should be highly performant. So, if you&#8217;re using jython and JSON, we recommend you check out <a href="http://jyson.xhaus.com">jyson</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/announce-jyson-a-pure-java-json-codec-for-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modjy now fully integrated into jython.</title>
		<link>http://jython.xhaus.com/modjy-now-fully-integrated-into-jython/</link>
		<comments>http://jython.xhaus.com/modjy-now-fully-integrated-into-jython/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 15:40:06 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=77</guid>
		<description><![CDATA[I&#8217;m delighted to announce that modjy, the java servlet to python WSGI gateway that I originally wrote to track the WSGI spec, has now finally been fully integrated into the jython source base.

Modjy has been distributed with jython for several months now, in the form of a third party library, as a zip file; I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m delighted to announce that <a href="http://modjy.xhaus.com">modjy</a>, the <a href="http://java.sun.com/products/servlet/">java servlet</a> to <a href="http://www.python.org/dev/peps/pep-0333/">python WSGI</a> gateway that I originally wrote to track the WSGI spec, has now finally been fully integrated into the jython source base.</p>
<p><span id="more-77"></span></p>
<p>Modjy has been distributed with jython for several months now, in the form of a third party library, as a zip file; I used to maintain the modjy source code in a private subversion repo. But now all of the java and jython source code for modjy has been checked into the jython source base. I did the integration work on a <a href="http://fisheye3.atlassian.com/browse/jython/branches/modjy">dedicated modjy branch</a>. The jython <a href="http://en.wikipedia.org/wiki/Benevolent_Dictator_For_Life">BDFL</a>, <a href="http://fwierzbicki.blogspot.com/">Frank Wierzbicki</a>, then kindly exercised his considerable subversion fu to <a href="http://fisheye3.atlassian.com/changelog/jython/?cs=6075">integrate that branch with the jython trunk</a>, from whence the first jython 2.5 release candidate will be cut.</p>
<p>Jython 2.5 is a fantastic achievement, a tribute to Frank and all of the jython developers!</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/modjy-now-fully-integrated-into-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modjy to be distributed with jython.</title>
		<link>http://jython.xhaus.com/modjy-to-be-distributed-with-jython/</link>
		<comments>http://jython.xhaus.com/modjy-to-be-distributed-with-jython/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 17:00:29 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=41</guid>
		<description><![CDATA[I&#8217;m delighted to announce that, modjy, our jython WSGI gateway for Java Servlets, was checked into the jython source repository today, and will be distributed with jython from today forth.

For those not familiar with it, python (and thus jython) has a Batteries Included philosophy, which generally means that you can use it straight out of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m delighted to announce that, <a href="http://modjy.xhaus.com">modjy</a>, our jython <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> gateway for <a href="http://java.sun.com/products/servlet/">Java Servlets</a>, was <a href="http://fisheye3.atlassian.com/changelog/jython/?cs=5535">checked into the jython source repository</a> today, and will be distributed with jython from today forth.</p>
<p><span id="more-41"></span></p>
<p>For those not familiar with it, python (and thus jython) has a <a  href="http://www.python.org/about/">Batteries Included</a> philosophy, which generally means that you can use it straight out of the box to do what you need; python and jython come with a <a href="http://docs.python.org/library/">huge variety of modules</a> to do everything from <a href="http://docs.python.org/library/internet.html">all popular network protocols</a> to <a href="http://docs.python.org/library/numeric.html">numeric and maths processing</a> to <a href="http://docs.python.org/library/persistence.html">all kinds of databases</a> to <a href="http://docs.python.org/library/crypto.html">crytography</a> to <a href="http://docs.python.org/library/markup.html">markup processing</a>.</p>
<p>The jython 2.5 distribution already contains a pure python WSGI server, <a href="http://www.python.org/doc/2.5.2/lib/module-wsgiref.html">WSGIRef</a>, written by the principal designer of WSGI, <a href="http://dirtsimple.org/programming/index.html">Philip J. Eby</a>. There are also <a href="http://wsgi.org/wsgi/Servers">lots of other WSGI servers out there</a>, most of which will run on jython, so jython users are not limited to using modjy.</p>
<p>But modjy is unique in one respect. The great attraction of jython is that it allows the user to script the amazing <a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine">Java Virtual Machine</a> with python, which makes it much easier to deploy python applications inside the incredible range of servers available for java. Modjy&#8217;s unique selling point is that it allows the user to deploy python WSGI applications, such as <a href="http://www.djangoproject.com">Django</a>, inside <a href="http://en.wikipedia.org/wiki/Servlet">java servlet containers</a>. </p>
<p>There will still be a modjy presence on xhaus.com&#8217;s website. We&#8217;ll continue to host information about modjy, jython, WSGI and J2EE in general on a new <a href="http://modjy.xhaus.com">modjy.xhaus.com</a> subdomain. Soon, we&#8217;ll be hosting a wiki, and possibly some forums, at that domain.</p>
<p>So, it&#8217;s onwards and upwards for jython; we&#8217;re delighted to continue contributing to jython, and to open source in general.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/modjy-to-be-distributed-with-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP Compression in python and jython</title>
		<link>http://jython.xhaus.com/http-compression-in-python-and-jython/</link>
		<comments>http://jython.xhaus.com/http-compression-in-python-and-jython/#comments</comments>
		<pubDate>Sun, 13 Jan 2002 10:00:46 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[web technology]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=124</guid>
		<description><![CDATA[Index

Introduction
Can the browser handle GZIPped content?
GZIP vs ZLIB
Content-encoding vs Transfer-encoding
Content-length
Character translation on Windows and OS/2
OutputStream vs. Writer in jython servlets
Some links for related reading
Some sample CGI code
Some sample code for mod_python
Some sample code for jython servlets


		
Introduction

			These are some notes on how to do HTTP compression, i.e. compress content before it is sent to the user. [...]]]></description>
			<content:encoded><![CDATA[<h3>Index</h3>
<ol>
<li><a class="a" href="#intro">Introduction</a></li>
<li><a class="a" href="#browser">Can the browser handle GZIPped content?</a></li>
<li><a class="a" href="#gzip">GZIP vs ZLIB</a></li>
<li><a class="a" href="#encoding">Content-encoding vs Transfer-encoding</a></li>
<li><a class="a" href="#length">Content-length</a></li>
<li><a class="a" href="#chartrans">Character translation on Windows and OS/2</a></li>
<li><a class="a" href="#servletout">OutputStream vs. Writer in jython servlets</a></li>
<li><a class="a" href="#links">Some links for related reading</a></li>
<li><a class="a" href="#cgicode">Some sample CGI code</a></li>
<li><a class="a" href="#modpython">Some sample code for mod_python</a></li>
<li><a class="a" href="#jython">Some sample code for jython servlets</a></li>
</ol>
<hr/>
		<a name="intro"></a></p>
<h3>Introduction</h3>
<p>
			These are some notes on how to do HTTP compression, i.e. compress content before it is sent to the user. The benefits are
		</p>
<ol>
<li>You transmit less bandwidth. If the amount of bandwidth you can serve is limited (i.e. you have fixed allocation of X gig/month), then compressing your content before you send it can dramatically lower your transmitted bandwidth.</li>
<li>Your client receives less bandwidth, meaning that pages load faster for them. This is particularly important for people using modems. (Although some modems already do compression. I have no idea how efficient modem compression is compared to gzip. See the <a class="a" href="#links">Links section</a> for a link to an article which discusses HTML compression vs. modem compression.)</li>
</ol>
<p>
			Some points to remember
		</p>
<ol>
<li>Although you save on bandwidth transmitted from your server, it comes at a cost of increased CPU usage on the server.</li>
<li>Compressing images probably isn&#8217;t worth it. Specialised image compression formats such as <b>GIF</b>, <b>JPEG</b>, and <b>PNG</b> are optimised for the content they carry, and probably cannot be much improved on. So it&#8217;s probably not worth compressing images using these techniques.</li>
<li>The best bandwidth saving will be achieved on textual files, i.e. mime types like <code>&lt;text/plain&gt;, &lt;text/html&gt;, &lt;text/xml&gt;</code>.</li>
</ol>
<p>
			I&#8217;m not going to go into the details of the rationale or the mechanisms of compression here, I&#8217;m just going to stick to telling you how to do http compression in python. If you want to know about the nuts and bolts of compression and http, I suggest you read
		</p>
<ol>
<li><a class="a" href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616: Hypertext Transfer Protocol &#8212; HTTP/1.1</a></li>
<li><a class="a" href="http://www.ietf.org/rfc/rfc1952.txt">RFC1952: GZIP file format specification version 4.3</a></li>
</ol>
<hr/>
<p>		<a name="browser"></a></p>
<h3>Can the browser handle GZIPped content?</h3>
<p>
			Not all browsers can handle compressed content. Old browsers that support HTTP version 0.9 are unlikely to support compressed content. Compression was optional in version 1.0 of the HTTP spec, so only some HTTP 1.0 clients support it, most notably versions 4.x of Netscape Navigator. Support for compression is compulsory in HTTP 1.1, so all HTTP 1.1 clients should support compression. HTTP 1.1 clients include Internet Explorer 5.0 and up. Although I don&#8217;t know if Internet Explorer 4.0 is HTTP 1.1 or 1.0, I&#8217;m sure IE 4.0 supports gzip compression.
		</p>
<p>
			Fortunately, you don&#8217;t have to guess or keep a list of which browsers do or do not support compression, since the browsers themselves will inform you of it in their HTTP request. Browsers that support compression will inform you via the HTTP header <code>Accept-Encoding</code> (Check your browser&#8217;s headers <a href="http://www.xhaus.com/headers">here</a>). Possible compression methods, as mentioned in RFC2616, include <b>gzip</b>, <b>compress</b>, <b>deflate</b>, and <b>identity</b>. Note that the last one, <b>identity</b>, means <b>no</b> compression. Note also that I&#8217;m only going to cover <b>gzip</b> in this document.
		</p>
<p>
			So if a browser supports compression, its HTTP request will include a header similar to one of the following
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Accept-Encoding: <span style="color: #dc143c;">gzip</span>
Accept-Encoding: <span style="color: #dc143c;">gzip</span>, deflate</pre></div></div>

<p>
			So you need to get the value of the <code>Accept-Encoding</code> header, and check if it contains <code>gzip</code>. If it does, then you can send gzip-compressed content to that browser. Here is some CGI code that checks the content of the header
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
acceptsGzip = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;HTTP_ACCEPT_ENCODING&quot;</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
        acceptsGzip = <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>
			And here is some mod_python code that checks the content of the header.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> acceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
        Checks if a browser request indicates that the browser will accept
        gzipped content in reply.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> req.<span style="color: black;">headers_in</span>.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">encodings</span> = req.<span style="color: black;">headers_in</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">encodings</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span></pre></div></div>

<p>
			And here is some jython servlet code that checks the content of the header.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> acceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
        Checks if a browser request indicates that the browser will accept
        gzipped content in reply.
    &quot;&quot;&quot;</span>
    <span style="color: #dc143c;">encodings</span> = req.<span style="color: black;">getHeader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">encodings</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">encodings</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span></pre></div></div>

</p>
<hr/>
<p>		<a name="gzip"></a></p>
<h3>GZIP vs ZLIB</h3>
<p>
			There are a few compression libraries that come with Python. The one which is used in HTTP compression is <b>GZIP</b>. <b>ZLIB</b>, although it is used by GZIP to do part of its job, should <b>not</b> be needed directly in your code.
		</p>
<p>
			When a file is compressed for transmission through http, it must be preceded by some special header bytes and followed by some special trailer bytes. Conveniently enough, the python GZIP module constructs exactly those headers and trailers. The details of what those headers and trailers are can be found in <a class="a" href="http://www.ietf.org/rfc/rfc1952.txt">RFC1952</a>.
		</p>
<p>
			In order to compress using the GZIP module, you&#8217;ll need to use code something like this.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gzip</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> compressBuf<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>:
    zbuf = <span style="color: #dc143c;">cStringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    zfile = <span style="color: #dc143c;">gzip</span>.<span style="color: black;">GzipFile</span><span style="color: black;">&#40;</span>mode = <span style="color: #483d8b;">'wb'</span>,  fileobj = zbuf, compresslevel = <span style="color: #ff4500;">9</span><span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> zbuf.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
			Note that this code compresses into a buffer held in memory, rather than a disk file. This is done through the use of <code>cStringIO.StringIO()</code>.
		</p>
<p>
			You can vary the compression level by changing the value of the <code>compresslevel</code> parameter, with compresslevel = 9 giving the best compression but consuming the most CPU cycles, and compresslevel = 1 giving the least compression and also consuming the least CPU.
		</p>
<hr/>
<p>		<a name="encoding"></a></p>
<h3>Content-encoding vs Transfer-encoding</h3>
<p>
		When you&#8217;re sending compressed content back to the browser, you have to inform the browser of the compression. This is done by the header <code>Content-Encoding</code>. So you should include a header in your response that looks like this.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Content-Encoding: <span style="color: #dc143c;">gzip</span></pre></div></div>

<p>
		You don&#8217;t need to read any further in this section. The note below about different methods of declaring encoding is just here for interest and completeness.
		</p>
<p>
		Note: There is another possible way to communicate the encoding: the <code>Transfer-Encoding</code> header. According to RFC2616, the difference between the two headers is as follows
		</p>
<ol>
<li><b>Content-Encoding</b> should be used when the encoding is a property of the content. So if you were serving a static file that is always compressed, then this is the header to use.</li>
<li><b>Transfer-Encoding</b> should be used when the encoding is a property of the message used to transmit the content. So you were sending a static file that is normally uncompressed, and were compressing it just so as to minimise bandwidth during the transmission, then this is the header you should use.</li>
</ol>
<p>
		However, RFC2616 is unclear what encoding to use if you are generating dynamic content, which may only be transient in memory and has no lifetime beyond the HTTP request-response pair it was contructed for. In such a situation, an argument could be made for using either <code>Content-Encoding</code> or <code>Transfer-Encoding</code>.
		</p>
<p>
		Rather than try to resolve that (potentially unresolvable) issue, I would just like to point out that majority of software &quot;out there&quot; seems to have opted for using <code>Content-Encoding</code>, and that&#8217;s the choice that I&#8217;ve made as well. You are, of course, free to choose otherwise.
		</p>
<hr/>
<p>		<a name="length"></a></p>
<h3>Content-Length</h3>
<p>
		You also need to tell the client browser the length of the compressed content you are sending. This is done by sending a <code>Content-Length</code> header, like this.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Content-Length: xyz</pre></div></div>

<p>
		where <b>xyz</b> is the <b>COMPRESSED</b> length of the content.
		</p>
<p>
		There seems to be some &quot;folk wisdom&quot; out there on the &#8216;net that you should send the <b>uncompressed</b> length of the content. This is <b>wrong</b>! <a class="a" href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> is quite clear about this. If you are interested, read sections 7.2.2 Entity-Length and 4.4 Message Length.
		</p>
<p>
		As far as I can see, the definitive statement on this matter is at the end of section 4.4 (I have underlined the relevant statement)
		</p>
<blockquote><p>
<u>When a Content-Length is given in a message where a message-body<br />
is allowed, its field value MUST exactly match the number of OCTETs<br />
in the message-body</u>. HTTP/1.1 user agents MUST notify the user when<br />
an invalid length is received and detected.
			</p></blockquote>
<hr/>
<p>		<a name="chartrans"></a></p>
<h3>Character translation on Windows and OS/2</h3>
<p>
		If you&#8217;re working in CGI, and on Windows or on OS/2, you need to be careful about character translation.
		</p>
<p>
		As you may be aware, Windows and OS/2 are different from other platforms in the way that they represent an end of line. Whereas most platforms, including *nix, represent line ends as an ASCII linefeed (hex 0&#215;0A, octal 012, python escape string &#8216;\n&#8217;), Windows and OS/2 represent end-of-line as a sequence of two characters, an ASCII carriage return followed by an ASCII linefeed (hex 0&#215;0D 0&#215;0A, octal 015 012, python escape string &#8216;\r\n&#8217;). Therefore, when you print anything in python, or write anything to <code>sys.stdout</code>, using code like this
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Hello World!&quot;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hello World!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
		then both Windows and OS/2 filter the characters, and turn all linefeed characters into a sequence of carriage return followed by linefeed.
		</p>
<p>
		This is fine when you&#8217;re printing text. But when you&#8217;re trying to send binary information, particularly a compressed gzipped file, then this translation will corrupt the binary content, and your transmission of gzip compressed content will fail. Therefore, you have to disable this character translation in order for transmission of gzipped content to work.
		</p>
<p>
			When you&#8217;re working in CGI, the best way to do this is with the &#8220;-u&#8221; command line flag to python. This was kindly pointed out by <b>Richie Hindle</b>, who says
		</p>
<blockquote><p><b><br />
		&#8230;&#8230; There is a much simpler way to switch off character translation of the standard<br />
channels.  The python interpreter accepts the -u switch to mean &#8220;make the<br />
standard channels both unbuffered and binary.&#8221;  This is tailor-made for<br />
CGI &#8211; change your shebang line from &#8220;#!&#8230;python&#8221; to &#8220;#!&#8230;python -u&#8221; and<br />
everything will work without changing your code (and without relying on<br />
platorm-specific modules like msvcrt).  Responsiveness may even improve<br />
due to the lack of buffering &#8211; and that&#8217;s also true on platforms like Unix<br />
which don&#8217;t do character translation.<br />
		</b></p></blockquote>
<p>
		A less convenient method is to execute some platform specific code to disable character translation inside your script. On Windows (MSVC), you should execute some code like this
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">msvcrt</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #dc143c;">msvcrt</span>.<span style="color: black;">setmode</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">O_BINARY</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
		I don&#8217;t know what the equivalent code is on Windows (CygWin) or OS/2. If anyone does, <a class="a" href="http://www.xhaus.com/contact/alan">email it to me</a>, and I&#8217;ll include it in this page.
		</p>
<hr/>
<p>		<a name="servletout"></a></p>
<h3>OutputStream vs. Writer in jython servlets.</h3>
<p>
		Under the J2EE Servlet interface, you have a choice of two different ways to output generated content. They are
		</p>
<ol>
<li>Through an <b>OutputStream</b> (obtained by calling <code>ServletResponse.getOutputStream()</code>). <code>OutputStream</code>s do not carry out character translation on their output.</li>
<li>Through a <b>Writer</b> (obtained by calling <code>ServletResponse.getWriter()</code>). <code>Writer</code>s carry out character translation on their output, i.e. they will change the value of bytes in the content output by the servlet, to ensure that it meets the character encoding requirements of the client.</li>
</ol>
<p>
		Since compressed gzip content is a (dense) binary format, none of the output bytes should be translated. If any bytes are translated, the output may be corrupted and the recipient may be unable to decode it. Therefore, you must output compressed content through a (non-translating) <code>OutputStream</code> object.
		</p>
<hr/>
<p>		<a name="links"></a></p>
<h3>Some links for related reading</h3>
<ul>
<li>W3C: <a class="a" href="http://www.w3.org/Protocols/HTTP/Performance/#Compression">Compression and Performance</a></li>
</ul>
<hr/>
<p>		<a name="cgicode"></a></p>
<h3>Some sample CGI code</h3>
<p>
		So, without further ado, here is some sample CGI code that will transmit compressed HTML to gzip capable browsers.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /path/to/python -u</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gzip</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cStringIO</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> compressBuf<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>:
    zbuf = <span style="color: #dc143c;">cStringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    zfile = <span style="color: #dc143c;">gzip</span>.<span style="color: black;">GzipFile</span><span style="color: black;">&#40;</span>mode = <span style="color: #483d8b;">'wb'</span>,  fileobj = zbuf, compresslevel = <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> zbuf.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> testAcceptsGzip<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    acceptsGzip = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;HTTP_ACCEPT_ENCODING&quot;</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
            acceptsGzip = <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">pass</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> acceptsGzip
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> sendHtml<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-type: text/html<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> testAcceptsGzip<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        zbuf = compressBuf<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-Encoding: gzip<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Content-Length: %d<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
&nbsp;
myHtml = <span style="color: #483d8b;">&quot;&quot;&quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;hello compressed world!&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span>
sendHtml<span style="color: black;">&#40;</span>myHtml<span style="color: black;">&#41;</span></pre></div></div>

<hr/>
<p>		<a name="modpython"></a></p>
<h3>Some sample mod python code</h3>
<p>
		And here is some sample mod python code that will transmit compressed HTML to gzip capable browsers.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gzip</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cStringIO</span>
<span style="color: #ff7700;font-weight:bold;">from</span>   mod_python <span style="color: #ff7700;font-weight:bold;">import</span> apache
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> compressBuf<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>:
    zbuf = <span style="color: #dc143c;">cStringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    zfile = <span style="color: #dc143c;">gzip</span>.<span style="color: black;">GzipFile</span><span style="color: black;">&#40;</span>mode = <span style="color: #483d8b;">'wb'</span>,  fileobj = zbuf, compresslevel = <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> zbuf.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> testAcceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> req.<span style="color: black;">headers_in</span>.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">encodings</span> = req.<span style="color: black;">headers_in</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">encodings</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> handler<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
    req.<span style="color: black;">content_type</span> = <span style="color: #483d8b;">&quot;text/html&quot;</span>
    myHtml = <span style="color: #483d8b;">&quot;&quot;&quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;hello compressed world!&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> testAcceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
        zbuf = compressBuf<span style="color: black;">&#40;</span>myHtml<span style="color: black;">&#41;</span>
        req.<span style="color: black;">headers_out</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Content-Encoding'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'gzip'</span>
        req.<span style="color: black;">headers_out</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Content-Length'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'%d'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        req.<span style="color: black;">send_http_header</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        req.<span style="color: black;">write</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        req.<span style="color: black;">send_http_header</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        req.<span style="color: black;">write</span><span style="color: black;">&#40;</span>myHtml<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> apache.<span style="color: black;">OK</span></pre></div></div>

<hr/>
<p>		<a name="jython"></a></p>
<h3>Some sample jython servlet code</h3>
<p>
		And here is some sample jython servlet code that will transmit compressed HTML to gzip capable browsers.
		</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span>  javax.<span style="color: black;">servlet</span>.<span style="color: black;">http</span>.<span style="color: black;">HttpServlet</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span>  <span style="color: #dc143c;">cStringIO</span>
<span style="color: #ff7700;font-weight:bold;">import</span>  <span style="color: #dc143c;">gzip</span>
<span style="color: #ff7700;font-weight:bold;">import</span>  <span style="color: #dc143c;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> compressBuf<span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>:
    zbuf = <span style="color: #dc143c;">cStringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    zfile = <span style="color: #dc143c;">gzip</span>.<span style="color: black;">GzipFile</span><span style="color: black;">&#40;</span>mode = <span style="color: #483d8b;">'wb'</span>,  fileobj = zbuf, compresslevel = <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span>buf<span style="color: black;">&#41;</span>
    zfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> zbuf.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> acceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">encodings</span> = req.<span style="color: black;">getHeader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'accept-encoding'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">encodings</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">encodings</span>, <span style="color: #483d8b;">&quot;gzip&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> compressor<span style="color: black;">&#40;</span>javax.<span style="color: black;">servlet</span>.<span style="color: black;">http</span>.<span style="color: black;">HttpServlet</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> service<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, req, resp<span style="color: black;">&#41;</span>:
        resp.<span style="color: black;">setContentType</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'text/html'</span><span style="color: black;">&#41;</span>
        myHtml = <span style="color: #483d8b;">&quot;&quot;&quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;hello compressed world!&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> acceptsGzip<span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>:
            binarychan = resp.<span style="color: black;">getOutputStream</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            zbuf = compressBuf<span style="color: black;">&#40;</span>myHtml<span style="color: black;">&#41;</span>
            resp.<span style="color: black;">setHeader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Content-Encoding'</span>, <span style="color: #483d8b;">'gzip'</span><span style="color: black;">&#41;</span>
            resp.<span style="color: black;">setHeader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Content-Length'</span>, <span style="color: #483d8b;">'%d'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            binarychan.<span style="color: black;">write</span><span style="color: black;">&#40;</span>zbuf<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            textchan = resp.<span style="color: black;">getWriter</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            textchan.<span style="color: black;">write</span><span style="color: black;">&#40;</span>myHtml<span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/http-compression-in-python-and-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
